From e1876e84c564c0ab35463808b6e72681ba8ba2fb Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 10 Sep 2006 21:58:51 +0200 Subject: [PATCH] ndb - bug#20612 ins-del fix in tup storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp: allocate separate copy tuple for delete after insert or update in same tx, instead of sharing pointer to same copy tuple. this is an easy fix independent of commit/abort order of operations mysql-test/r/ndb_dd_basic.result: test INS-DEL via assert in disk data code mysql-test/t/ndb_dd_basic.test: test INS-DEL via assert in disk data code --- mysql-test/r/ndb_dd_basic.result | 20 ++++++++++++++ mysql-test/t/ndb_dd_basic.test | 26 +++++++++++++++++++ .../kernel/blocks/dbtup/DbtupExecQuery.cpp | 10 ++++++- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ndb_dd_basic.result b/mysql-test/r/ndb_dd_basic.result index 6c10fbe63b3..f3b8bf7daab 100644 --- a/mysql-test/r/ndb_dd_basic.result +++ b/mysql-test/r/ndb_dd_basic.result @@ -422,6 +422,26 @@ SELECT COUNT(*) FROM t1; COUNT(*) 0 DROP TABLE t1; +CREATE TABLE t1 ( +a int NOT NULL, +b varchar(4000), -- must use 2 pages undo +PRIMARY KEY using hash (a) +) +TABLESPACE ts1 STORAGE DISK ENGINE=NDBCLUSTER; +set autocommit = 0; +insert into t1 values(0,'x'); +insert into t1 values(1,'x'); +insert into t1 values(2,'x'); +insert into t1 values(3,'x'); +insert into t1 values(4,'x'); +insert into t1 values(5,'x'); +insert into t1 values(6,'x'); +insert into t1 values(7,'x'); +insert into t1 values(8,'x'); +delete from t1 where a = 0; +commit; +set autocommit = 1; +drop table t1; ALTER TABLESPACE ts1 DROP DATAFILE 'datafile.dat' ENGINE = NDB; diff --git a/mysql-test/t/ndb_dd_basic.test b/mysql-test/t/ndb_dd_basic.test index 9df2cfb0371..ab21362c0f9 100644 --- a/mysql-test/t/ndb_dd_basic.test +++ b/mysql-test/t/ndb_dd_basic.test @@ -345,6 +345,32 @@ DELETE FROM t1 WHERE a=2; SELECT COUNT(*) FROM t1; DROP TABLE t1; +# bug#20612 INS-DEL bug (not pgman bug) +# found via disk data assert but is not pgman or disk data related + +CREATE TABLE t1 ( + a int NOT NULL, + b varchar(4000), -- must use 2 pages undo + PRIMARY KEY using hash (a) +) +TABLESPACE ts1 STORAGE DISK ENGINE=NDBCLUSTER; + +set autocommit = 0; +insert into t1 values(0,'x'); +insert into t1 values(1,'x'); +insert into t1 values(2,'x'); +insert into t1 values(3,'x'); +insert into t1 values(4,'x'); +insert into t1 values(5,'x'); +insert into t1 values(6,'x'); +insert into t1 values(7,'x'); +insert into t1 values(8,'x'); +delete from t1 where a = 0; +commit; +set autocommit = 1; + +drop table t1; + ################### # Test Cleanup ################### diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp index dc1b194eed2..3118164badd 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp @@ -1469,7 +1469,15 @@ int Dbtup::handleDeleteReq(Signal* signal, { Operationrec* prevOp= req_struct->prevOpPtr.p; regOperPtr->tupVersion= prevOp->tupVersion; - regOperPtr->m_copy_tuple_location= prevOp->m_copy_tuple_location; + // make copy since previous op is committed before this one + const Uint32* org = c_undo_buffer.get_ptr(&prevOp->m_copy_tuple_location); + Uint32* dst = c_undo_buffer.alloc_copy_tuple( + ®OperPtr->m_copy_tuple_location, regTabPtr->total_rec_size); + if (dst == 0) { + terrorCode = ZMEM_NOMEM_ERROR; + goto error; + } + memcpy(dst, org, regTabPtr->total_rec_size << 2); } else {