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
|
# ==== Purpose ====
#
# This test script serves as the functionality testing for the table
# performance_schema.replication_applier_status_by_worker. Test
# for ddl and dml operations is a part of the perfschema suite.
# The ddl/dml tests are named:
# 1) ddl_replication_applier_status_by_worker.test and
# 2) dml_replication_applier_status_by_worker.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.
# - We perform all the testing on connection "slave". On master, the table
# returns an empty set.
#
# The follwing scenarios are tested in this test script:
#
# - Test each field on a fresh replication setup.
# - Introduce error in worker thread and check for the correctness of error
# error number, message and timestamp.
# - Verify that, the change in values are correctly shown by the table.
# - Verify that the values are preserved after STOP SLAVE.
# - Set up replication in gtid-mode=on and test 'Last_Seen_Transaction' field.
# - Verify that the value in 'Last_Seen_Transaction' field is preserved after
# STOP SLAVE.
#
# ==== Related Bugs and Worklogs ====
#
# MDEV-20220: Merge 5.7 P_S replication table 'replication_applier_status_by_worker
#
--source include/have_perfschema.inc
--source include/have_binlog_format_mixed.inc
--source include/have_innodb.inc
--source include/master-slave.inc
let $assert_text= On master, the table should return an empty set.;
let $assert_cond= count(*) = 0 from performance_schema.replication_applier_status_by_worker;
source include/assert.inc;
--echo
--echo # Setup MTS and perform testing on a fresh slave.
--echo
--connection slave
call mtr.add_suppression("Error 'Table 'test.t' doesn't exist' on query.");
source include/stop_slave.inc;
set @save_slave_parallel_workers= @@global.slave_parallel_workers;
# to avoid warnings
set @save_slave_transaction_retries= @@global.slave_transaction_retries;
RESET SLAVE ALL;
evalp CHANGE MASTER 'slave1' TO MASTER_USER='root',MASTER_PORT=$MASTER_MYPORT, MASTER_HOST='127.0.0.1', MASTER_USE_GTID=slave_pos, MASTER_SSL_VERIFY_SERVER_CERT=0;
SET default_master_connection='slave1';
SET @@global.slave_parallel_workers=1;
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
START SLAVE 'slave1';
--source include/wait_for_slave_to_start.inc
let $ps_value= query_get_value(select channel_name from performance_schema.replication_applier_status_by_worker, channel_name, 1);
let $assert_text= Channel_name will be empty for a worker when it has not processed any transaction;
let $assert_cond= "$ps_value"= "";
source include/assert.inc;
# To verify the correctness of thread_id field, we check for the name of
# the thread.
let $thread_name= `select name from performance_schema.threads where thread_id= (select Thread_Id from performance_schema.replication_applier_status_by_worker)`;
let $assert_text= thread_name should should indicate worker thread.;
let $assert_cond= "$thread_name" = "thread/sql/rpl_parallel";
source include/assert.inc;
let $ps_value= query_get_value(select Service_State from performance_schema.replication_applier_status_by_worker, Service_State, 1);
let $assert_text= Service_State should be "ON" on a fresh slave server.;
let $assert_cond= "$ps_value"= "ON";
source include/assert.inc;
let $ps_value= query_get_value(select Last_Seen_Transaction from performance_schema.replication_applier_status_by_worker, Last_Seen_Transaction, 1);
let $assert_text= Last_Seen_Transaction should show "" if no transaction applierd;
let $assert_cond= "$ps_value" = "";
source include/assert.inc;
--connection master
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
--source include/save_master_gtid.inc
connection slave;
--source include/sync_with_master_gtid.inc
let $ps_value= query_get_value(select channel_name from performance_schema.replication_applier_status_by_worker, channel_name, 1);
let $assert_text= Channel_name must be slave1;
let $assert_cond= "$ps_value"= "slave1";
source include/assert.inc;
let $ps_value= query_get_value(select Last_Seen_Transaction from performance_schema.replication_applier_status_by_worker, Last_Seen_Transaction, 1);
let $sss_value= query_get_value(SHOW SLAVE STATUS, Gtid_IO_Pos, 1);
let $assert_text= Last_Seen_Transaction should show $sss_value;
let $assert_cond= "$ps_value" = "$sss_value";
source include/assert.inc;
let $sss_value= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1);
let $ps_value= query_get_value(select Last_Error_Number from performance_schema.replication_applier_status_by_worker, 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_SQL_Error, 1);
let $ps_value= query_get_value(select Last_Error_Message from performance_schema.replication_applier_status_by_worker, Last_Error_Message, 1);
let $assert_text= Value returned by SSS and PS table for Last_Error_Message should both be empty.;
let $assert_cond= "$sss_value" = "$ps_value";
source include/assert.inc;
let $ps_value= query_get_value(select Last_Error_Timestamp from performance_schema.replication_applier_status_by_worker, Last_Error_Timestamp, 1);
let $assert_text= Value returned by PS table for Last_Error_Timestamp should be 0000-00-00 00:00:00.;
let $assert_cond= "$ps_value" = "0000-00-00 00:00:00";
source include/assert.inc;
--connection master
sleep 1;
--connection slave
let $ps_value= query_get_value(select worker_idle_time from performance_schema.replication_applier_status_by_worker, worker_idle_time, 1);
let $assert_text= Value returned by PS table for worker_idle_time should be >= 1;
let $assert_cond= "$ps_value" >= "1";
source include/assert.inc;
--connection master
DROP TABLE t1;
--save_master_pos
--connection slave
--sync_with_master 0,'slave1'
STOP SLAVE 'slave1';
--source include/wait_for_slave_to_stop.inc
RESET SLAVE ALL;
SET default_master_connection='';
evalp CHANGE MASTER TO MASTER_USER='root', MASTER_HOST='127.0.0.1',MASTER_PORT=$MASTER_MYPORT;
--source include/start_slave.inc
--echo
--echo # Introduce an error in the worker thread and check for the correctness
--echo # of error number, message and timestamp fields.
--echo
# Cause an error in Worker thread.
# 1) Create a table 't' at master, replicate at slave.
# 2) Drop table 't' at slave only.
# 3) Insert a value in table 't' on master and replicate on slave.
# Since slave doesnt have table 't' anymore, worker thread will report an error.
--connection master
use test;
create table t(a int primary key);
sync_slave_with_master;
drop table t;
--connection master
insert into t values(1);
--connection slave
let $slave_sql_errno=1146;
source include/wait_for_slave_sql_error.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_SQL_Errno, 1);
let $ps_value= query_get_value(select Last_Error_Number from performance_schema.replication_applier_status_by_worker, 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;
--disable_query_log
--replace_regex /master-bin.[0-9]+/FILENAME/ /end_log_pos [0-9]+/end_log_pos POSITION/
select Last_Error_Message from performance_schema.replication_applier_status_by_worker;
--enable_query_log
--echo
--echo # Verify that the error fields are preserved after STOP SLAVE.
--echo
--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_applier_status_by_worker, 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 $ps_value= query_get_value(select service_state from performance_schema.replication_applier_status_by_worker, service_state, 1);
let $assert_text= So, Service_State after STOP SLAVE should be "OFF".;
let $assert_cond= "$ps_value"= "OFF";
source include/assert.inc;
--echo
--echo # 2. Extract the worker_id 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, Last_SQL_Errno, 1);
let $ps_value= query_get_value(select Last_Error_Number from performance_schema.replication_applier_status_by_worker, 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;
--disable_query_log
--replace_regex /master-bin.[0-9]+/FILENAME/ /end_log_pos [0-9]+/end_log_pos POSITION/
select Last_Error_Message from performance_schema.replication_applier_status_by_worker;
--enable_query_log
# The timestamp format is slightly different in SSS and PS.
# SSS => YYMMDD HH:MM:SS
# PS => YYYY-MM-DD HH:MM:SS
# To match the two, we get rid of hyphons from PS output and first two digits
# the year field so that it can be matched directly.
#--- TODO: Can we include Last_SQL_Error_Timestamp as part of SSS
#let $sss_value= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error_Timestamp, 1);
#let $ps_value= query_get_value(select Last_Error_Timestamp from performance_schema.replication_applier_status_by_worker, 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 $assert_text= Value returned by SSS and PS table for Last_Error_Timestamp should be same.;
#let $assert_cond= "$sss_value" = "$ps_value_in_sss_format";
#source include/assert.inc;
--let $rpl_only_running_threads= 1
--source include/stop_slave.inc
RESET SLAVE;
--connection master
DROP TABLE t;
RESET MASTER;
--echo
--echo # Verify that number of rows in 'replication_applier_status_by_worker' table match with
--echo # number of slave_parallel_workers.
--echo
--connection slave
SET @@global.slave_parallel_workers=4;
--source include/start_slave.inc
--let $assert_text= On slave, the table should return 4 rows.
--let $assert_cond= count(*) = 4 from performance_schema.replication_applier_status_by_worker
--source include/assert.inc
--source include/stop_slave.inc
--echo
--echo # Cleanup.
--echo
set @@global.slave_parallel_workers= @save_slave_parallel_workers;
set @@global.slave_transaction_retries= @save_slave_transaction_retries;
source include/start_slave.inc;
source include/rpl_end.inc;
|