Skip to content
Snippets Groups Projects
Commit f266559b authored by Vladimir Davydov's avatar Vladimir Davydov
Browse files

ddl: allow to execute non-yielding DDL statements in transactions

The patch is pretty straightforward - all it does is moves checks for
single statement transactions from alter.cc to txn_enable_yield_for_ddl
so that now any DDL request may be executed in a transaction unless it
builds an index or checks the format of a non-empty space (those are the
only two operations that may yield).

There's two things that must be noted explicitly. The first is removal
of an assertion from priv_grant. The assertion ensured that a revoked
privilege was in the cache. The problem is the cache is built from the
contents of the space, see user_reload_privs. On rollback, we first
revert the content of the space to the original state, and only then
start invoking rollback triggers, which call priv_grant. As a result, we
will revert the cache to the original state right after the first
trigger is invoked and the following triggers will have no effect on it.
Thus we have to remove this assertion.

The second subtlety lays in vinyl_index_commit_modify. Before the commit
we assumed that if statement lsn is <= vy_lsm::commit_lsn, then it must
be local recovery from WAL. Now it's not true, because there may be
several operations for the same index in a transaction, and they all
will receive the same signature in on_commit trigger. We could, of
course, try to assign different signatures to them, but that would look
cumbersome - better simply allow lsn <= vy_lsm::commit_lsn after local
recovery, there's actually nothing wrong about that.

Closes #4083

@TarantoolBot document
Title: Transactional DDL

Now it's possible to group non-yielding DDL statements into
transactions, e.g.

```Lua
box.begin()
box.schema.space.create('my_space')
box.space.my_space:create_index('primary')
box.commit() -- or box.rollback()
```

Most DDL statements don't yield and hence can be run from transactions.
There are just two exceptions: creation of a new index and changing the
format of a non-empty space. Those are long operations that may yield
so as not to block the event loop for too long. Those statements can't
be executed from transactions (to be more exact, such a statement must
go first in any transaction).

Also, just like in case of DML transactions in memtx, it's forbidden to
explicitly yield in a DDL transaction by calling fiber.sleep or any
other yielding function. If this happens, the transaction will be
aborted and an attempt to commit it will fail.
parent 626c5fd0
No related branches found
No related tags found
No related merge requests found
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment