summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2023-03-24 15:20:21 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2023-03-24 15:20:21 +0530
commite06c6046d25052d8ad7a8c1f72ea666bc983c674 (patch)
tree3c98a7a5086f9c9cb6c97484cf5c15d666059eef
parent07460c31e30cc1f6b56dab6e9a54a7618e26050b (diff)
downloadmariadb-git-e06c6046d25052d8ad7a8c1f72ea666bc983c674.tar.gz
MDEV-29545 InnoDB: Can't find record during replace stmt
Problem: ======== - InnoDB replace statement returns can't find record as result during bulk insert operation. InnoDB returns DB_END_OF_INDEX blindly when bulk transaction is visible to current transaction even though the search tuple is inserted as a part of current replace statement. Solution: ========= row_search_mvcc(): InnoDB should allow the transaction to read all the rows when innodb intends to do any locking on the record even though bulk insert transaction changes are visible to the current transaction
-rw-r--r--mysql-test/suite/innodb/r/insert_into_empty.result22
-rw-r--r--mysql-test/suite/innodb/t/insert_into_empty.test22
-rw-r--r--storage/innobase/row/row0sel.cc6
3 files changed, 49 insertions, 1 deletions
diff --git a/mysql-test/suite/innodb/r/insert_into_empty.result b/mysql-test/suite/innodb/r/insert_into_empty.result
index 25cc489bdab..ef7d015f7f3 100644
--- a/mysql-test/suite/innodb/r/insert_into_empty.result
+++ b/mysql-test/suite/innodb/r/insert_into_empty.result
@@ -229,4 +229,26 @@ commit;
SELECT * FROM t;
c
DROP TABLE t;
+#
+# MDEV-29545 InnoDB: Can't find record during replace stmt
+#
+CREATE TABLE t1(c1 INT PRIMARY KEY)ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t1 VALUES(3331);
+connect con1,localhost,root,,,;
+BEGIN;
+SELECT c1 FROM t1;
+c1
+connection default;
+COMMIT;
+connection con1;
+REPLACE INTO t1 VALUES(1984), (1984);
+COMMIT;
+connection default;
+disconnect con1;
+SELECT * FROM t1;
+c1
+1984
+3331
+DROP TABLE t1;
# End of 10.6 tests
diff --git a/mysql-test/suite/innodb/t/insert_into_empty.test b/mysql-test/suite/innodb/t/insert_into_empty.test
index 932ab4c2a23..010b7ecb43a 100644
--- a/mysql-test/suite/innodb/t/insert_into_empty.test
+++ b/mysql-test/suite/innodb/t/insert_into_empty.test
@@ -247,4 +247,26 @@ SAVEPOINT a;
commit;
SELECT * FROM t;
DROP TABLE t;
+
+--echo #
+--echo # MDEV-29545 InnoDB: Can't find record during replace stmt
+--echo #
+CREATE TABLE t1(c1 INT PRIMARY KEY)ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t1 VALUES(3331);
+
+connect(con1,localhost,root,,,);
+BEGIN;
+SELECT c1 FROM t1;
+
+connection default;
+COMMIT;
+
+connection con1;
+REPLACE INTO t1 VALUES(1984), (1984);
+COMMIT;
+connection default;
+disconnect con1;
+SELECT * FROM t1;
+DROP TABLE t1;
--echo # End of 10.6 tests
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index e44cc466295..d1d264a7e8a 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -4892,7 +4892,11 @@ page_corrupted:
if (trx->isolation_level == TRX_ISO_READ_UNCOMMITTED
|| !trx->read_view.is_open()) {
} else if (trx_id_t bulk_trx_id = index->table->bulk_trx_id) {
- if (!trx->read_view.changes_visible(bulk_trx_id)) {
+ /* InnoDB should allow the transaction to read all
+ the rows when InnoDB intends to do any locking
+ on the record */
+ if (prebuilt->select_lock_type == LOCK_NONE
+ && !trx->read_view.changes_visible(bulk_trx_id)) {
trx->op_info = "";
err = DB_END_OF_INDEX;
goto normal_return;