From 92b2a911e516ded986945d5d3dc6326f5575a21a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 11 Mar 2021 18:36:09 +0200 Subject: [PATCH] MDEV-24818 Concurrent use of InnoDB table is impossible until the first transaction is finished In MDEV-515, we enabled an optimization where an insert into an empty table will use table-level locking and undo logging. This may break applications that expect row-level locking. The SQL statements created by the mysqldump utility will include the following: SET unique_checks=0, foreign_key_checks=0; We will use these flags to enable the table-level locked and logged insert. Unless the parameters are set, INSERT will be executed in the old way, with row-level undo logging and implicit record locks. --- mysql-test/include/innodb_trx_weight.inc | 4 ++++ mysql-test/suite/innodb/r/insert_into_empty.result | 1 + mysql-test/suite/innodb/t/innodb_trx_weight.test | 4 ---- mysql-test/suite/innodb/t/insert_into_empty.test | 3 +++ mysql-test/suite/innodb_fts/r/innodb_fts_plugin.result | 1 + mysql-test/suite/innodb_fts/t/innodb_fts_plugin.test | 2 ++ storage/innobase/row/row0ins.cc | 1 + 7 files changed, 12 insertions(+), 4 deletions(-) diff --git a/mysql-test/include/innodb_trx_weight.inc b/mysql-test/include/innodb_trx_weight.inc index 56d3d47da36..a1e64276511 100644 --- a/mysql-test/include/innodb_trx_weight.inc +++ b/mysql-test/include/innodb_trx_weight.inc @@ -2,6 +2,8 @@ -- connect (con2,localhost,root,,) -- connection con1 +# Enable MDEV-515 table-level undo logging for insert into empty table +SET foreign_key_checks=0, unique_checks=0; SET autocommit=0; SELECT * FROM t1 FOR UPDATE; -- if ($con1_extra_sql_present) { @@ -9,6 +11,8 @@ SELECT * FROM t1 FOR UPDATE; -- } -- connection con2 +# Enable MDEV-515 table-level undo logging for insert into empty table +SET foreign_key_checks=0, unique_checks=0; SET autocommit=0; SELECT * FROM t2 FOR UPDATE; -- if ($con2_extra_sql_present) { diff --git a/mysql-test/suite/innodb/r/insert_into_empty.result b/mysql-test/suite/innodb/r/insert_into_empty.result index da352e4970b..b879086ccc2 100644 --- a/mysql-test/suite/innodb/r/insert_into_empty.result +++ b/mysql-test/suite/innodb/r/insert_into_empty.result @@ -1,3 +1,4 @@ +SET foreign_key_checks=0, unique_checks=0; # # MDEV-24715 Assertion !node->table->skip_alter_undo # diff --git a/mysql-test/suite/innodb/t/innodb_trx_weight.test b/mysql-test/suite/innodb/t/innodb_trx_weight.test index e33885dac8b..819f05f331e 100644 --- a/mysql-test/suite/innodb/t/innodb_trx_weight.test +++ b/mysql-test/suite/innodb/t/innodb_trx_weight.test @@ -22,10 +22,6 @@ SET default_storage_engine=InnoDB; # if someone runs ./mysql-test-run.pl --ps-protocol -- disable_ps_protocol --- disable_warnings -DROP TABLE IF EXISTS t1, t2, t3, t4, t5_nontrans; --- enable_warnings - # we will create a simple deadlock with t1, t2 and two connections CREATE TABLE t1 (a INT); CREATE TABLE t2 (a INT); diff --git a/mysql-test/suite/innodb/t/insert_into_empty.test b/mysql-test/suite/innodb/t/insert_into_empty.test index 21387b08377..0c1765e0d71 100644 --- a/mysql-test/suite/innodb/t/insert_into_empty.test +++ b/mysql-test/suite/innodb/t/insert_into_empty.test @@ -1,6 +1,9 @@ --source include/have_innodb.inc --source include/have_sequence.inc +# Enable MDEV-515 table-level undo logging for insert into empty table +SET foreign_key_checks=0, unique_checks=0; + --echo # --echo # MDEV-24715 Assertion !node->table->skip_alter_undo --echo # diff --git a/mysql-test/suite/innodb_fts/r/innodb_fts_plugin.result b/mysql-test/suite/innodb_fts/r/innodb_fts_plugin.result index b1426ece222..85271aebcf4 100644 --- a/mysql-test/suite/innodb_fts/r/innodb_fts_plugin.result +++ b/mysql-test/suite/innodb_fts/r/innodb_fts_plugin.result @@ -115,6 +115,7 @@ title VARCHAR(200), body TEXT, FULLTEXT (title, body) WITH PARSER simple_parser ) ENGINE=InnoDB; +SET unique_checks=0, foreign_key_checks=0; BEGIN; INSERT INTO articles (title, body) VALUES ('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_plugin.test b/mysql-test/suite/innodb_fts/t/innodb_fts_plugin.test index cd31500b23f..643e4a08b0e 100644 --- a/mysql-test/suite/innodb_fts/t/innodb_fts_plugin.test +++ b/mysql-test/suite/innodb_fts/t/innodb_fts_plugin.test @@ -125,6 +125,8 @@ CREATE TABLE articles ( FULLTEXT (title, body) WITH PARSER simple_parser ) ENGINE=InnoDB; +# Enable MDEV-515 table-level undo logging when inserting into empty table +SET unique_checks=0, foreign_key_checks=0; BEGIN; INSERT INTO articles (title, body) VALUES ('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 65cb8321500..b652aa187e8 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -2660,6 +2660,7 @@ commit_exit: if (!(flags & BTR_NO_UNDO_LOG_FLAG) && page_is_empty(block->frame) && !entry->is_metadata() && !trx->duplicates + && !trx->check_unique_secondary && !trx->check_foreigns && !trx->ddl && !trx->internal && block->page.id().page_no() == index->page && !index->table->skip_alter_undo