Skip to content
Snippets Groups Projects
Commit d529082f authored by Georgiy Lebedev's avatar Georgiy Lebedev Committed by Serge Petrenko
Browse files

txn: run statement `on_rollback` triggers before rolling back statement

Logically, we call triggers after running statements. These triggers can
make significant changes (for instance, DDL triggers), so, for consistency,
we should call the statement's `on_rollback` triggers before rolling back
the statement. This also adheres to the logic that transaction
`on_rollback` triggers are called before rolling back individual
transaction statements.

One particular bug that this patch fixes is rolling back of DDL on the
`_space` space. DDL is essentially a replace operation on the `_space`
space, which also invokes the `on_replace_dd_space` trigger. In this
trigger, among other things, we swap the indexes of the original space,
`alter->old_space`, which is equal to the corresponding transaction
`stmt->space`, with the indexes of the newly created space,
`alter->new_space`:
https://github.com/tarantool/tarantool/blob/de80e0264f7deb58ea86ef85b37b92653a803430/src/box/alter.cc#L1036-L1047

If then a rollback happens, we first rollback the replace operation, using
`stmt->space`, and only after that do we swap back the indexes in
`alter_space_rollback`:
https://github.com/tarantool/tarantool/blob/de80e0264f7deb58ea86ef85b37b92653a803430/src/box/memtx_engine.cc#L659-L669
https://github.com/tarantool/tarantool/blob/de80e0264f7deb58ea86ef85b37b92653a803430/src/box/alter.cc#L916-L925

For DDL on the _space space, the replace operation and DDL occur on the
same space. This means that during rollback of the replace, we will try to
do a replace in the empty indexes that were created for `alter->new_space`.
Not only does this break the replace operation, but also the newly inserted
tuple, which remains in the index, gets deleted, and access to it causes
undefined behavior (heap-use-after-free).

As part of the work on this patch, tests of rollback of DDL on system
spaces which use `on_rollback` triggers were enumerated:
* `_sequence` — box/sequence.test.lua;
* `_sequence_data` — box/sequence.test.lua;
* `_space_sequence` — box/sequence.test.lua;
* `_trigger` — sql/ddl.test.lua, sql/errinj.test.lua;
* `_collation` — engine-luatest/gh_4544_collation_drop_test.lua,
                 box/ddl_collation.test.lua;
* `_space` — box/transaction.test.lua, sql/ddl.test.lua;
* `_index` — box/transaction.test.lua, sql/ddl.test.lua;
* `_cluster` — box/transaction.test.lua;
* `_func` — box/transaction.test.lua, box/function1.test.lua;
* `_priv` — box/errinj.test.lua,
            box-luatest/rollback_ddl_on__priv_space_test.lua;
* `_user` — box/transaction.test.lua,
            box-luatest/gh_4348_transactional_ddl_test.lua.

Closes #9893

NO_DOC=<bugfix>
parent 797c04ff
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