polardbxengine/mysql-test/suite/rpl/t/rpl_perfschema_connect_stat...

382 lines
16 KiB
Plaintext

# ==== 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/slave_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 master to master_heartbeat_period= 0.5;
set @restore_slave_net_timeout= @@global.slave_net_timeout;
set @@global.slave_net_timeout= 10;
source include/start_slave.inc;
# there is an explicit sleep lasting longer than slave_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.
real_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 slave 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 slave_net_timeout to default after testing heartbeats.
set @@global.slave_net_timeout= @restore_slave_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 master to
master_user='replssl',
master_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 master to
master_user = 'root',
master_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;
source include/rpl_end.inc;