Skip to content

Commit a1af525

Browse files
FooBarriorvuvova
authored andcommitted
MDEV-31804 Assertion `thd->m_transaction_psi == __null' fails
... upon replicating online ALTER When an online event is applied and slave_exec_mode is idempotent, Write_rows_log_event::do_before_row_operations had reset thd->lex->sql_command to SQLCOM_REPLACE. This led to that a statement was detected as a row-type during binlogging, and was logged as not standalone. So the corresponding Gtid_log_event, when applied on replica, did not exit early and created a new PSI transaction. Hence the difference with non-online ALTER.
1 parent c373e6c commit a1af525

File tree

5 files changed

+77
-2
lines changed

5 files changed

+77
-2
lines changed

mysql-test/suite/rpl/r/rpl_alter_online_debug.result

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,29 @@ connection master;
44
call mtr.add_suppression("Unsafe statement written to the binary log using statement format");
55
connection slave;
66
call mtr.add_suppression("Unsafe statement written to the binary log using statement format");
7+
# MDEV-31804 Assertion `thd->m_transaction_psi == __null' fails upon
8+
# replicating online ALTER
9+
connection master;
10+
create table t (a char(8)) engine=myisam;
11+
insert into t values ('foo'),('bar');
12+
set debug_sync= 'alter_table_online_progress signal go_dml wait_for go_alter';
13+
set @old_slave_exec_mode= @@global.slave_exec_mode;
14+
set @@global.slave_exec_mode= idempotent;
15+
alter table t force;
16+
connection master1;
17+
set debug_sync= 'now wait_for go_dml';
18+
insert into t (a) values ('qux');
19+
set debug_sync= 'now signal go_alter';
20+
connection master;
21+
connection slave;
22+
connection master;
23+
drop table t;
24+
set global slave_exec_mode= @old_slave_exec_mode;
25+
set debug_sync= reset;
26+
#
27+
# End of 11.2 tests (Single-phase alter)
28+
#
29+
connection slave;
730
include/stop_slave.inc
831
set global slave_parallel_threads=3;
932
set global slave_parallel_mode= optimistic;
@@ -49,6 +72,9 @@ connection master;
4972
drop table t;
5073
connection slave;
5174
connection master;
75+
#
76+
# End of 11.2 tests (Two-phase alter)
77+
#
5278
connection slave;
5379
include/stop_slave.inc
5480
set global binlog_row_image=FULL;

mysql-test/suite/rpl/t/rpl_alter_online_debug.test

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,46 @@ call mtr.add_suppression("Unsafe statement written to the binary log using state
88
--connection slave
99
call mtr.add_suppression("Unsafe statement written to the binary log using statement format");
1010

11+
#
12+
# Single-phase alter
13+
#
14+
15+
--echo # MDEV-31804 Assertion `thd->m_transaction_psi == __null' fails upon
16+
--echo # replicating online ALTER
17+
--connection master
18+
create table t (a char(8)) engine=myisam;
19+
insert into t values ('foo'),('bar');
20+
21+
set debug_sync= 'alter_table_online_progress signal go_dml wait_for go_alter';
22+
set @old_slave_exec_mode= @@global.slave_exec_mode;
23+
set @@global.slave_exec_mode= idempotent;
24+
send alter table t force;
25+
26+
--connection master1
27+
set debug_sync= 'now wait_for go_dml';
28+
insert into t (a) values ('qux');
29+
set debug_sync= 'now signal go_alter';
30+
31+
--connection master
32+
--reap
33+
--sync_slave_with_master
34+
35+
# Cleanup
36+
--connection master
37+
drop table t;
38+
set global slave_exec_mode= @old_slave_exec_mode;
39+
set debug_sync= reset;
40+
41+
42+
--echo #
43+
--echo # End of 11.2 tests (Single-phase alter)
44+
--echo #
45+
46+
47+
#
48+
# Two-phase alter
49+
#
50+
--connection slave
1151
source include/stop_slave.inc;
1252
--let $slave_parallel_threads=`select @@global.slave_parallel_threads`
1353
--let $slave_parallel_mode= `select @@global.slave_parallel_mode`
@@ -75,7 +115,7 @@ drop table t;
75115
--connection master
76116

77117
--echo #
78-
--echo # End of 11.2 tests
118+
--echo # End of 11.2 tests (Two-phase alter)
79119
--echo #
80120

81121
--connection slave

sql/log_event.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,9 @@ const char* Log_event::get_type_str()
719719
Log_event::Log_event(const uchar *buf,
720720
const Format_description_log_event* description_event)
721721
:temp_buf(0), exec_time(0), cache_type(Log_event::EVENT_INVALID_CACHE),
722+
#ifndef MYSQL_CLIENT
723+
slave_exec_mode(SLAVE_EXEC_MODE_STRICT),
724+
#endif
722725
checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
723726
{
724727
#ifndef MYSQL_CLIENT

sql/log_event_server.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ int append_query_string(CHARSET_INFO *csinfo, String *to,
545545

546546
Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
547547
:log_pos(0), temp_buf(0), exec_time(0),
548+
slave_exec_mode(SLAVE_EXEC_MODE_STRICT),
548549
checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF), thd(thd_arg)
549550
{
550551
server_id= thd->variables.server_id;
@@ -569,6 +570,7 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
569570

570571
Log_event::Log_event()
571572
:temp_buf(0), exec_time(0), flags(0), cache_type(EVENT_INVALID_CACHE),
573+
slave_exec_mode(SLAVE_EXEC_MODE_STRICT),
572574
checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF), thd(0)
573575
{
574576
server_id= global_system_variables.server_id;
@@ -5099,7 +5101,8 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
50995101
bitmap_set_bit(table->write_set, table->s->vers.end_fieldno);
51005102
}
51015103

5102-
this->slave_exec_mode= (enum_slave_exec_mode)slave_exec_mode_options;
5104+
if (!rpl_data.is_online_alter())
5105+
this->slave_exec_mode= (enum_slave_exec_mode)slave_exec_mode_options;
51035106

51045107
// Do event specific preparations
51055108
error= do_before_row_operations(rgi);

sql/sql_table.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12116,6 +12116,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
1211612116
MEM_UNDEFINED(from->record[0], from->s->rec_buff_length * 2);
1211712117
MEM_UNDEFINED(to->record[0], to->s->rec_buff_length * 2);
1211812118
thd_progress_next_stage(thd);
12119+
enum_sql_command saved_sql_command= thd->lex->sql_command;
1211912120
Table_map_log_event table_event(thd, from, from->s->table_map_id,
1212012121
from->file->has_transactions());
1212112122
Relay_log_info rli(false);
@@ -12171,6 +12172,8 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
1217112172
if (error)
1217212173
from->s->tdc->flush_unused(1); // to free the binlog
1217312174
to->pos_in_table_list= NULL; // Safety
12175+
DBUG_ASSERT(thd->lex->sql_command == saved_sql_command);
12176+
thd->lex->sql_command= saved_sql_command; // Just in case
1217412177
}
1217512178
else if (online) // error was on copy stage
1217612179
{

0 commit comments

Comments
 (0)