summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Nesterenko <brandon.nesterenko@mariadb.com>2021-11-15 16:33:45 -0700
committerBrandon Nesterenko <brandon.nesterenko@mariadb.com>2021-11-15 16:33:45 -0700
commitc3329b48619016865f8690146833e1704a334921 (patch)
treece8d7d43433aaa74fba584d35ceef2eeabff240e
parent7ea12742d30be7b56120f1bf66d91f777b1da450 (diff)
downloadmariadb-git-bb-10.3-DBAAS-7828.tar.gz
DBAAS-7828: Primary/replica: configuration change of autocommit=0 can not be appliedbb-10.3-DBAAS-7828
Problem: ======== When the mysql.gtid_slave_pos table uses the InnoDB engine, and mysqld starts, it reads the table and begins a transaction. After reading the value, it should end the transaction and release all associated locks. The bug reported in DBAAS-7828 shows that when autocommit is off, the locks are not released, resulting in indefinite hangs on future attempts to change gtid_slave_pos. In particular, the transaction was not properly finalized because thd->server_status was not updated to reflect the end of the transaction. Solution: ======== This patch updates the code to properly commit the transaction after reading gtid_slave_pos during mysqld start-up. Reviewed By: ============ Andrei Elkin <andrei.elkin@mariadb.com>
-rw-r--r--mysql-test/suite/binlog/r/binlog_autocommit_off_no_hang.result6
-rw-r--r--mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang-master.opt1
-rw-r--r--mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test45
-rw-r--r--sql/rpl_rli.cc2
4 files changed, 53 insertions, 1 deletions
diff --git a/mysql-test/suite/binlog/r/binlog_autocommit_off_no_hang.result b/mysql-test/suite/binlog/r/binlog_autocommit_off_no_hang.result
new file mode 100644
index 00000000000..71eecd881ca
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_autocommit_off_no_hang.result
@@ -0,0 +1,6 @@
+ALTER TABLE mysql.gtid_slave_pos ENGINE=innodb;
+# Restart the server so mysqld reads the gtid_slave_pos using innodb
+# Set gtid_slave_pos should not hang
+SET GLOBAL gtid_slave_pos=@@gtid_binlog_pos;
+COMMIT;
+RESET MASTER;
diff --git a/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang-master.opt b/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang-master.opt
new file mode 100644
index 00000000000..e0fa81e6eeb
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang-master.opt
@@ -0,0 +1 @@
+--autocommit=0
diff --git a/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test b/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test
new file mode 100644
index 00000000000..8f1dbb2a2dd
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test
@@ -0,0 +1,45 @@
+#
+# Purpose:
+# When the mysql.gtid_slave_pos table uses the InnoDB engine, and mysqld
+# starts, it reads the table and begins a transaction. After mysqld reads the
+# value, it should end the transaction and release all associated locks.
+# The bug reported in DBAAS-7828 shows that when autocommit is off, the locks
+# are not released, resulting in indefinite hangs on future attempts to change
+# gtid_slave_pos. This test ensures its fix such that the locks are properly
+# released.
+#
+# References:
+# DBAAS-7828: Primary/replica: configuration change of "autocommit=0" can
+# not be applied
+#
+
+--source include/have_innodb.inc
+--source include/have_log_bin.inc
+
+# Reading gtid_slave_pos table is format independent so just use one for
+# reduced test time
+--source include/have_binlog_format_row.inc
+
+--let old_slave_pos_engine= query_get_value(SHOW TABLE STATUS FROM mysql LIKE 'gtid_slave_pos', Engine, 1)
+
+# Use a transactional engine
+ALTER TABLE mysql.gtid_slave_pos ENGINE=innodb;
+
+--echo # Restart the server so mysqld reads the gtid_slave_pos using innodb
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--shutdown_server
+--source include/wait_until_disconnected.inc
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+
+--echo # Set gtid_slave_pos should not hang
+SET GLOBAL gtid_slave_pos=@@gtid_binlog_pos;
+COMMIT;
+
+# Revert table type
+--disable_query_log
+--eval ALTER TABLE mysql.gtid_slave_pos ENGINE=$old_slave_pos_engine
+--enable_query_log
+
+RESET MASTER;
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 88cb8fc5e1e..176801130d7 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1675,7 +1675,7 @@ end:
{
table->file->ha_index_or_rnd_end();
ha_commit_trans(thd, FALSE);
- ha_commit_trans(thd, TRUE);
+ trans_commit(thd);
}
if (table_opened)
{