Commit cce2b45c authored by Andrei Elkin's avatar Andrei Elkin

MDEV-17803 Row-based event is not applied when table map id is greater

           32 bit int

Row-based slave applier could not parse correctly the table id when
the value exceeded the max of 32 bit unsigned int.
The reason turns out in that the being parsed value placeholder
was sized as 4 bytes.

The type is fixed to ulonglong.

Additionally the patch works around Rows_log_event::m_table_id 4 bytes
size on 32 bits platforms. In case of last_table_id value overflows
the 4 byte max, there won't be the zero value for m_table_id generated
and the first wrapped-around value is one, this is thanks to excluding
UINT_MAX32 + 1 from TABLE_SHARE::table_map_id.
parent 2a0f1d61
include/master-slave.inc
[connection master]
include/rpl_restart_server.inc [server_number=1]
SET @@debug_dbug="d,simulate_big_table_id";
CREATE TABLE t (a int);
INSERT INTO t SET a= 0;
ALTER TABLE t comment '';
INSERT INTO t SET a= 1;
ALTER TABLE t comment '';
INSERT INTO t SET a= 2;
ALTER TABLE t comment '';
INSERT INTO t SET a= 3;
show binlog events in <file> from <pos>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000002 # Gtid 1 # BEGIN GTID #-#-#
master-bin.000002 # Table_map 1 # table_id: 4294967294 (test.t)
master-bin.000002 # Write_rows_v1 1 # table_id: 4294967294 flags: STMT_END_F
master-bin.000002 # Query 1 # COMMIT
master-bin.000002 # Gtid 1 # GTID #-#-#
master-bin.000002 # Query 1 # use `test`; ALTER TABLE t comment ''
master-bin.000002 # Gtid 1 # BEGIN GTID #-#-#
master-bin.000002 # Table_map 1 # table_id: 1 (test.t)
master-bin.000002 # Write_rows_v1 1 # table_id: 1 flags: STMT_END_F
master-bin.000002 # Query 1 # COMMIT
master-bin.000002 # Gtid 1 # GTID #-#-#
master-bin.000002 # Query 1 # use `test`; ALTER TABLE t comment ''
master-bin.000002 # Gtid 1 # BEGIN GTID #-#-#
master-bin.000002 # Table_map 1 # table_id: 2 (test.t)
master-bin.000002 # Write_rows_v1 1 # table_id: 2 flags: STMT_END_F
master-bin.000002 # Query 1 # COMMIT
master-bin.000002 # Gtid 1 # GTID #-#-#
master-bin.000002 # Query 1 # use `test`; ALTER TABLE t comment ''
master-bin.000002 # Gtid 1 # BEGIN GTID #-#-#
master-bin.000002 # Table_map 1 # table_id: 3 (test.t)
master-bin.000002 # Write_rows_v1 1 # table_id: 3 flags: STMT_END_F
master-bin.000002 # Query 1 # COMMIT
DROP TABLE t;
include/rpl_end.inc
include/master-slave.inc
[connection master]
include/rpl_restart_server.inc [server_number=1]
SET @@debug_dbug="d,simulate_big_table_id";
CREATE TABLE t (a int);
INSERT INTO t SET a= 0;
ALTER TABLE t comment '';
INSERT INTO t SET a= 1;
ALTER TABLE t comment '';
INSERT INTO t SET a= 2;
ALTER TABLE t comment '';
INSERT INTO t SET a= 3;
show binlog events in <file> from <pos>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000002 # Gtid 1 # BEGIN GTID #-#-#
master-bin.000002 # Table_map 1 # table_id: 4294967294 (test.t)
master-bin.000002 # Write_rows_v1 1 # table_id: 4294967294 flags: STMT_END_F
master-bin.000002 # Query 1 # COMMIT
master-bin.000002 # Gtid 1 # GTID #-#-#
master-bin.000002 # Query 1 # use `test`; ALTER TABLE t comment ''
master-bin.000002 # Gtid 1 # BEGIN GTID #-#-#
master-bin.000002 # Table_map 1 # table_id: 4294967295 (test.t)
master-bin.000002 # Write_rows_v1 1 # table_id: 4294967295 flags: STMT_END_F
master-bin.000002 # Query 1 # COMMIT
master-bin.000002 # Gtid 1 # GTID #-#-#
master-bin.000002 # Query 1 # use `test`; ALTER TABLE t comment ''
master-bin.000002 # Gtid 1 # BEGIN GTID #-#-#
master-bin.000002 # Table_map 1 # table_id: 4294967296 (test.t)
master-bin.000002 # Write_rows_v1 1 # table_id: 4294967296 flags: STMT_END_F
master-bin.000002 # Query 1 # COMMIT
master-bin.000002 # Gtid 1 # GTID #-#-#
master-bin.000002 # Query 1 # use `test`; ALTER TABLE t comment ''
master-bin.000002 # Gtid 1 # BEGIN GTID #-#-#
master-bin.000002 # Table_map 1 # table_id: 4294967297 (test.t)
master-bin.000002 # Write_rows_v1 1 # table_id: 4294967297 flags: STMT_END_F
master-bin.000002 # Query 1 # COMMIT
DROP TABLE t;
include/rpl_end.inc
##################################################################
# rpl_row_big_table_id
#
# MDEV-17803 Row-based event is not applied when
# table map id is greater 32 bit int
#
# Verify row-based events applying when table map id value is about and greater
# than 1 << 32.
##################################################################
--source include/have_debug.inc
--source include/have_binlog_format_row.inc
--source include/master-slave.inc
--connection master
# To reset last table id
--let $rpl_server_number= 1
--source include/rpl_restart_server.inc
SET @@debug_dbug="d,simulate_big_table_id";
CREATE TABLE t (a int);
--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
--let $binlog_pos= query_get_value(SHOW MASTER STATUS, Position, 1)
INSERT INTO t SET a= 0;
ALTER TABLE t comment '';
INSERT INTO t SET a= 1;
ALTER TABLE t comment '';
INSERT INTO t SET a= 2;
ALTER TABLE t comment '';
INSERT INTO t SET a= 3;
# display simulated big table_id
--let $_in_from=in '$binlog_file' from $binlog_pos
--replace_result "$_in_from" "in <file> from <pos>"
--replace_column 2 # 5 #
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /file_id=[0-9]+/file_id=#/ /GTID [0-9]+-[0-9]+-[0-9]+/GTID #-#-#/
--eval show binlog events in '$binlog_file' from $binlog_pos
--sync_slave_with_master
if (`SELECT sum(a) != 6 FROM t`)
{
--echo *** unexpected result; check slave applier ***
--die
}
# Cleanup
--connection master
DROP TABLE t;
--sync_slave_with_master
--source include/rpl_end.inc
##################################################################
# rpl_row_big_table_id
#
# MDEV-17803 Row-based event is not applied when
# table map id is greater 32 bit int
#
# Verify row-based events applying when table map id value is about and greater
# than 1 << 32.
##################################################################
--source include/have_32bit.inc
--source rpl_row_big_table_id.inc
##################################################################
# rpl_row_big_table_id
#
# MDEV-17803 Row-based event is not applied when
# table map id is greater 32 bit int
#
# Verify row-based events applying when table map id value is about and greater
# than 1 << 32.
##################################################################
--source include/have_64bit.inc
--source rpl_row_big_table_id.inc
...@@ -1816,7 +1816,7 @@ struct TABLE_LIST ...@@ -1816,7 +1816,7 @@ struct TABLE_LIST
/* Index names in a "... JOIN ... USE/IGNORE INDEX ..." clause. */ /* Index names in a "... JOIN ... USE/IGNORE INDEX ..." clause. */
List<Index_hint> *index_hints; List<Index_hint> *index_hints;
TABLE *table; /* opened table */ TABLE *table; /* opened table */
uint table_id; /* table id (from binlog) for opened table */ ulonglong table_id; /* table id (from binlog) for opened table */
/* /*
select_result for derived table to pass it from table creation to table select_result for derived table to pass it from table creation to table
filling procedure filling procedure
......
...@@ -1206,6 +1206,9 @@ void tdc_assign_new_table_id(TABLE_SHARE *share) ...@@ -1206,6 +1206,9 @@ void tdc_assign_new_table_id(TABLE_SHARE *share)
DBUG_ASSERT(share); DBUG_ASSERT(share);
DBUG_ASSERT(tdc_inited); DBUG_ASSERT(tdc_inited);
DBUG_EXECUTE_IF("simulate_big_table_id",
if (last_table_id < UINT_MAX32)
last_table_id= UINT_MAX32 - 1;);
/* /*
There is one reserved number that cannot be used. Remember to There is one reserved number that cannot be used. Remember to
change this when 6-byte global table id's are introduced. change this when 6-byte global table id's are introduced.
...@@ -1215,7 +1218,7 @@ void tdc_assign_new_table_id(TABLE_SHARE *share) ...@@ -1215,7 +1218,7 @@ void tdc_assign_new_table_id(TABLE_SHARE *share)
my_atomic_rwlock_wrlock(&LOCK_tdc_atomics); my_atomic_rwlock_wrlock(&LOCK_tdc_atomics);
tid= my_atomic_add64(&last_table_id, 1); tid= my_atomic_add64(&last_table_id, 1);
my_atomic_rwlock_wrunlock(&LOCK_tdc_atomics); my_atomic_rwlock_wrunlock(&LOCK_tdc_atomics);
} while (unlikely(tid == ~0UL)); } while (unlikely(tid == ~0UL || tid == 0));
share->table_map_id= tid; share->table_map_id= tid;
DBUG_PRINT("info", ("table_id= %lu", share->table_map_id)); DBUG_PRINT("info", ("table_id= %lu", share->table_map_id));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment