Skip to content

Commit 3900147

Browse files
committed
MDEV-26031 unnessary xid logging in one phase commit case
The bug was originally observed as hanging binlog background thread at shutdown similar to one of MDEV-21120. It occurred through unnessary xid logging in 1pc execution. Two parts of the issue are fixed. Per engine loop by involved engine with attempt to mark a group requiring xid unlogging gets corrected in two ways. Do not execute it when the termination event is irrelevant for recovery, does not have xid in particular. Do not break the loop anymore unconditionally at the end of the 1st iteration.
1 parent c29f45c commit 3900147

File tree

3 files changed

+87
-5
lines changed

3 files changed

+87
-5
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
RESET MASTER;
2+
CREATE TABLE t (f INT) ENGINE=INNODB;
3+
CREATE TABLE ta (f INT) ENGINE=Aria;
4+
BEGIN;
5+
INSERT INTO t SET f = 1;
6+
INSERT INTO ta SET f = 1;
7+
COMMIT;
8+
include/show_binlog_events.inc
9+
Log_name Pos Event_type Server_id End_log_pos Info
10+
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
11+
master-bin.000001 # Query # # use `test`; INSERT INTO ta SET f = 1
12+
master-bin.000001 # Query # # COMMIT
13+
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
14+
master-bin.000001 # Query # # use `test`; INSERT INTO t SET f = 1
15+
master-bin.000001 # Query # # COMMIT
16+
# Prove that binlog is resettable. Under the bug condition it was not.
17+
RESET MASTER;
18+
SET @@binlog_format = ROW;
19+
CREATE TABLE ta2 ENGINE = Aria SELECT * from t;
20+
include/show_binlog_events.inc
21+
Log_name Pos Event_type Server_id End_log_pos Info
22+
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
23+
master-bin.000001 # Query # # use `test`; CREATE TABLE `ta2` (
24+
`f` int(11) DEFAULT NULL
25+
) ENGINE=Aria PAGE_CHECKSUM=1
26+
master-bin.000001 # Annotate_rows # # CREATE TABLE ta2 ENGINE = Aria SELECT * from t
27+
master-bin.000001 # Table_map # # table_id: # (test.ta2)
28+
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
29+
master-bin.000001 # Query # # COMMIT
30+
# Prove that binlog is resettable. Under the bug condition it was not.
31+
RESET MASTER;
32+
# Cleanup
33+
DROP TABLE ta2, ta, t;
34+
# End of the tests
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# The test file contains tests specific to one phase commit
2+
# execution and binlogging.
3+
#
4+
# MDEV-26031 unnessary xid logging in one phase commit case
5+
#
6+
--source include/have_innodb.inc
7+
--source include/have_aria.inc
8+
--source include/have_binlog_format_mixed.inc
9+
10+
RESET MASTER;
11+
12+
CREATE TABLE t (f INT) ENGINE=INNODB;
13+
CREATE TABLE ta (f INT) ENGINE=Aria;
14+
15+
--let $binlog_start = query_get_value(SHOW MASTER STATUS, Position, 1)
16+
BEGIN;
17+
INSERT INTO t SET f = 1;
18+
INSERT INTO ta SET f = 1;
19+
COMMIT;
20+
--let $binlog_file = query_get_value(SHOW MASTER STATUS, File, 1)
21+
--source include/show_binlog_events.inc
22+
23+
--echo # Prove that binlog is resettable. Under the bug condition it was not.
24+
RESET MASTER;
25+
26+
--let $binlog_start = query_get_value(SHOW MASTER STATUS, Position, 1)
27+
--let $binlog_file = query_get_value(SHOW MASTER STATUS, File, 1)
28+
SET @@binlog_format = ROW;
29+
CREATE TABLE ta2 ENGINE = Aria SELECT * from t;
30+
--source include/show_binlog_events.inc
31+
32+
--echo # Prove that binlog is resettable. Under the bug condition it was not.
33+
RESET MASTER;
34+
35+
36+
--echo # Cleanup
37+
DROP TABLE ta2, ta, t;
38+
39+
--echo # End of the tests

sql/log.cc

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2186,11 +2186,20 @@ int binlog_commit(THD *thd, bool all, bool ro_1pc)
21862186
*/
21872187
if (likely(!error) && ending_trans(thd, all))
21882188
{
2189-
error= is_preparing_xa(thd) ?
2189+
bool is_xa_prepare= is_preparing_xa(thd);
2190+
2191+
error= is_xa_prepare ?
21902192
binlog_commit_flush_xa_prepare(thd, all, cache_mngr) :
21912193
binlog_commit_flush_trx_cache (thd, all, cache_mngr, ro_1pc);
2194+
// the user xa is unlogged on common exec path with the "empty" xa case
2195+
if (cache_mngr->need_unlog && !is_xa_prepare)
2196+
{
2197+
error=
2198+
mysql_bin_log.unlog(BINLOG_COOKIE_MAKE(cache_mngr->binlog_id,
2199+
cache_mngr->delayed_error), 1);
2200+
cache_mngr->need_unlog= false;
2201+
}
21922202
}
2193-
21942203
/*
21952204
This is part of the stmt rollback.
21962205
*/
@@ -7634,16 +7643,16 @@ MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd,
76347643
entry.need_unlog= is_preparing_xa(thd);
76357644
ha_info= all ? thd->transaction->all.ha_list : thd->transaction->stmt.ha_list;
76367645
entry.ro_1pc= is_ro_1pc;
7646+
entry.end_event= end_ev;
7647+
auto has_xid= entry.end_event->get_type_code() == XID_EVENT;
76377648

7638-
for (; !entry.need_unlog && ha_info; ha_info= ha_info->next())
7649+
for (; has_xid && !entry.need_unlog && ha_info; ha_info= ha_info->next())
76397650
{
76407651
if (ha_info->is_started() && ha_info->ht() != binlog_hton &&
76417652
!ha_info->ht()->commit_checkpoint_request)
76427653
entry.need_unlog= true;
7643-
break;
76447654
}
76457655

7646-
entry.end_event= end_ev;
76477656
if (cache_mngr->stmt_cache.has_incident() ||
76487657
cache_mngr->trx_cache.has_incident())
76497658
{

0 commit comments

Comments
 (0)