1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
|
# ==== Purpose ====
#
# This test script serves as the functionality testing for the table
# performance_schema.replication_connection_status. Test for ddl and dml
# operations is a part of the perfschema suite. The ddl/dml tests are named:
# 1) ddl_replication_connection_status.test and
# 2) dml_replication_connection_status.test.
#
# This test script does the following:
# - Verify that SELECT works for every field in the table.
# - The SELECT per field produces an output similar to the corresponding field
# in SHOW SLAVE STATUS(SSS), if there is one.
# - If there is no matching field in SSS, we resort to other method of testing
# those fields.
#
# The follwing scenarios are tested:
#
# - Test each field on a fresh replication setup.
# - Cause an error in the IO thread and check for the correctness of the error
# number, meaasge and timestamp field.
# - Verify that the error fields are preserved after STOP SLAVE, thread_id
# changes to NULL and service_state to "off".
# - Start server with gtid-mode=on and test the RECEIVED_TRANSACTION_SET field.
# Also, make sure the value in this field is preserved after STOP SLAVE.
# - Test Group Replication related fields. They should be set NULL when plugin
# is not installed on slave.
# - When Group Replication plugin is not installed, table must return an empty
# set.
# ==== Related Worklog ====
#
# WL#3656: PERFORMANCE SCHEMA table for SHOW SLAVE STATUS
# WL#6841: PERFORMANCE SCHEMA to show Group Replication kernel stats
#
source include/not_valgrind.inc;
source include/master-slave.inc;
source include/have_binlog_format_mixed.inc;
--let $assert_text= On master, the table should return an empty set.
--let $assert_cond= [select count(*) from performance_schema.replication_connection_status] = 0
--source include/assert.inc
--connection slave
--let $Group_Name= query_get_value(select Group_Name from performance_schema.replication_connection_status, Group_Name, 1)
--let $assert_text= On slave, the group_name should be set NULL
--let $assert_cond= "$Group_Name"= ""
--source include/assert.inc
--echo
--echo # Verify that SELECT works for every field and produces an output similar
--echo # to the corresponding field in SHOW SLAVE STATUS(SSS). To verify the
--echo # correctness of thread_id field, we check for the name of the thread.
--echo
let $sss_value= query_get_value(SHOW SLAVE STATUS, Master_UUID, 1);
let $ps_value= query_get_value(select Source_UUID from performance_schema.replication_connection_status, Source_UUID, 1);
let $assert_text= Value returned by SSS and PS table for Source_UUID should be same.;
let $assert_cond= "$sss_value" = "$ps_value";
source include/assert.inc;
let $thread_name= `select name from performance_schema.threads where thread_id= (select Thread_Id from performance_schema.replication_connection_status)`;
let $assert_text= thread_name should should indicate io thread.;
let $assert_cond= "$thread_name" = "thread/sql/replica_io";
source include/assert.inc;
let $sss_value= query_get_value(SHOW SLAVE STATUS, Slave_IO_Running, 1);
let $ps_value= query_get_value(select Service_State from performance_schema.replication_connection_status, Service_State, 1);
let $assert_text= SSS shows Slave_IO_Running as "Yes". So, Service_State from this PS table should be "ON".;
let $assert_cond= "$sss_value" = "Yes" AND "$ps_value"= "ON";
source include/assert.inc;
#
# Heartbeat count and last hearbeat timestamp are not in SSS, but these are in
# IS. So to test count_received_heartbeats and last_heartbeat_timestamp
# we compare values from IS and PS unlike SSS and PS for other fields in this
# test.
let $ps_value= query_get_value(select last_heartbeat_timestamp from performance_schema.replication_connection_status, last_heartbeat_timestamp, 1);
let $assert_text= PS table should output 0000-00-00 00:00:00.000000 indicating no heartbeats have been received;
let $assert_cond= "$ps_value"= "0000-00-00 00:00:00.000000";
source include/assert.inc;
let $sss_value= query_get_value(SHOW SLAVE STATUS, Retrieved_Gtid_Set, 1);
let $ps_value= query_get_value(select Received_Transaction_Set from performance_schema.replication_connection_status, Received_Transaction_Set, 1);
let $assert_text= Value returned by SSS and PS table for Received_Transaction_Set should be same.;
let $assert_cond= "$sss_value" = "$ps_value";
source include/assert.inc;
let $sss_value= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1);
let $ps_value= query_get_value(select Last_Error_Number from performance_schema.replication_connection_status, Last_Error_Number, 1);
let $assert_text= Value returned by SSS and PS table for Last_Error_Number should be same.;
let $assert_cond= "$sss_value" = "$ps_value";
source include/assert.inc;
let $sss_value= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1);
let $ps_value= query_get_value(select Last_Error_Message from performance_schema.replication_connection_status, Last_Error_Message, 1);
let $assert_text= Value returned by SSS and PS table for Last_Error_Message should be same.;
let $assert_cond= "$sss_value" = "$ps_value";
source include/assert.inc;
let $sss_value= query_get_value(SHOW SLAVE STATUS, Last_IO_Error_Timestamp, 1);
let $ps_value= query_get_value(select Last_Error_Timestamp from performance_schema.replication_connection_status, Last_Error_Timestamp, 1);
let $assert_text= Value returned by PS table for Last_Error_Timestamp should be 0000-00-00 00:00:00.000000.;
let $assert_cond= "$ps_value" = "0000-00-00 00:00:00.000000";
source include/assert.inc;
source include/stop_slave.inc;
--echo
--echo # heartbeat count and last heartbeat timestamp are indeterministic so we
--echo # can not test for their exact values. We will thus check for >0 number
--echo # of heartbeats and last heartbeat timestamp!= zeros.
--echo
CHANGE REPLICATION SOURCE to SOURCE_HEARTBEAT_PERIOD= 0.5;
set @restore_replica_net_timeout= @@global.replica_net_timeout;
set @@global.replica_net_timeout= 10;
source include/start_slave.inc;
# there is an explicit sleep lasting longer than replica_net_timeout
# to ensure that nothing will come to slave from master for that period.
# That would cause reconnecting and relaylog rotation w/o the fix i.e
# without a heartbeat received.
sleep 15;
#
# proof that there has been received at least one heartbeat;
# The exact number of received heartbeat is an indeterministic value
# and therefore it's not recorded into results.
#
let $slave_wait_param_counter= 300;
let $slave_value= query_get_value(select count_received_heartbeats from performance_schema.replication_connection_status, count_received_heartbeats, 1);
# Checking the fact that at least one heartbeat is received
while (!$slave_value)
{
dec $slave_wait_param_counter;
if (!$slave_wait_param_counter)
{
query_vertical show slave status;
select count_received_heartbeats from performance_schema.replication_connection_status;
--die ERROR: failed while waiting for replica to generate a heartbeat.
exit;
}
sleep 0.1;
let $slave_value= query_get_value(select count_received_heartbeats from performance_schema.replication_connection_status, count_received_heartbeats, 1);
}
--echo
--echo A heartbeat has been received by the slave
--echo
#
# check for non-zero value of the Slave_last_heartbeat variable when the slave is enabled
#
let $ps_value= query_get_value(select last_heartbeat_timestamp from performance_schema.replication_connection_status, last_heartbeat_timestamp, 1);
let $assert_text= last_heartbeat_timestamp should NOT be zero;
let $assert_cond= "$ps_value" != "0000-00-00 00:00:00";
source include/assert.inc;
# Reset replica_net_timeout to default after testing heartbeats.
set @@global.replica_net_timeout= @restore_replica_net_timeout;
--echo
--echo # We now introduce an error in the IO thread and check for the correctness
--echo # of error number, message and timestamp fields.
--echo
# Cause an error in IO thread.
--connection slave
source include/stop_slave.inc;
replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR;
replace_column 2 ####;
eval CHANGE REPLICATION SOURCE to
SOURCE_USER='replssl',
SOURCE_PASSWORD='';
start slave io_thread;
let $slave_param= Last_IO_Errno;
let $slave_param_value= 1045;
source include/wait_for_slave_param.inc;
--echo
--echo # Extract the error related fields from SSS and PS table and compare
--echo # them for correctness.
--echo
let $sss_value= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1);
let $ps_value= query_get_value(select Last_Error_Number from performance_schema.replication_connection_status, Last_Error_Number, 1);
let $assert_text= Value returned by SSS and PS table for Last_Error_Number should be same.;
let $assert_cond= "$sss_value" = "$ps_value";
source include/assert.inc;
# Availability of special characters like single quote and backtick character
# makes it difficult use the assert.inc or mysql functionstrcmp().
# So, the equality of error messages is checked using the below perl code.
let $sss_value= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1);
let $ps_value= query_get_value(select Last_Error_Message from performance_schema.replication_connection_status, Last_Error_Message, 1);
let PS_VALUE= $ps_value;
let SSS_VALUE= $sss_value;
perl;
use strict;
my $ps_value= $ENV{'PS_VALUE'};
my $sss_value= $ENV{'SSS_VALUE'};
if ($ps_value eq $sss_value)
{
print "Value returned by SSS and PS table for Last_Error_Message is same.\n";
}
else
{
print "Value returned by SSS and PS table for Last_Error_Message is NOT same\n";
}
EOF
# End of perl code for testing the error message.
# The timestamp format is slightly different in SSS and PS.
# SSS => YYMMDD HH:MM:SS
# PS => YYYY-MM-DD HH:MM:SS.ssssss
# To match the two, we get rid of hyphons from PS output and first two digits
# the year field and the microseconds (after WL7319) so that it can be matched
# directly.
let $sss_value= query_get_value(SHOW SLAVE STATUS, Last_IO_Error_Timestamp, 1);
let $ps_value= query_get_value(select Last_Error_Timestamp from performance_schema.replication_connection_status, Last_Error_Timestamp, 1);
let $ps_value_without_hyphons= `SELECT REPLACE("$ps_value", '-', '')`;
let $ps_value_in_sss_format= `select substring("$ps_value_without_hyphons", 3)`;
let $ps_value_without_microseconds= `select substring_index("$ps_value_in_sss_format", '.', 1)`;
let $assert_text= Value returned by SSS and PS table for Last_Error_Timestamp should be same.;
let $assert_cond= "$sss_value" = "$ps_value_without_microseconds";
source include/assert.inc;
--echo
--echo # Verify that source_UUID and the error related fields are preserved
--echo # after STOP SLAVE, thread_id changes to NULL and service_state to "off".
--echo
--let $slave_io_errno= convert_error(ER_ACCESS_DENIED_ERROR)
source include/stop_slave.inc;
--echo
--echo # 1. Verify that thread_id changes to NULL and service_state to "off" on
--echo # STOP SLAVE.
--echo
let $ps_value= query_get_value(select thread_id from performance_schema.replication_connection_status, thread_id, 1);
let $assert_text= After STOP SLAVE, thread_id should be NULL;
let $assert_cond= "$ps_value" = "NULL";
source include/assert.inc;
let $sss_value= query_get_value(SHOW SLAVE STATUS, Slave_IO_Running, 1);
let $ps_value= query_get_value(select Service_State from performance_schema.replication_connection_status, Service_State, 1);
let $assert_text= SSS shows Slave_IO_Running as "No". So, Service_State from this PS table should be "OFF".;
let $assert_cond= "$sss_value" = "No" AND "$ps_value"= "OFF";
source include/assert.inc;
--echo
--echo # 2. Extract the source_UUID and the error related fields from SSS and PS
--echo # table and compare them. These fields should preserve their values.
--echo
let $sss_value= query_get_value(SHOW SLAVE STATUS, Master_UUID, 1);
let $ps_value= query_get_value(select Source_UUID from performance_schema.replication_connection_status, Source_UUID, 1);
let $assert_text= Value returned by SSS and PS table for Source_UUID should be same.;
let $assert_cond= "$sss_value" = "$ps_value";
source include/assert.inc;
let $sss_value= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1);
let $ps_value= query_get_value(select Last_Error_Number from performance_schema.replication_connection_status, Last_Error_Number, 1);
let $assert_text= Value returned by SSS and PS table for Last_Error_Number should be same.;
let $assert_cond= "$sss_value" = "$ps_value";
source include/assert.inc;
# Availability of special characters like single quote and backtick character
# makes it difficult use the assert.inc or mysql functionstrcmp().
# So, the equality of error messages is checked using the below perl code.
let $sss_value= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1);
let $ps_value= query_get_value(select Last_Error_Message from performance_schema.replication_connection_status, Last_Error_Message, 1);
let PS_VALUE= $ps_value;
let SSS_VALUE= $sss_value;
perl;
use strict;
my $ps_value= $ENV{'PS_VALUE'};
my $sss_value= $ENV{'SSS_VALUE'};
if ($ps_value eq $sss_value)
{
print "Value returned by SSS and PS table for Last_Error_Message is same.\n";
}
else
{
print "Value returned by SSS and PS table for Last_Error_Message is NOT same\n";
}
EOF
# End of perl code for testing error message.
# The timestamp format is slightly different in SSS and PS.
# SSS => YYMMDD HH:MM:SS
# PS => YYYY-MM-DD HH:MM:SS.ssssss
# To match the two, we get rid of hyphons from PS output and first two digits
# the year field and also the microseconds (after WL#7319) so that it can be
# matched directly.
let $sss_value= query_get_value(SHOW SLAVE STATUS, Last_IO_Error_Timestamp, 1);
let $ps_value= query_get_value(select Last_Error_Timestamp from performance_schema.replication_connection_status, Last_Error_Timestamp, 1);
let $assert_text= Value returned by SSS and PS table for Last_Error_Timestamp should be same.;
let $ps_value_without_hyphons= `SELECT REPLACE("$ps_value", '-', '')`;
let $ps_value_in_sss_format= `select substring("$ps_value_without_hyphons", 3)`;
let $ps_value_without_microseconds= `select substring_index("$ps_value_in_sss_format", '.', 1)`;
let $assert_text= Value returned by SSS and PS table for Last_Error_Timestamp should be same.;
let $assert_cond= "$sss_value" = "$ps_value_without_microseconds";
source include/assert.inc;
--echo
--echo # Restart the master and slave servers in gtid-mode=on, execute some
--echo # transactions and verify the 'Received_Transaction_Set' field.
--echo
let $rpl_server_number= 1;
let $rpl_start_with_gtids= 1;
source include/rpl_restart_server.inc;
let $rpl_server_number= 2;
let $rpl_start_with_gtids= 1;
source include/rpl_restart_server.inc;
--connection slave
replace_column 2 ####;
CHANGE REPLICATION SOURCE to
SOURCE_USER = 'root',
SOURCE_AUTO_POSITION= 1;
source include/start_slave.inc;
--connection master
use test;
create table t(a int);
insert into t values(1);
--source include/sync_slave_sql_with_master.inc
let $sss_value= query_get_value(SHOW SLAVE STATUS, Retrieved_Gtid_Set, 1);
let $ps_value= query_get_value(select Received_Transaction_Set from performance_schema.replication_connection_status, Received_Transaction_Set, 1);
let $assert_text= Value returned by SSS and PS table for Received_Transaction_Set should be same.;
let $assert_cond= "$sss_value" = "$ps_value";
source include/assert.inc;
--echo
--echo # Verify that the value for 'Received_Transaction_Set' field is preserved
--echo # after STOP SLAVE.
--echo
--source include/stop_slave.inc
--let $old_ps_value= $ps_value
--let $assert_text= Received_Transaction_Set should not have changed after STOP SLAVE
--let $assert_cond= "$ps_value" = "$old_ps_value";
--source include/assert.inc
--echo
--echo # Verify that the value for 'Received_Transaction_Set' is cleared
--echo # after RESET SLAVE.
--echo
RESET SLAVE;
--let $assert_cond= Received_Transaction_Set = "" FROM performance_schema.replication_connection_status
--let $assert_text= Received_Transaction_Set should be empty after RESET SLAVE
--source include/assert.inc
source include/start_slave.inc;
--connection master
drop table t;
--source include/sync_slave_sql_with_master.inc
let $rpl_only_running_threads= 1;
source include/stop_slave.inc;
--connection slave
CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION = 0 FOR CHANNEL '';
# Reset the gtid mode if the test started with gtid_mode=OFF
if ($gtid_mode_on == 0) {
--let $rpl_gtid_mode = 0
--let $rpl_set_enforce_gtid_consistency = 0
}
--let $no_extra_info = 1
--source include/rpl_set_gtid_mode.inc
source include/rpl_end.inc;
|