3 # Changes replication topology. This file is normally sourced from
4 # include/rpl_init.inc, but test cases can also source it if they
5 # need to change topology after they have sourced include/rpl_init.inc
7 # This file sets up variables needed by include/rpl_sync.inc and many
8 # other replication scripts in the include/ directory. It also issues
9 # CHANGE MASTER on all servers where the configuration changes from
10 # what it was before. It does not issue START SLAVE (use
11 # include/rpl_start_slaves.inc for that).
13 # Note: it is not currently possible to change the number of servers
14 # after the rpl_init.inc, without first calling rpl_end.inc. So the
15 # test has to set $rpl_server_count to the total number of servers
16 # that the test uses, before it sources include/rpl_init.inc. After
17 # that, $rpl_server_count must not change until after next time the
18 # test sources include/rpl_end.inc.
20 # Note: Since this script issues CHANGE MASTER, the test case must
21 # ensure that all slaves where the configuration changes have stopped
22 # both the IO thread and the SQL thread before this script is sourced.
27 # [--let $rpl_server_count= 7]
28 # --let $rpl_topology= 1->2->3->1->4, 2->5, 6->7
29 # [--let $use_gtids= 1]
30 # [--let $rpl_skip_change_master= 1]
31 # [--let $rpl_master_log_file= 1:master-bin.000001,3:master-bin.000003]
32 # [--let $rpl_master_log_pos= 1:4711,3:107]
33 # [--let $rpl_debug= 1]
34 # [--let $rpl_unconditional_change_master= 1]
35 # --source include/rpl_change_topology.inc
39 # Use option MASTER_AUTO_POSITION = 1 to CHANGE MASTER.
41 # $rpl_master_log_file
42 # By default, CHANGE MASTER is executed with MASTER_LOG_FILE set
43 # to the name of the last binlog file on the master (retrieved by
44 # executing SHOW MASTER STATUS). This variable can be set to
45 # specify another filename. This variable should be a
46 # comma-separated list of the following form:
48 # SERVER_NUMBER_1:FILE_NAME_1,SERVER_NUMBER_2:FILE_NAME_2,...
50 # Before CHANGE MASTER is executed on server N, this script checks
51 # if $rpl_master_log_file contains the text N:FILE_NAME. If it
52 # does, then MASTER_LOG_FILE is set to FILE_NAME. Otherwise,
53 # MASTER_LOG_FILE is set to the last binlog on the master. For
54 # example, to specify that server_1 should start replicate from
55 # master-bin.000007 and server_5 should start replicate from
56 # master-bin.012345, do:
57 # --let $rpl_master_log_file= 1:master-bin.000007,5:master-bin.012345
60 # By default, CHANGE MASTER is executed without specifying the
61 # MASTER_LOG_POS parameter. This variable can be set to set a
62 # specific position. It has the same form as $rpl_master_log_file
63 # (see above). For example, to specify that server_3 should start
64 # replicate from position 4711 of its master, do:
65 # --let $rpl_master_log_pos= 3:4711
67 # $rpl_unconditional_change_master
68 # This script remembers the topology set by previous invokations
69 # of either rpl_init.inc or of this script. By default, this
70 # script only executes CHANGE MASTER on servers that actually have
71 # a new master. If $rpl_unconditiona_change_master is set, then
72 # this script unconditionally executes CHANGE MASTER on all
73 # servers that have a master. This is useful either if you have
74 # changed the topology without invoking the scripts or if you want
75 # to set some other parameters of CHANGE MASTER.
77 # $rpl_server_count, $rpl_topology, $rpl_debug, $rpl_skip_change_master
78 # See include/rpl_init.inc
81 # ==== Internal variables configured by this file ====
83 # This file sets up the following variables, which are used by other
84 # low-level replication files such as:
85 # include/rpl_sync.inc
86 # include/rpl_start_slaves.inc
87 # include/rpl_stop_slaves.inc
90 # $rpl_server_count_length:
91 # Set to LENGTH($rpl_server_count). So if $rpl_server_count < 10,
92 # then $rpl_server_count_length = 1; if 10 <= $rpl_server_count <
93 # 100, then $rpl_server_count_length = 2, etc.
96 # Set to a string consisting of $rpl_server_count numbers, each one
97 # whitespace-padded to $rpl_server_count_length characters. If
98 # server N is a slave, then the N'th number is the master of server
99 # N. If server N is not a slave, then the N'th number is just spaces
100 # (so in fact it is not a number). For example, if $rpl_topology is
101 # '1->2,2->3,3->1,2->4,5->6', then $rpl_master_list is '3122 6'.
103 # $rpl_sync_chain_dirty
104 # This variable is set to 1. This tells include/rpl_sync.inc to
105 # compute a new value for $rpl_sync_chain next time that
106 # include/rpl_sync.inc is sourced. See
107 # include/rpl_generate_sync_chain.inc and include/rpl_sync.inc for
111 # Remove whitespace from $rpl_topology
112 --let $rpl_topology= `SELECT
REPLACE(
'$rpl_topology',
' ',
'')`
114 --let $include_filename= rpl_change_topology.inc [
new topology=$rpl_topology]
115 --source include/begin_include_file.inc
120 --echo ----
Check input ----
124 if (`SELECT
'$rpl_topology' =
'' OR
'$rpl_server_count' =
''`)
126 --die You must
set $rpl_topology and $rpl_server_count before you source rpl_change_topology.inc. If you really want
to change
to the empty topology,
set $rpl_topology= none
128 --let $_rpl_topology= $rpl_topology
129 if ($_rpl_topology ==
'none')
131 --let $_rpl_topology=
133 if ($rpl_master_list ==
'')
135 --die You must source include/rpl_init.inc before you source include/rpl_change_topology.inc
137 --let $_rpl_old_master_list= $rpl_master_list
141 --echo \$rpl_server_count=
'$rpl_server_count'
142 --echo \$rpl_server_count_length=
'$rpl_server_count_length'
143 --echo new \$rpl_topology=
'$_rpl_topology'
144 --echo old \$rpl_master_list=
'$rpl_master_list'
145 --echo old \$rpl_sync_chain=
'$rpl_sync_chain'
151 --echo ---- Generate \$rpl_server_count_length and \$rpl_master_list ----
154 --let $rpl_server_count_length= `SELECT LENGTH(
'$rpl_server_count')`
155 --let $rpl_master_list=
156 --let $_rpl_no_server= `SELECT REPEAT(
' ', $rpl_server_count_length)`
157 --let $rpl_master_list= `SELECT REPEAT(
'$_rpl_no_server', $rpl_server_count)`
158 while ($_rpl_topology)
160 # Get 's1->s2' from 's1->s2->s3->...' or from 's1->s2,s3->s4,...'
161 --let $_rpl_master_slave= `SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(
'$_rpl_topology',
',', 1),
'->', 2)`
162 # Modify $_rpl_topology as follows:
163 # - If it starts with 's1->s2,', remove 's1->s2,'
164 # - If it starts with 's1->s2->', remove 's1->'
165 # - If it is equal to 's1->s2', remove 's1->s2'
166 --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)`
167 # Get 's1' from 's1->s2'
168 --let $_rpl_master= `SELECT SUBSTRING_INDEX(
'$_rpl_master_slave',
'->', 1)`
169 # Get 's2' from 's1->s2'
170 --let $_rpl_slave= `SELECT SUBSTRING(
'$_rpl_master_slave', LENGTH(
'$_rpl_master') + 3)`
171 # Check that s2 does not have another master.
172 if (`SELECT SUBSTR(
'$rpl_master_list', 1 + ($_rpl_slave - 1) * $rpl_server_count_length, $rpl_server_count_length) !=
'$_rpl_no_server'`)
174 --echo ERROR IN TEST: Server
'$_rpl_slave' has more than one master in topology
'$rpl_topology'
175 --die ERROR IN TEST: found a server with more than one master in the $rpl_topology variable
177 # Save 's1' at position 's2' in $rpl_master_list
178 --let $rpl_master_list= `SELECT INSERT(
'$rpl_master_list', 1 + ($_rpl_slave - 1) * $rpl_server_count_length, $rpl_server_count_length, RPAD(
'$_rpl_master', $rpl_server_count_length,
' '))`
183 --echo new \$rpl_server_count_length =
'$rpl_server_count_length'
184 --echo new \$rpl_master_list =
'$rpl_master_list'
187 if (!$rpl_skip_change_master)
191 --echo ---- Execute CHANGE MASTER on all servers ----
199 --let $_rpl_server= $rpl_server_count
202 if (!$rpl_unconditional_change_master)
204 # The following statement evaluates to:
205 # - The master server, if we need to execute CHANGE MASTER on
206 # server_$_rpl_server.
207 # - The empty string otherwise; i.e., if server_$_rpl_server is
208 # not a slave or if server_$_rpl_server has the same master
211 `SELECT TRIM(IFNULL(NULLIF(
212 SUBSTRING(
'$rpl_master_list',
213 1 + ($_rpl_server - 1) * $rpl_server_count_length,
214 $rpl_server_count_length),
215 SUBSTRING(
'$_rpl_old_master_list',
216 1 + ($_rpl_server - 1) * $rpl_server_count_length,
217 $rpl_server_count_length)
220 if ($rpl_unconditional_change_master)
222 # The following statement evaluates to the master server, or to
223 # the empty string if the server_$_rpl_server is not a slave.
224 let $_rpl_master= `SELECT TRIM(
225 SUBSTRING(
'$rpl_master_list',
226 1 + ($_rpl_server - 1) * $rpl_server_count_length,
227 $rpl_server_count_length)
232 --echo \$_rpl_server=
'$_rpl_server' \$_rpl_master=
'$_rpl_master'
234 if ($_rpl_master !=
'')
237 --let $_rpl_port= \$SERVER_MYPORT_$_rpl_master
240 --let $_rpl_change_master_position= MASTER_AUTO_POSITION = 1
241 --let $rpl_connection_name= server_$_rpl_server
242 --source include/rpl_connection.inc
246 # Get MASTER_LOG_FILE
247 --let $_rpl_master_log_file_index= `SELECT LOCATE(
'$_rpl_server:',
'$rpl_master_log_file')`
248 if ($_rpl_master_log_file_index)
250 # Get text from after ':' and before ',', starting at
251 # $_rpl_master_log_file
252 --let $_rpl_master_log_file= `SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING(
'$rpl_master_log_file', $_rpl_master_log_file_index),
',', 1),
':', -1)`
254 if (!$_rpl_master_log_file_index)
256 --let $rpl_connection_name= server_$_rpl_master
257 --source include/rpl_connection.inc
258 --let $_rpl_master_log_file= query_get_value(SHOW MASTER
STATUS, File, 1)
260 --let $_rpl_change_master_position= MASTER_LOG_FILE =
'$_rpl_master_log_file'
262 --let $rpl_connection_name= server_$_rpl_server
263 --source include/rpl_connection.inc
265 --let $_rpl_master_log_pos_index= `SELECT LOCATE(
'$_rpl_server:',
'$rpl_master_log_pos')`
266 if ($_rpl_master_log_pos_index)
268 --let $_rpl_master_log_pos= `SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING(
'$rpl_master_log_pos', $_rpl_master_log_pos_index),
',', 1),
':', -1)`
269 --let $_rpl_change_master_position= $_rpl_change_master_position, MASTER_LOG_POS = $_rpl_master_log_pos
272 --replace_regex /[0-9]{4}/####/
273 eval CHANGE MASTER TO MASTER_HOST =
'127.0.0.1', MASTER_PORT = $_rpl_port, MASTER_USER =
'root', $_rpl_change_master_position, MASTER_CONNECT_RETRY = 1;
275 if ($_rpl_master ==
'')
277 # This un-configures the server so that it's not a slave.
278 # After BUG#28796, such configuration is not possible any more.
279 #--let $rpl_connection_name= server_$_rpl_server
280 #--source include/rpl_connection.inc
281 #CHANGE MASTER TO MASTER_HOST = '';
288 --let $rpl_sync_chain_dirty= 1
291 --let $include_filename= rpl_change_topology.inc
292 --source include/end_include_file.inc