24
25
"""test replication administration commands
25
26
This test runs the mysqlrpladmin utility on a known topology.
27
Note: this test will run against older servers. See rpl_admin_gtid
28
test for test cases for GTID enabled servers.
28
Note: this test will run against servers without GTID enabled.
29
See rpl_admin_gtid test for test cases for GTID enabled servers.
31
32
def check_prerequisites(self):
32
if self.servers.get_server(0).check_version_compat(5, 6, 5):
33
raise MUTLibError("Test requires server version prior to 5.6.5")
33
if not self.servers.get_server(0).check_version_compat(5, 5, 30):
34
raise MUTLibError("Test requires server version 5.5.30 or later.")
35
if self.servers.get_server(0).supports_gtid() == "ON":
36
raise MUTLibError("Test requires servers without GTID enabled.")
34
37
return self.check_num_servers(1)
36
39
def spawn_server(self, name, mysqld=None, kill=False):
79
82
self.server3 = self.spawn_server("rep_slave2")
80
83
self.server4 = self.spawn_server("rep_slave3")
85
# Reset spawned servers (clear binary log and GTID_EXECUTED set)
82
88
self.m_port = self.server1.port
83
89
self.s1_port = self.server2.port
84
90
self.s2_port = self.server3.port
85
91
self.s3_port = self.server4.port
87
93
for slave in [self.server2, self.server3, self.server4]:
94
slave.exec_query("SET SQL_LOG_BIN= 0")
88
95
slave.exec_query("GRANT REPLICATION SLAVE ON *.* TO "
89
"'rpl'@'localhost' IDENTIFIED BY 'rpl'")
96
"'rpl'@'%s' IDENTIFIED BY 'rpl'" %
98
slave.exec_query("SET SQL_LOG_BIN= 1")
91
100
# Form replication topology - 1 master, 3 slaves
92
101
return self.reset_topology()
151
160
raise MUTLibError("%s: failed" % comment)
154
cmd_str = "mysqlrpladmin.py --master=%s " % master_conn
155
cmd_opts = " health --disc=root:root "
156
cmd_opts += "--slaves=%s" % slaves_loopback
157
comment= "Test case %s - health with loopback and discovery" % test_num
158
res = mutlib.System_test.run_test_case(self, 0, cmd_str+cmd_opts,
161
raise MUTLibError("%s: failed" % comment)
164
# Perform stop, start, and reset
163
cmd_str = ("mysqlrpladmin.py --master={0} health "
164
"--slaves={1}").format(master_conn, slaves_loopback)
165
comment = "Test case {0} - health with loopback".format(test_num)
166
res = self.run_test_case(0, cmd_str, comment)
168
raise MUTLibError("{0}: failed".format(comment))
171
cmd_str = ("mysqlrpladmin.py --master={0} health "
172
"--disc=root:root").format(master_conn)
173
comment = "Test case {0} - health with discovery".format(test_num)
174
res = self.run_test_case(0, cmd_str, comment)
176
raise MUTLibError("{0}: failed".format(comment))
179
# Perform stop, start, and reset (with --master option)
165
180
commands = ['stop', 'start', 'stop', 'reset']
166
181
for cmd in commands:
167
comment = "Test case %s - run command %s" % (test_num, cmd)
168
cmd_str = "mysqlrpladmin.py --master=%s " % master_conn
169
cmd_opts = " --slaves=%s %s" % (slaves_str, cmd)
170
res = mutlib.System_test.run_test_case(self, 0, cmd_str+cmd_opts,
173
raise MUTLibError("%s: failed" % comment)
182
comment = ("Test case {0} - run command {1} with "
183
"--master").format(test_num, cmd)
184
cmd_str = ("mysqlrpladmin.py --master={0} --slaves={1} "
185
"{2}").format(master_conn, slaves_str, cmd)
186
res = self.run_test_case(0, cmd_str, comment)
188
raise MUTLibError("%s: failed" % comment)
190
# START SLAVE is asynchronous and it can take some time to complete
193
time.sleep(3) # wait 3 second for START to finish
195
# Needed to reset the topology here to run with 5.1 servers.
196
# Note: With 5.1 servers after reset commands slaves seem to forgot
197
# about their master.
198
self.reset_topology()
200
# Perform stop, start, and reset (without --master option)
201
commands = ['start', 'stop', 'reset']
203
comment = ("Test case {0} - run command {1} without "
204
"--master").format(test_num, cmd)
205
cmd_str = ("mysqlrpladmin.py --slaves={0} "
206
"{1}").format(slaves_str, cmd)
207
res = self.run_test_case(0, cmd_str, comment)
209
raise MUTLibError("%s: failed" % comment)
176
212
# Now we return the topology to its original state for other tests
177
213
self.reset_topology()
186
222
self.replace_substring(str(self.s1_port), "PORT2")
187
223
self.replace_substring(str(self.s2_port), "PORT3")
188
224
self.replace_substring(str(self.s3_port), "PORT4")
190
def reset_topology(self):
191
# Form replication topology - 1 master, 3 slaves
226
self.replace_substring(": NO", ": XXX") # for columns.
227
self.replace_substring("| NO ", "| XXX")
228
self.replace_substring("OFF", "XXX")
230
# Mask slaves behind master.
231
# It happens sometimes on windows in a non-deterministic way.
232
self.replace_substring("+--------------------------------------------"
233
"--+", "+---------+")
234
self.replace_substring("| health "
236
self.replace_substring("| OK "
238
self.replace_substring("| Slave delay is 1 seconds behind master., "
240
self.replace_substring("| Slave delay is 2 seconds behind master., "
242
self.replace_substring("| Slave delay is 3 seconds behind master., "
244
self.replace_substring("| Slave delay is 4 seconds behind master., "
247
def reset_master(self, servers_list=[]):
248
# Clear binary log and GTID_EXECUTED of given servers
250
servers = servers_list
252
servers = [self.server1, self.server2, self.server3, self.server4]
255
srv.exec_query("RESET MASTER")
256
except Exception as err:
257
raise MUTLibError("Unexpected error performing RESET MASTER "
258
"for server %s:%s: %s"
259
% (srv.host, srv.port, err))
261
def reset_topology(self, slaves_list=[]):
265
# Default replication topology - 1 master, 3 slaves
266
slaves = [self.server2, self.server3, self.server4]
192
267
self.master_str = " --master=%s" % \
193
268
self.build_connection_string(self.server1)
194
for slave in [self.server1, self.server2, self.server3, self.server4]:
270
servers = [self.server1]
271
servers.extend(slaves)
272
for slave in servers:
196
274
slave.exec_query("STOP SLAVE")
197
275
slave.exec_query("RESET SLAVE")
201
for slave in [self.server2, self.server3, self.server4]:
202
280
slave_str = " --slave=%s" % self.build_connection_string(slave)
203
281
conn_str = self.master_str + slave_str
204
cmd = "mysqlreplicate.py --rpl-user=rpl:rpl %s" % conn_str
282
cmd = "mysqlreplicate.py --rpl-user=rpl:rpl %s -vvv" % conn_str
205
283
res = self.exec_util(cmd, self.res_fname)