summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2023-03-22 14:15:36 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2023-03-22 17:20:41 +0530
commit8afa679d50285a784fcc27d08b23c279832dd998 (patch)
treea585339bcb733c39e901571a6f044640a4b81ec0
parent535a38c4559160c7a46f0d9ece52495b83718d45 (diff)
downloadmariadb-git-bb-10.6-MDEV-29545.tar.gz
MDEV-29545 InnoDB: Can't find record during replace stmtbb-10.6-MDEV-29545
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;