polardbxengine/mysql-test/include/rpl_change_topology.inc

257 lines
10 KiB
PHP

# ==== Purpose ====
#
# Changes replication topology. This file is normally sourced from
# include/rpl_init.inc, but test cases can also source it if they
# need to change topology after they have sourced include/rpl_init.inc
#
# This file sets up variables needed by include/rpl_sync.inc and many
# other replication scripts in the include/ directory. It also issues
# CHANGE MASTER on all servers where the configuration changes from
# what it was before. It does not issue START SLAVE (use
# include/rpl_start_slaves.inc for that).
#
# Note: it is not currently possible to change the number of servers
# after the rpl_init.inc, without first calling rpl_end.inc. So the
# test has to set $rpl_server_count to the total number of servers
# that the test uses, before it sources include/rpl_init.inc. After
# that, $rpl_server_count must not change until after next time the
# test sources include/rpl_end.inc.
#
# Note: Since this script issues CHANGE MASTER, the test case must
# ensure that all slaves where the configuration changes have stopped
# both the IO thread and the SQL thread before this script is sourced.
#
#
# ==== Usage ====
#
# [--let $rpl_server_count= 7]
# --let $rpl_topology= 1->2->3->1->4, 2->5, 6->7
# [--let $rpl_multi_source= 1]
# [--let $use_gtids= 1]
# [--let $rpl_group_replication= 1]
# [--let $rpl_skip_change_master= 1]
# [--let $rpl_master_log_file= 1:master-bin.000001,3:master-bin.000003]
# [--let $rpl_master_log_pos= 1:4711,3:107]
# [--let $rpl_debug= 1]
# [--let $rpl_unconditional_change_master= 1]
# [--let $rpl_privilege_checks_user= *:'user'@'host',1:'user'@'host',2:NULL]
# [--let $rpl_privilege_checks_user_dont_create_user= 0]
# --source include/rpl_change_topology.inc
#
# Parameters:
# $use_gtids
# Use option MASTER_AUTO_POSITION = 1 to CHANGE MASTER.
#
# $rpl_master_log_file
# By default, CHANGE MASTER is executed without specifying the
# MASTER_LOG_FILE parameter. This variable can be set to specify a
# filename. This variable should be a comma-separated list of the
# following form:
#
# SERVER_NUMBER_1:FILE_NAME_1,SERVER_NUMBER_2:FILE_NAME_2,...
#
# Before CHANGE MASTER is executed on server N, this script checks
# if $rpl_master_log_file contains the text N:FILE_NAME. If it
# does, then MASTER_LOG_FILE is set to FILE_NAME. Otherwise,
# MASTER_LOG_FILE is not specified. For example, to specify that
# server_1 should start replicate from master-bin.000007 and
# server_5 should start replicate from master-bin.012345, do:
#
# --let $rpl_master_log_file= 1:master-bin.000007,5:master-bin.012345
#
# $rpl_master_log_pos
# By default, CHANGE MASTER is executed without specifying the
# MASTER_LOG_POS parameter. This variable can be set to set a
# specific position. It has the same form as $rpl_master_log_file
# (see above). For example, to specify that server_3 should start
# replicate from position 4711 of its master, do:
# --let $rpl_master_log_pos= 3:4711
#
# $rpl_unconditional_change_master
# This script remembers the topology set by previous invokations
# of either rpl_init.inc or of this script. By default, this
# script only executes CHANGE MASTER on servers that actually have
# a new master. If $rpl_unconditiona_change_master is set, then
# this script unconditionally executes CHANGE MASTER on all
# servers that have a master. This is useful either if you have
# changed the topology without invoking the scripts or if you want
# to set some other parameters of CHANGE MASTER.
#
# $rpl_server_count, $rpl_topology, $rpl_debug,
# $rpl_skip_change_master, $rpl_multi_source
# See include/rpl_init.inc
#
# $rpl_group_replication
# This checks for whether we have Group Replication enabled or not. Based
# on the check this parameter we execute change master or not in this
# inc file.
#
# $rpl_privilege_checks_user By default, CHANGE MASTER is executed without
# specifying the `PRIVILEGE_CHECKS_USER` parameter. Instantiating
# `$rpl_privilege_checks_user` sets the `PRIVILEGE_CHECKS_USER` option for
# the `CHANGE MASTER TO...` command, bounding the replication applier to
# execute within the security context of the given user. For example, to
# specify that server_1 should use 'u1'@'localhost' as base user for
# replication applier security context and server_5 shouldn't check
# privileges while applying replicated events, do:
#
# --let $rpl_privilege_checks_user= 1:'u1'@'localhost',5:NULL
#
# To specify that all node applier thread should run with a given user's
# security context, do:
#
# --let $rpl_privilege_checks_user= *:'u1'@'localhost'
#
# $rpl_privilege_checks_user_dont_create_user
# Force to not create the user provided in `$rpl_privilege_checks_user`. If
# set to 0, creates it if doesn't exists and, if created, assigns the
# `REPLICATION_APPLIER` privilege.
#
# ==== Internal variables configured by this file ====
#
# This file sets up the following variables, which are used by other
# low-level replication files such as:
# include/rpl_sync.inc
# include/rpl_start_slaves.inc
# include/rpl_stop_slaves.inc
# include/rpl_end.inc
#
# $rpl_connection_list
# This variable will be set to a string consisting of N master-slave
# specifications, where N is the number of master-slave
# connections. Each master-slave specification has the form
# 'm<NUMBER1> s<NUMBER2> '. This indicates that server <NUMBER1> is a
# direct master of server <NUMBER2>. Each <NUMBER> is padded to the
# right by spaces to a fixed width of $rpl_server_count_length. For
# example, if $rpl_topology is '1->2->3->1,2->4,5->6', then
# $rpl_connection_list is 'm1 s2 m2 s3 m3 s1 m2 s4 m5 s6'.
# The length of this variable is exactly
# 2*(2+$rpl_connection_count_length)*$rpl_connection_list.
#
# $rpl_sync_chain_dirty
# This variable is set to 1. This tells include/rpl_sync.inc to
# compute a new value for $rpl_sync_chain next time that
# include/rpl_sync.inc is sourced. See
# include/rpl_generate_sync_chain.inc and include/rpl_sync.inc for
# details.
#
# See also rpl_init.inc
# Remove whitespace from $rpl_topology
--let $rpl_topology= `SELECT REPLACE('$rpl_topology', ' ', '')`
--let $include_filename= rpl_change_topology.inc [new topology=$rpl_topology]
--source include/begin_include_file.inc
if ($rpl_debug)
{
--echo ---- Check input ----
}
# $rpl_server_count must not change between rpl_init.inc and rpl_end.inc
if ($rpl_server_count != $_rpl_server_count)
{
--die ERROR IN TEST: Detected that $rpl_server_count has changed. You are not allowed to change this between rpl_init.inc and rpl_end.inc.
}
# $rpl_topology must be set
if ($rpl_topology == '')
{
--die ERROR IN TEST: You must set $rpl_topology before you source include/rpl_change_topology.inc. If you really want to change to the empty topology, set $rpl_topology= none
}
--let $_rpl_topology= $rpl_topology
if ($_rpl_topology == 'none')
{
--let $_rpl_topology=
}
# include/rpl_init.inc should be invoked before this file
if (!$rpl_inited)
{
--die ERROR IN TEST: You must source include/rpl_init.inc before you source include/rpl_change_topology.inc
}
--let $_rpl_old_connection_list= $rpl_connection_list
if ($rpl_debug)
{
--echo \$rpl_server_count='$rpl_server_count'
--echo \$rpl_server_count_length='$rpl_server_count_length'
--echo old \$rpl_connection_list='$rpl_connection_list'
--echo old \$rpl_sync_chain='$rpl_sync_chain'
--echo new \$rpl_topology='$_rpl_topology'
}
if ($rpl_debug)
{
--echo ---- Generate \$rpl_connection_list and \$rpl_connection_count ----
}
--let $rpl_connection_list=
--let $rpl_connection_count= 0
while ($_rpl_topology)
{
# Get 's1->s2' from 's1->s2->s3->...' or from 's1->s2,s3->s4,...'
--let $_rpl_master_slave= `SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('$_rpl_topology', ',', 1), '->', 2)`
# Modify $_rpl_topology as follows:
# - If it starts with 's1->s2,', remove 's1->s2,'
# - If it starts with 's1->s2->', remove 's1->'
# - If it is equal to 's1->s2', remove 's1->s2'
--let $_rpl_topology= `SELECT SUBSTR('$_rpl_topology', IF(SUBSTR('$_rpl_topology', LENGTH('$_rpl_master_slave') + 1, 2) != '->', LENGTH('$_rpl_master_slave'), LOCATE('->', '$_rpl_master_slave')) + 2)`
# Get 's1' from 's1->s2'
--let $_rpl_master= `SELECT RPAD(SUBSTRING_INDEX('$_rpl_master_slave', '->', 1), $rpl_server_count_length, ' ')`
# Get 's2' from 's1->s2'
--let $_rpl_slave= `SELECT RPAD(SUBSTRING('$_rpl_master_slave', LENGTH('$_rpl_master') + 3), $rpl_server_count_length, ' ')`
if (!$rpl_multi_source)
{
# Check that s2 does not have another master.
if (`SELECT LOCATE('s$_rpl_slave ', '$rpl_connection_list') != 0`)
{
--echo ERROR IN TEST: Server '$_rpl_slave' has more than one master in topology '$rpl_topology'
--die ERROR IN TEST: found a server with more than one master in the $rpl_topology variable
}
}
# Append 'm<s1> s<s2> ' to $rpl_connection_list
--let $_rpl_new_connection= m$_rpl_master s$_rpl_slave$_rpl_space
--let $rpl_connection_list= $rpl_connection_list$_rpl_new_connection
--inc $rpl_connection_count
}
if ($rpl_debug)
{
--echo new \$rpl_connection_list = '$rpl_connection_list'
--echo new \$rpl_connection_count = '$rpl_connection_count'
}
--let $_rpl_change_topology_privilege_checks_all_index= `SELECT LOCATE('*:', "$rpl_privilege_checks_user")`
if ($_rpl_change_topology_privilege_checks_all_index)
{
--let $_rpl_change_topology_privilege_checks_all= `SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING("$rpl_privilege_checks_user", $_rpl_change_topology_privilege_checks_all_index), ',', 1), ':', -1)`
}
if (!$rpl_skip_change_master)
{
if ($rpl_debug)
{
--echo ---- Execute CHANGE MASTER on all servers ----
}
if (!$rpl_debug)
{
--disable_query_log
}
--let $rpl_source_file= include/rpl_change_topology_helper.inc
--source include/rpl_for_each_connection.inc
}
--let $rpl_sync_chain_dirty= 1
--let $_rpl_change_topology_privilege_checks_all=
--let $_rpl_change_topology_privilege_checks_all_index=
--let $include_filename= rpl_change_topology.inc
--source include/end_include_file.inc