From 1502ee4f7c39d81b2b87808ccf1022c52ea94ef6 Mon Sep 17 00:00:00 2001 From: Hui Liu Date: Thu, 23 Jan 2020 14:29:07 -0800 Subject: [PATCH] FB8-201: Add semi sync and replication status to SHOW SLAVE HOSTS (#1096) (#1096) Summary: Jira issue: https://jira.percona.com/browse/FB8-201 Reference Patch: https://github.com/facebook/mysql-5.6/commit/b5ad812f53e Reference Patch: https://github.com/facebook/mysql-5.6/commit/cc1081494bf Add two additional columns to "show slave hosts": Is_semi_sync_slave and Replication_status. Pull Request resolved: https://github.com/facebook/mysql-5.6/pull/1096 Reviewed By: lloyd Differential Revision: D19525150 Pulled By: hui80 --- mysql-test/include/show_slave_hosts.inc | 11 ++++- mysql-test/r/disabled_replication.result | 2 +- .../rpl/r/rpl_show_replica_auth_info.result | 24 +++++----- .../suite/rpl/r/rpl_show_slave_hosts.result | 18 +++++--- .../rpl/t/rpl_show_slave_hosts-master.opt | 1 + .../rpl/t/rpl_show_slave_hosts-slave.opt | 1 + .../suite/rpl/t/rpl_show_slave_hosts.cnf | 2 + .../suite/rpl/t/rpl_show_slave_hosts.test | 45 +++++++++++-------- .../rpl_nogtid/r/rpl_mixed_ddl_dml.result | 4 +- .../test_routing_sharing_constrained_pools.cc | 4 +- sql/rpl_binlog_sender.cc | 2 +- sql/rpl_source.cc | 38 ++++++++++++++-- sql/rpl_source.h | 2 +- 13 files changed, 109 insertions(+), 45 deletions(-) create mode 100644 mysql-test/suite/rpl/t/rpl_show_slave_hosts-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_show_slave_hosts-slave.opt diff --git a/mysql-test/include/show_slave_hosts.inc b/mysql-test/include/show_slave_hosts.inc index e27c1bfb09cc..5d48317f51c6 100644 --- a/mysql-test/include/show_slave_hosts.inc +++ b/mysql-test/include/show_slave_hosts.inc @@ -1,3 +1,12 @@ ---replace_result $SLAVE_MYPORT SLAVE_PORT $DEFAULT_MASTER_PORT DEFAULT_PORT +let $repl_status_semisync=`SELECT info FROM information_schema.processlist WHERE info like 'Semisync%' limit 1`; +if (!$repl_status_semisync) { + let $repl_status_semisync=CANNOTFIND; +} +let $repl_status_async=`SELECT info FROM information_schema.processlist WHERE info like 'Async%' limit 1`; +if (!$repl_status_async) { + let $repl_status_async=CANNOTFIND; +} + +--replace_result $SLAVE_MYPORT SLAVE_PORT $DEFAULT_MASTER_PORT DEFAULT_PORT $repl_status_semisync REPL_STATUS_SEMISYNC $repl_status_async REPL_STATUS_ASYNC --replace_regex /[0-9, a-f]{8}-[0-9, a-f]{4}-[0-9, a-f]{4}-[0-9, a-f]{4}-[0-9, a-f]{12}/SLAVE_UUID/ SHOW SLAVE HOSTS; diff --git a/mysql-test/r/disabled_replication.result b/mysql-test/r/disabled_replication.result index 0f05dcdb59e2..8a94fcdb5f6b 100644 --- a/mysql-test/r/disabled_replication.result +++ b/mysql-test/r/disabled_replication.result @@ -46,7 +46,7 @@ ERROR HY000: You are not using binary logging SHOW MASTER STATUS; File Position Binlog_Do_DB Binlog_Ignore_DB Executed_Gtid_Set SHOW SLAVE HOSTS; -Server_id Host Port Master_id Slave_UUID +Server_id Host Port Master_id Slave_UUID Is_semi_sync_slave Replication_status Warnings: Warning 1287 'SHOW SLAVE HOSTS' is deprecated and will be removed in a future release. Please use SHOW REPLICAS instead RESET MASTER; diff --git a/mysql-test/suite/rpl/r/rpl_show_replica_auth_info.result b/mysql-test/suite/rpl/r/rpl_show_replica_auth_info.result index 1e699b828f48..7a7c48ef9e67 100644 --- a/mysql-test/suite/rpl/r/rpl_show_replica_auth_info.result +++ b/mysql-test/suite/rpl/r/rpl_show_replica_auth_info.result @@ -19,11 +19,11 @@ include/start_slave.inc include/assert_error_log.inc [server: 1, pattern: NONE] * R2.1, R2.2: Have columns SHOW REPLICAS; -Server_Id Host User Password Port Source_Id Replica_UUID -2 127.0.0.1 USER PASS REPLICA_PORT 1 REPLICA_UUID +Server_Id Host User Password Port Source_Id Replica_UUID Is_semi_sync_slave Replication_status +2 127.0.0.1 USER PASS REPLICA_PORT 1 REPLICA_UUID 0 Async slave offset: master-bin.000002 157 SHOW SLAVE HOSTS; -Server_id Host User Password Port Master_id Slave_UUID -2 127.0.0.1 USER PASS REPLICA_PORT 1 REPLICA_UUID +Server_id Host User Password Port Master_id Slave_UUID Is_semi_sync_slave Replication_status +2 127.0.0.1 USER PASS REPLICA_PORT 1 REPLICA_UUID 0 Async slave offset: master-bin.000002 157 Warnings: Warning 1287 'SHOW SLAVE HOSTS' is deprecated and will be removed in a future release. Please use SHOW REPLICAS instead ==== R3: show-slave-auth-info ==== @@ -38,11 +38,11 @@ include/start_slave.inc include/assert_error_log.inc [server: 1, pattern: The syntax 'show-slave-auth-info' is deprecated and will be removed in a future release. Please use show-replica-auth-info instead.] * R3.2, R3.3: Have columns SHOW REPLICAS; -Server_Id Host User Password Port Source_Id Replica_UUID -2 127.0.0.1 USER PASS REPLICA_PORT 1 REPLICA_UUID +Server_Id Host User Password Port Source_Id Replica_UUID Is_semi_sync_slave Replication_status +2 127.0.0.1 USER PASS REPLICA_PORT 1 REPLICA_UUID 0 Async slave offset: master-bin.000003 157 SHOW SLAVE HOSTS; -Server_id Host User Password Port Master_id Slave_UUID -2 127.0.0.1 USER PASS REPLICA_PORT 1 REPLICA_UUID +Server_id Host User Password Port Master_id Slave_UUID Is_semi_sync_slave Replication_status +2 127.0.0.1 USER PASS REPLICA_PORT 1 REPLICA_UUID 0 Async slave offset: master-bin.000003 157 Warnings: Warning 1287 'SHOW SLAVE HOSTS' is deprecated and will be removed in a future release. Please use SHOW REPLICAS instead ==== R1: no command-line options ==== @@ -56,11 +56,11 @@ include/start_slave.inc include/assert_error_log.inc [server: 1, pattern: NONE] * R1.2, R1.3: No columns SHOW REPLICAS; -Server_Id Host Port Source_Id Replica_UUID -2 127.0.0.1 REPLICA_PORT 1 REPLICA_UUID +Server_Id Host Port Source_Id Replica_UUID Is_semi_sync_slave Replication_status +2 127.0.0.1 REPLICA_PORT 1 REPLICA_UUID 0 Async slave offset: master-bin.000004 157 SHOW SLAVE HOSTS; -Server_id Host Port Master_id Slave_UUID -2 127.0.0.1 REPLICA_PORT 1 REPLICA_UUID +Server_id Host Port Master_id Slave_UUID Is_semi_sync_slave Replication_status +2 127.0.0.1 REPLICA_PORT 1 REPLICA_UUID 0 Async slave offset: master-bin.000004 157 Warnings: Warning 1287 'SHOW SLAVE HOSTS' is deprecated and will be removed in a future release. Please use SHOW REPLICAS instead ==== Clean up ==== diff --git a/mysql-test/suite/rpl/r/rpl_show_slave_hosts.result b/mysql-test/suite/rpl/r/rpl_show_slave_hosts.result index fc33818ef59c..09a39bdaa752 100644 --- a/mysql-test/suite/rpl/r/rpl_show_slave_hosts.result +++ b/mysql-test/suite/rpl/r/rpl_show_slave_hosts.result @@ -3,6 +3,8 @@ Warnings: Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the connection metadata repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START REPLICA; see the 'START REPLICA Syntax' in the MySQL Manual for more information. [connection master] +call mtr.add_suppression("A message intended for a client cannot be sent there as no client-session is attached"); +[connection slave2] RESET SLAVE; Warnings: Warning 1287 'RESET SLAVE' is deprecated and will be removed in a future release. Please use RESET REPLICA instead @@ -14,18 +16,24 @@ START SLAVE IO_THREAD; Warnings: Warning 1287 'START SLAVE' is deprecated and will be removed in a future release. Please use START REPLICA instead include/wait_for_slave_io_to_start.inc +[connection master] +CREATE TABLE t1 (data LONGBLOB); +INSERT INTO t1 (data) VALUES (repeat('a',1024*1024)); +DROP TABLE t1; SHOW SLAVE HOSTS; -Server_id Host Port Master_id Slave_UUID -2 SLAVE_PORT 1 SLAVE_UUID -3 slave2 SLAVE_PORT 1 SLAVE_UUID +Server_id Host Port Master_id Slave_UUID Is_semi_sync_slave Replication_status +2 SLAVE_PORT 1 SLAVE_UUID 1 REPL_STATUS_SEMISYNC +3 slave2 SLAVE_PORT 1 SLAVE_UUID 0 REPL_STATUS_ASYNC Warning 1287 SLAVE_PORT Warnings: +[connection slave2] include/stop_slave_io.inc +[connection master] CREATE TABLE t1(a int); DROP TABLE t1; SHOW SLAVE HOSTS; -Server_id Host Port Master_id Slave_UUID -2 SLAVE_PORT 1 SLAVE_UUID +Server_id Host Port Master_id Slave_UUID Is_semi_sync_slave Replication_status +2 SLAVE_PORT 1 SLAVE_UUID 1 REPL_STATUS_SEMISYNC Warnings: Warning 1287 'SHOW SLAVE HOSTS' is deprecated and will be removed in a future release. Please use SHOW REPLICAS instead include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_show_slave_hosts-master.opt b/mysql-test/suite/rpl/t/rpl_show_slave_hosts-master.opt new file mode 100644 index 000000000000..8c9e13fe2c4a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_show_slave_hosts-master.opt @@ -0,0 +1 @@ +$SEMISYNC_MASTER_PLUGIN_OPT $SEMISYNC_MASTER_PLUGIN_LOAD diff --git a/mysql-test/suite/rpl/t/rpl_show_slave_hosts-slave.opt b/mysql-test/suite/rpl/t/rpl_show_slave_hosts-slave.opt new file mode 100644 index 000000000000..7585c48909a2 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_show_slave_hosts-slave.opt @@ -0,0 +1 @@ +$SEMISYNC_SLAVE_PLUGIN_OPT $SEMISYNC_SLAVE_PLUGIN_LOAD diff --git a/mysql-test/suite/rpl/t/rpl_show_slave_hosts.cnf b/mysql-test/suite/rpl/t/rpl_show_slave_hosts.cnf index 825e012ed134..5b8398fb0e2b 100644 --- a/mysql-test/suite/rpl/t/rpl_show_slave_hosts.cnf +++ b/mysql-test/suite/rpl/t/rpl_show_slave_hosts.cnf @@ -6,9 +6,11 @@ # instances when MTR runs rpl tests with parallel 4 or more. [mysqld.1] +rpl_semi_sync_master_enabled=1 server_id=1 [mysqld.2] +rpl_semi_sync_slave_enabled=1 server_id=2 report-host= report-user= diff --git a/mysql-test/suite/rpl/t/rpl_show_slave_hosts.test b/mysql-test/suite/rpl/t/rpl_show_slave_hosts.test index 8eeabe3601ee..39c92d14f036 100644 --- a/mysql-test/suite/rpl/t/rpl_show_slave_hosts.test +++ b/mysql-test/suite/rpl/t/rpl_show_slave_hosts.test @@ -10,10 +10,14 @@ # implemented. ####################################################################### --source include/not_group_replication_plugin.inc -source include/master-slave.inc; -connect (slave2,127.0.0.1,root,,test,$SLAVE_MYPORT2,); +--source include/have_debug_sync.inc +--source include/master-slave.inc -connection slave2; +call mtr.add_suppression("A message intended for a client cannot be sent there as no client-session is attached"); + +--connect (slave2,127.0.0.1,root,,test,$SLAVE_MYPORT2,) + +--source include/rpl_connection_slave2.inc RESET SLAVE; --replace_result $MASTER_MYPORT MASTER_PORT --replace_column 2 #### @@ -21,34 +25,39 @@ RESET SLAVE; START SLAVE IO_THREAD; source include/wait_for_slave_io_to_start.inc; -connection master; -let $show_statement= SHOW SLAVE HOSTS; -let $field= Server_id; +--source include/rpl_connection_master.inc + +CREATE TABLE t1 (data LONGBLOB); +INSERT INTO t1 (data) VALUES (repeat('a',1024*1024)); +DROP TABLE t1; + +--let $show_statement= SHOW SLAVE HOSTS +--let $field= Server_id # 3 is server_id of slave2. -let $condition= ='3'; -source include/wait_show_condition.inc; +--let $condition= ='3' +--source include/wait_show_condition.inc --replace_column 3 'SLAVE_PORT' ---replace_result $SLAVE_MYPORT SLAVE_PORT $DEFAULT_MASTER_PORT DEFAULT_PORT --sorted_result -source include/show_slave_hosts.inc; +--source include/show_slave_hosts.inc -connection slave2; +--source include/rpl_connection_slave2.inc --source include/stop_slave_io.inc -connection master; +--source include/rpl_connection_master.inc # Run dummy DDL to wake up dump thread and detect the disconnected slave CREATE TABLE t1(a int); DROP TABLE t1; -let $show_statement= SHOW SLAVE HOSTS; -let $field= Server_id; +--let $show_statement= SHOW SLAVE HOSTS +--let $field= Server_id # 3 is server_id of slave2. -let $condition= <> '3'; +--let $condition= <> '3' # All rows of 'SHOW SLAVE HOSTS' are not equal to 3. It mean that master has # knew the leave of slave2 and has unregistered it. -let $wait_for_all= 1; -source include/wait_show_condition.inc; -source include/show_slave_hosts.inc; +--let $wait_for_all= 1 +--source include/wait_show_condition.inc +--source include/show_slave_hosts.inc +--disconnect slave2 --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl_nogtid/r/rpl_mixed_ddl_dml.result b/mysql-test/suite/rpl_nogtid/r/rpl_mixed_ddl_dml.result index 5a902ee94a5e..69b7381e16ec 100644 --- a/mysql-test/suite/rpl_nogtid/r/rpl_mixed_ddl_dml.result +++ b/mysql-test/suite/rpl_nogtid/r/rpl_mixed_ddl_dml.result @@ -13,8 +13,8 @@ n 2001 2002 SHOW SLAVE HOSTS; -Server_id Host Port Master_id Slave_UUID -2 127.0.0.1 SLAVE_PORT 1 SLAVE_UUID +Server_id Host Port Master_id Slave_UUID Is_semi_sync_slave Replication_status +2 127.0.0.1 SLAVE_PORT 1 SLAVE_UUID 0 REPL_STATUS_ASYNC Warnings: Warning 1287 'SHOW SLAVE HOSTS' is deprecated and will be removed in a future release. Please use SHOW REPLICAS instead drop table t1; diff --git a/router/tests/integration/test_routing_sharing_constrained_pools.cc b/router/tests/integration/test_routing_sharing_constrained_pools.cc index a8fd5daae433..6a8a2b4b028d 100644 --- a/router/tests/integration/test_routing_sharing_constrained_pools.cc +++ b/router/tests/integration/test_routing_sharing_constrained_pools.cc @@ -1912,7 +1912,9 @@ WHERE t.thread_id = r.thread_id "some_funky_host", // host std::to_string(replica_server.server_port()), // port "1", // source-id - Not(IsEmpty()) // server-uuid + Not(IsEmpty()), // server-uuid + "0", + Not(IsEmpty()) // Async slave offset ))); } diff --git a/sql/rpl_binlog_sender.cc b/sql/rpl_binlog_sender.cc index fdf2638fe15d..6fa4075eacd5 100644 --- a/sql/rpl_binlog_sender.cc +++ b/sql/rpl_binlog_sender.cc @@ -401,7 +401,7 @@ void Binlog_sender::cleanup() { my_eof(thd); } -static bool is_semi_sync_slave() { +bool is_semi_sync_slave() { long long val = 0; get_user_var_int("rpl_semi_sync_slave", &val, nullptr); return val; diff --git a/sql/rpl_source.cc b/sql/rpl_source.cc index 4d915d0b0aed..4c4cf4f3802c 100644 --- a/sql/rpl_source.cc +++ b/sql/rpl_source.cc @@ -194,7 +194,7 @@ int register_replica(THD *thd, uchar *packet, size_t packet_length) { */ p += 4; if (!(si->master_id = uint4korr(p))) si->master_id = server_id; - si->thd_id = thd->thread_id(); + si->thd = thd; si->valid_replica_uuid = false; if (get_replica_uuid(thd, &replica_uuid)) { si->valid_replica_uuid = @@ -220,14 +220,34 @@ void unregister_replica(THD *thd, bool only_mine, bool need_lock_slave_list) { mysql_mutex_assert_owner(&LOCK_replica_list); auto it = slave_list.find(thd->server_id); - if (it != slave_list.end() && - (!only_mine || it->second->thd_id == thd->thread_id())) + if (it != slave_list.end() && (!only_mine || it->second->thd == thd)) slave_list.erase(it); if (need_lock_slave_list) mysql_mutex_unlock(&LOCK_replica_list); } } +bool is_semi_sync_slave(THD *thd, bool need_lock) { + constexpr auto name = "rpl_semi_sync_slave"; + + if (need_lock) + mysql_mutex_lock(&thd->LOCK_thd_data); + else + mysql_mutex_assert_owner(&thd->LOCK_thd_data); + + longlong integral_result = 0; + const auto it = thd->user_vars.find(name); + + if (it != thd->user_vars.end()) { + auto null_value = false; + auto tmp = it->second->val_int(&null_value); + if (!null_value) integral_result = tmp; + } + + if (need_lock) mysql_mutex_unlock(&thd->LOCK_thd_data); + return integral_result != 0; +} + /** Execute a SHOW REPLICAS / SHOW SLAVE HOSTS statement. @@ -251,6 +271,9 @@ bool show_replicas(THD *thd) { field_list.push_back(new Item_return_int("Port", 7, MYSQL_TYPE_LONG)); field_list.push_back(new Item_return_int("Source_Id", 10, MYSQL_TYPE_LONG)); field_list.push_back(new Item_empty_string("Replica_UUID", UUID_LENGTH)); + field_list.push_back( + new Item_return_int("Is_semi_sync_slave", 7, MYSQL_TYPE_LONG)); + field_list.push_back(new Item_empty_string("Replication_status", 20)); // TODO: once the old syntax is removed, remove this as well. if (thd->lex->is_replication_deprecated_syntax_used()) @@ -281,6 +304,15 @@ bool show_replicas(THD *thd) { } else { protocol->store("", &my_charset_bin); } + protocol->store(is_semi_sync_slave(si->thd, /*need_lock*/ true)); + + mysql_mutex_lock(&si->thd->LOCK_thd_query); + LEX_CSTRING replication_status = si->thd->query(); + if (replication_status.length) + protocol->store(replication_status.str, &my_charset_bin); + else + protocol->store("", &my_charset_bin); + mysql_mutex_unlock(&si->thd->LOCK_thd_query); if (protocol->end_row()) { mysql_mutex_unlock(&LOCK_replica_list); diff --git a/sql/rpl_source.h b/sql/rpl_source.h index 81363c458c85..0102d116c8d5 100644 --- a/sql/rpl_source.h +++ b/sql/rpl_source.h @@ -55,7 +55,7 @@ struct REPLICA_INFO { char user[USERNAME_LENGTH + 1]; char password[MAX_PASSWORD_LENGTH + 1]; uint16 port; - my_thread_id thd_id; + THD *thd; binary_log::Uuid replica_uuid; bool valid_replica_uuid; };