mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
Bug#12346411 SQL/LOG.CC:6509: ASSERTION `PREPARED_XIDS > 0' FAILED
This assert could be triggered during two phase commit if binary log was used as transaction coordinator log. The triggered assert checks that the same number of transaction IDs are processed in the prepare and commit phases. The reason it was triggered, was that the transaction consisted of an INSERT/UPDATE IGNORE that had an ignorable error. Since it had an error, no row log events were made and therefore prepared_xids was 0. However, since it was an IGNORE statement, the statement started a read/write statement transaction, committed it and completed successfully. This patch fixes the problem by adjusting the assert to take this possibility into account. Test case added to binlog.binlog_innodb_row.test.
This commit is contained in:
@@ -59,3 +59,20 @@ show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `t1` /* generated by server */
|
||||
###############################################
|
||||
#
|
||||
# Bug#12346411 SQL/LOG.CC:6509: ASSERTION `PREPARED_XIDS > 0' FAILED
|
||||
#
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
CREATE TABLE t1(a INT PRIMARY KEY) engine=innodb;
|
||||
CREATE TABLE t2(a INT) engine=myisam;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
START TRANSACTION;
|
||||
INSERT INTO t2 VALUES (1);
|
||||
INSERT IGNORE INTO t1 VALUES (1);
|
||||
COMMIT;
|
||||
INSERT INTO t1 VALUES (2);
|
||||
START TRANSACTION;
|
||||
INSERT INTO t2 VALUES (2);
|
||||
UPDATE IGNORE t1 SET a=1 WHERE a=2;
|
||||
COMMIT;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
@@ -77,3 +77,29 @@ DROP TEMPORARY TABLE t1;
|
||||
-- echo ###############################################
|
||||
-- source include/show_binlog_events.inc
|
||||
-- echo ###############################################
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Bug#12346411 SQL/LOG.CC:6509: ASSERTION `PREPARED_XIDS > 0' FAILED
|
||||
--echo #
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1(a INT PRIMARY KEY) engine=innodb;
|
||||
CREATE TABLE t2(a INT) engine=myisam;
|
||||
|
||||
INSERT INTO t1 VALUES (1);
|
||||
START TRANSACTION;
|
||||
INSERT INTO t2 VALUES (1);
|
||||
INSERT IGNORE INTO t1 VALUES (1);
|
||||
COMMIT;
|
||||
|
||||
INSERT INTO t1 VALUES (2);
|
||||
START TRANSACTION;
|
||||
INSERT INTO t2 VALUES (2);
|
||||
UPDATE IGNORE t1 SET a=1 WHERE a=2;
|
||||
COMMIT;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
@@ -6506,8 +6506,11 @@ int TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
|
||||
{
|
||||
DBUG_ENTER("TC_LOG_BINLOG::unlog");
|
||||
mysql_mutex_lock(&LOCK_prep_xids);
|
||||
DBUG_ASSERT(prepared_xids > 0);
|
||||
if (--prepared_xids == 0) {
|
||||
// prepared_xids can be 0 if the transaction had ignorable errors.
|
||||
DBUG_ASSERT(prepared_xids >= 0);
|
||||
if (prepared_xids > 0)
|
||||
prepared_xids--;
|
||||
if (prepared_xids == 0) {
|
||||
DBUG_PRINT("info", ("prepared_xids=%lu", prepared_xids));
|
||||
mysql_cond_signal(&COND_prep_xids);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user