From 50a4a87a63cc9db9a162db8993548f3a473f6157 Mon Sep 17 00:00:00 2001 From: Vladimir Davydov <vdavydov.dev@gmail.com> Date: Tue, 20 Jun 2017 13:41:33 +0300 Subject: [PATCH] alter: proscribe space truncate in transaction Space truncation is implemented as recreation of a space and all its indexes. On success the original space is deleted by the commit trigger, while on failure the new space is deleted by the rollback trigger. The commit/rollback triggers are always called before commit/rollback engine methods, which makes space truncation incompatible with transactions: engine commit/rollback may access a space that have already been deleted by commit/rollback trigger installed by space truncation, resulting in a crash. So let's forbid to use space.truncate from a transaction until triggers are made transaction-friendly. Closes #2525 --- src/box/alter.cc | 1 + test/engine/truncate.result | 29 +++++++++++++++++++++++++++++ test/engine/truncate.test.lua | 12 ++++++++++++ 3 files changed, 42 insertions(+) diff --git a/src/box/alter.cc b/src/box/alter.cc index 95027043e8..32d3cea5f0 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -1397,6 +1397,7 @@ on_replace_dd_truncate(struct trigger * /* trigger */, void *event) { struct txn *txn = (struct txn *) event; struct txn_stmt *stmt = txn_current_stmt(txn); + txn_check_autocommit(txn, "Space _truncate"); struct tuple *old_tuple = stmt->old_tuple; struct tuple *new_tuple = stmt->new_tuple; diff --git a/test/engine/truncate.result b/test/engine/truncate.result index 91153e2f17..01be5ffecb 100644 --- a/test/engine/truncate.result +++ b/test/engine/truncate.result @@ -8,6 +8,35 @@ fiber = require('fiber') --- ... -- +-- Check that space truncation is forbidden in a transaction. +-- +s = box.schema.create_space('test', {engine = engine}) +--- +... +_ = s:create_index('pk') +--- +... +_ = s:insert{123} +--- +... +box.begin() +--- +... +s:truncate() +--- +- error: Space _truncate does not support multi-statement transactions +... +box.commit() +--- +... +s:select() +--- +- - [123] +... +s:drop() +--- +... +-- -- Truncate space with no indexes. -- s = box.schema.create_space('test', {engine = engine}) diff --git a/test/engine/truncate.test.lua b/test/engine/truncate.test.lua index 41f5694d19..0f6addd58a 100644 --- a/test/engine/truncate.test.lua +++ b/test/engine/truncate.test.lua @@ -3,6 +3,18 @@ engine = test_run:get_cfg('engine') fiber = require('fiber') +-- +-- Check that space truncation is forbidden in a transaction. +-- +s = box.schema.create_space('test', {engine = engine}) +_ = s:create_index('pk') +_ = s:insert{123} +box.begin() +s:truncate() +box.commit() +s:select() +s:drop() + -- -- Truncate space with no indexes. -- -- GitLab