mirror of
https://github.com/MariaDB/server.git
synced 2025-11-28 17:36:30 +03:00
Suppose binlog file X has in its Gtid_list_event: 0-1-3,0-2-5, and suppose the slave requests to start replicating after 0-1-3. In this case the bug was that master would start sending events from the start of X. This is wrong, because 0-2-4 and 0-2-5 are contained in X-1, and are needed by the slave. So these events were lost. On the other hand, if the slave requested 0-2-5, then it _is_ correct to start sending from the beginning of binlog file X, because 0-2-5 is the last GTID logged in earlier binlogs. The difference is that 0-2-5 is the last of the GTIDs in the Gtid_list_event. The problem was that the code did not check that the matched GTID was the last one in the list. Fixed by checking if the gtid requested by slave that matches a gtid in the Gtid_list_event is the last event for that domain in the list. If not, go back to a prior binlog to ensure all needed events are sent to slave. mysql-test/include/show_events.inc: Backport --let $binlog_file=LAST, used by MDEV-4473 test case.
109 lines
3.0 KiB
PHP
109 lines
3.0 KiB
PHP
# ==== Purpose ====
|
|
#
|
|
# Auxiliary file used in include/show_binlog_events.inc and
|
|
# include/show_relaylog_events.inc.
|
|
#
|
|
# ==== Usage ====
|
|
#
|
|
# See include/show_binlog_events.inc
|
|
|
|
--let $include_filename= show_events.inc
|
|
--source include/begin_include_file.inc
|
|
|
|
--let $_se_old_statement= $statement
|
|
|
|
--let $statement=show BINLOG events
|
|
if ($is_relay_log)
|
|
{
|
|
--let $statement=show relaylog events
|
|
}
|
|
|
|
if ($binlog_file)
|
|
{
|
|
--let $_binlog_file= $binlog_file
|
|
if ($binlog_file == 'LAST')
|
|
{
|
|
if ($is_relay_log)
|
|
{
|
|
--let $_binlog_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1)
|
|
}
|
|
if (!$is_relay_log)
|
|
{
|
|
--let $_binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
|
|
}
|
|
}
|
|
--let $statement= $statement in '$_binlog_file'
|
|
}
|
|
|
|
# Do not modify $binlog_start - if we did, it could wrongly persist until a
|
|
# later call of show_events.inc.
|
|
if ($binlog_start)
|
|
{
|
|
--let $_binlog_start= $binlog_start
|
|
}
|
|
|
|
if (!$binlog_start)
|
|
{
|
|
# If $binlog_start is not set, we will set it as the fourth event's
|
|
# position (second in relay log which has not Binlog Checkpoint nor
|
|
# Gtid_list events).
|
|
# The first three events (Description Event, Gtid list, and Binlog Checkpoint
|
|
# event) are always ignored. For description event's length might be changed
|
|
# because of adding new events, 'SHOW BINLOG EVENTS LIMIT 3' is used to get
|
|
# the right value.
|
|
if ($is_relay_log)
|
|
{
|
|
--let $_binlog_start= query_get_value($statement LIMIT 1, End_log_pos, 1)
|
|
}
|
|
if (!$is_relay_log)
|
|
{
|
|
--let $_binlog_start= query_get_value($statement LIMIT 3, End_log_pos, 3)
|
|
}
|
|
}
|
|
|
|
--let $statement= $statement from $_binlog_start
|
|
|
|
if ($binlog_limit != '')
|
|
{
|
|
--let $statement= $statement limit $binlog_limit
|
|
}
|
|
|
|
# Execute the statement and write to $output_file
|
|
--let $output_file= GENERATE
|
|
--source include/write_result_to_file.inc
|
|
|
|
# Filter the file through the following script.
|
|
--delimiter ||
|
|
let $script=
|
|
# todo: use select_columns instead (requires updating all result files)
|
|
s{([^\t]*\t)[^\t]*(\t[^\t]*\t)[^\t]*\t[^\t]*(\t[^\t]*)}{DOLLAR1#DOLLAR2#\t#DOLLAR3};
|
|
s{/\* xid=.* \*/}{/\* XID \*/};
|
|
s{table_id: [0-9]+}{table_id: #};
|
|
s{file_id=[0-9]+}{file_id=#};
|
|
s{block_len=[0-9]+}{block_len=#};
|
|
s{Server ver:.*DOLLAR}{SERVER_VERSION, BINLOG_VERSION};
|
|
s{GTID [0-9]+-[0-9]+-[0-9]+}{GTID #-#-#};
|
|
s{\[[0-9]-[0-9]-[0-9]+\]}{[#-#-#]};
|
|
s{SQL_LOAD-[a-z,0-9,-]*.[a-z]*}{SQL_LOAD-<SERVER UUID>-<MASTER server-id>-<file-id>.<extension>};
|
|
s{rand_seed1=[0-9]*,rand_seed2=[0-9]*}{rand_seed1=<seed 1>,rand_seed2=<seed 2>};
|
|
s{((?:master|slave|slave-relay)-bin\.[0-9]{6};pos=)[0-9]+DOLLAR}{DOLLAR1POS};
|
|
s{DOLLARmysqltest_vardir}{MYSQLTEST_VARDIR}g;
|
|
||
|
|
--let $pre_script= my DOLLARmysqltest_vardir = DOLLARENV{'MYSQLTEST_VARDIR'};
|
|
--delimiter ;
|
|
|
|
#--let $select_columns= 1 3 6
|
|
--let $input_file= $output_file
|
|
--source include/filter_file.inc
|
|
|
|
# Write to result file
|
|
--cat_file $output_file
|
|
|
|
# Remove the file
|
|
--remove_file $output_file
|
|
|
|
--let $statement= $_se_old_statement
|
|
|
|
--let $include_filename= show_events.inc
|
|
--source include/end_include_file.inc
|