[PATCH] MDEV-33856 New definition for Seconds_Behind_Master
From: Monty <monty@mariadb.org> This commit adds 3 new status variables to 'show all slaves status': - Master_last_event_time ; timestamp of the last event read from the master by the IO thread. - Slave_last_event_time ; Master timestamp of the last event committed on the slave. - Master_Slave_time_diff: The difference of the above two timestamps. All the above variables are NULL until the slave has started and the slave has read one query event from the master that changes data. - Added information_schema.slave_status, which allows us to remove: - show_master_info(), show_master_info_get_fields(), send_show_master_info_data(), show_all_master_info() - class Sql_cmd_show_slave_status. - Protocol::store(I_List<i_string_pair>* str_list) as it is not used anymore. - Changed old SHOW SLAVE STATUS and SHOW ALL SLAVES STATUS to use the SELECT code path, as all other SHOW ... STATUS commands. Other things: - Xid_log_time is set to time of commit to allow slave that reads the binary log to calculate Master_last_event_time and Slave_last_event_time. This is needed as there is not 'exec_time' for row events. - Fixed that Load_log_event calculates exec_time identically to Query_event. - Updated RESET SLAVE to reset Master/Slave_last_event_time - Updated SQL thread's update on first transaction read-in to only update Slave_last_event_time on group events. - Fixed possible (unlikely) bugs in sql_show.cc ...old_format() functions if allocation of 'field' would fail. --- mysql-test/include/show_slave_status.inc | 2 +- mysql-test/main/grant_slave_monitor.result | 2 + mysql-test/main/grant_slave_monitor.test | 2 + mysql-test/main/information_schema-big.result | 2 + mysql-test/main/information_schema-big.test | 1 + .../information_schema-big_embedded.result | 133 +++ .../main/information_schema-big_embedded.test | 43 + mysql-test/main/information_schema.result | 7 +- .../information_schema_all_engines.result | 12 +- mysql-test/main/ps_change_master.test | 4 +- .../suite/funcs_1/r/is_columns_is.result | 131 +++ .../suite/funcs_1/r/is_tables_is.result | 50 + .../suite/multi_source/info_logs.result | 12 +- .../multi_source_slave_alias_replica.result | 6 + mysql-test/suite/multi_source/simple.result | 18 + mysql-test/suite/multi_source/syntax.result | 2 +- mysql-test/suite/perfschema/r/relaylog.result | 4 +- mysql-test/suite/perfschema/t/relaylog.test | 4 +- .../rpl/r/master_last_event_time_row.result | 203 ++++ .../rpl/r/master_last_event_time_stmt.result | 71 ++ .../suite/rpl/r/rpl_parallel_sbm.result | 8 + .../suite/rpl/t/master_last_event_time.inc | 58 ++ .../rpl/t/master_last_event_time_row.cnf | 16 + .../rpl/t/master_last_event_time_row.test | 168 ++++ .../rpl/t/master_last_event_time_stmt.cnf | 15 + .../rpl/t/master_last_event_time_stmt.test | 84 ++ mysql-test/suite/rpl/t/rpl_parallel_sbm.test | 42 + sql/handler.h | 3 + sql/item.h | 15 +- sql/log.cc | 18 +- sql/log_event.cc | 37 +- sql/log_event.h | 15 +- sql/log_event_server.cc | 21 +- sql/protocol.cc | 27 - sql/protocol.h | 2 +- sql/rpl_mi.cc | 53 +- sql/rpl_mi.h | 5 +- sql/rpl_parallel.cc | 3 + sql/rpl_rli.cc | 9 +- sql/rpl_rli.h | 16 +- sql/slave.cc | 874 ++++++------------ sql/slave.h | 4 +- sql/sql_class.h | 1 + sql/sql_cmd.h | 20 - sql/sql_lex.h | 2 + sql/sql_parse.cc | 2 +- sql/sql_prepare.cc | 40 +- sql/sql_repl.cc | 2 + sql/sql_show.cc | 245 ++++- sql/sql_type.cc | 20 +- sql/sql_yacc.yy | 14 +- sql/table.h | 13 +- 52 files changed, 1784 insertions(+), 777 deletions(-) create mode 100644 mysql-test/main/information_schema-big_embedded.result create mode 100644 mysql-test/main/information_schema-big_embedded.test create mode 100644 mysql-test/suite/rpl/r/master_last_event_time_row.result create mode 100644 mysql-test/suite/rpl/r/master_last_event_time_stmt.result create mode 100644 mysql-test/suite/rpl/t/master_last_event_time.inc create mode 100644 mysql-test/suite/rpl/t/master_last_event_time_row.cnf create mode 100644 mysql-test/suite/rpl/t/master_last_event_time_row.test create mode 100644 mysql-test/suite/rpl/t/master_last_event_time_stmt.cnf create mode 100644 mysql-test/suite/rpl/t/master_last_event_time_stmt.test diff --git a/mysql-test/include/show_slave_status.inc b/mysql-test/include/show_slave_status.inc index 429ed8a5abd..c91e76f1ec5 100644 --- a/mysql-test/include/show_slave_status.inc +++ b/mysql-test/include/show_slave_status.inc @@ -97,7 +97,7 @@ if ($all_slaves_status) { --die Bug in test case: Both $all_slaves_status and $slave_name are set. } - --let $_show_query=SHOW ALL SLAVES STATUS + --let $_show_query=SELECT * from information_schema.slave_status } if ($slave_name) { diff --git a/mysql-test/main/grant_slave_monitor.result b/mysql-test/main/grant_slave_monitor.result index 61c4ca308cc..75fb07fe317 100644 --- a/mysql-test/main/grant_slave_monitor.result +++ b/mysql-test/main/grant_slave_monitor.result @@ -13,6 +13,8 @@ GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, F # SHOW SLAVE STATUS; ERROR 42000: Access denied; you need (at least one of) the SLAVE MONITOR privilege(s) for this operation +SELECT * from information_schema.slave_status; +ERROR 42000: Access denied; you need (at least one of) the SLAVE MONITOR privilege(s) for this operation # # Verify that having REPLICATION SLAVE ADMIN doesn't allow SHOW RELAYLOG EVENTS # Expected error: Access denied; you need (at least one of) the REPLICA MONITOR diff --git a/mysql-test/main/grant_slave_monitor.test b/mysql-test/main/grant_slave_monitor.test index b5e65ef2cb4..1be9b7e944d 100644 --- a/mysql-test/main/grant_slave_monitor.test +++ b/mysql-test/main/grant_slave_monitor.test @@ -38,6 +38,8 @@ SHOW GRANTS; --echo # --error ER_SPECIFIC_ACCESS_DENIED_ERROR SHOW SLAVE STATUS; +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +SELECT * from information_schema.slave_status; --echo # --echo # Verify that having REPLICATION SLAVE ADMIN doesn't allow SHOW RELAYLOG EVENTS diff --git a/mysql-test/main/information_schema-big.result b/mysql-test/main/information_schema-big.result index 8c93cc79f64..cad4078deb5 100644 --- a/mysql-test/main/information_schema-big.result +++ b/mysql-test/main/information_schema-big.result @@ -52,6 +52,7 @@ SCHEMA_PRIVILEGES TABLE_SCHEMA SEQUENCES SEQUENCE_SCHEMA SESSION_STATUS VARIABLE_NAME SESSION_VARIABLES VARIABLE_NAME +SLAVE_STATUS Connection_name SPATIAL_REF_SYS SRID SQL_FUNCTIONS FUNCTION STATISTICS TABLE_SCHEMA @@ -117,6 +118,7 @@ SCHEMA_PRIVILEGES TABLE_SCHEMA SEQUENCES SEQUENCE_SCHEMA SESSION_STATUS VARIABLE_NAME SESSION_VARIABLES VARIABLE_NAME +SLAVE_STATUS Connection_name SPATIAL_REF_SYS SRID SQL_FUNCTIONS FUNCTION STATISTICS TABLE_SCHEMA diff --git a/mysql-test/main/information_schema-big.test b/mysql-test/main/information_schema-big.test index 89d7d877fb2..8baaaab6e0c 100644 --- a/mysql-test/main/information_schema-big.test +++ b/mysql-test/main/information_schema-big.test @@ -1,4 +1,5 @@ -- source include/have_innodb.inc +-- source include/not_embedded.inc # check that CSV engine was compiled in, as the result of the test depends # on the presence of the log tables (which are CSV-based). diff --git a/mysql-test/main/information_schema-big_embedded.result b/mysql-test/main/information_schema-big_embedded.result new file mode 100644 index 00000000000..8c93cc79f64 --- /dev/null +++ b/mysql-test/main/information_schema-big_embedded.result @@ -0,0 +1,133 @@ +# +# Bug#18925: subqueries with MIN/MAX functions on INFORMATION_SCHEMA +# +SELECT t.table_name, c1.column_name +FROM information_schema.tables t +INNER JOIN +information_schema.columns c1 +ON t.table_schema = c1.table_schema AND +t.table_name = c1.table_name +WHERE t.table_schema = 'information_schema' AND +c1.ordinal_position = +( SELECT COALESCE(MIN(c2.ordinal_position),1) +FROM information_schema.columns c2 +WHERE c2.table_schema = t.table_schema AND +c2.table_name = t.table_name AND +c2.column_name LIKE '%SCHEMA%' + ) +AND t.table_name NOT LIKE 'innodb%' and t.table_name NOT LIKE "OPTIMIZER_TRACE%"; +table_name column_name +ALL_PLUGINS PLUGIN_NAME +APPLICABLE_ROLES GRANTEE +CHARACTER_SETS CHARACTER_SET_NAME +CHECK_CONSTRAINTS CONSTRAINT_SCHEMA +CLIENT_STATISTICS CLIENT +COLLATIONS COLLATION_NAME +COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME +COLUMNS TABLE_SCHEMA +COLUMN_PRIVILEGES TABLE_SCHEMA +ENABLED_ROLES ROLE_NAME +ENGINES ENGINE +EVENTS EVENT_SCHEMA +FILES TABLE_SCHEMA +GEOMETRY_COLUMNS F_TABLE_SCHEMA +GLOBAL_STATUS VARIABLE_NAME +GLOBAL_VARIABLES VARIABLE_NAME +INDEX_STATISTICS TABLE_SCHEMA +KEYWORDS WORD +KEY_CACHES KEY_CACHE_NAME +KEY_COLUMN_USAGE CONSTRAINT_SCHEMA +KEY_PERIOD_USAGE CONSTRAINT_SCHEMA +OPTIMIZER_COSTS ENGINE +PARAMETERS SPECIFIC_SCHEMA +PARTITIONS TABLE_SCHEMA +PERIODS TABLE_SCHEMA +PLUGINS PLUGIN_NAME +PROCESSLIST ID +PROFILING QUERY_ID +REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA +ROUTINES ROUTINE_SCHEMA +SCHEMATA SCHEMA_NAME +SCHEMA_PRIVILEGES TABLE_SCHEMA +SEQUENCES SEQUENCE_SCHEMA +SESSION_STATUS VARIABLE_NAME +SESSION_VARIABLES VARIABLE_NAME +SPATIAL_REF_SYS SRID +SQL_FUNCTIONS FUNCTION +STATISTICS TABLE_SCHEMA +SYSTEM_VARIABLES VARIABLE_NAME +TABLES TABLE_SCHEMA +TABLESPACES TABLESPACE_NAME +TABLE_CONSTRAINTS CONSTRAINT_SCHEMA +TABLE_PRIVILEGES TABLE_SCHEMA +TABLE_STATISTICS TABLE_SCHEMA +TRIGGERS TRIGGER_SCHEMA +USERS USER +USER_PRIVILEGES GRANTEE +USER_STATISTICS USER +VIEWS TABLE_SCHEMA +SELECT t.table_name, c1.column_name +FROM information_schema.tables t +INNER JOIN +information_schema.columns c1 +ON t.table_schema = c1.table_schema AND +t.table_name = c1.table_name +WHERE t.table_schema = 'information_schema' AND +c1.ordinal_position = +( SELECT COALESCE(MIN(c2.ordinal_position),1) +FROM information_schema.columns c2 +WHERE c2.table_schema = 'information_schema' AND +c2.table_name = t.table_name AND +c2.column_name LIKE '%SCHEMA%' + ) +AND t.table_name NOT LIKE 'innodb%' and t.table_name NOT LIKE "OPTIMIZER_TRACE%"; +table_name column_name +ALL_PLUGINS PLUGIN_NAME +APPLICABLE_ROLES GRANTEE +CHARACTER_SETS CHARACTER_SET_NAME +CHECK_CONSTRAINTS CONSTRAINT_SCHEMA +CLIENT_STATISTICS CLIENT +COLLATIONS COLLATION_NAME +COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME +COLUMNS TABLE_SCHEMA +COLUMN_PRIVILEGES TABLE_SCHEMA +ENABLED_ROLES ROLE_NAME +ENGINES ENGINE +EVENTS EVENT_SCHEMA +FILES TABLE_SCHEMA +GEOMETRY_COLUMNS F_TABLE_SCHEMA +GLOBAL_STATUS VARIABLE_NAME +GLOBAL_VARIABLES VARIABLE_NAME +INDEX_STATISTICS TABLE_SCHEMA +KEYWORDS WORD +KEY_CACHES KEY_CACHE_NAME +KEY_COLUMN_USAGE CONSTRAINT_SCHEMA +KEY_PERIOD_USAGE CONSTRAINT_SCHEMA +OPTIMIZER_COSTS ENGINE +PARAMETERS SPECIFIC_SCHEMA +PARTITIONS TABLE_SCHEMA +PERIODS TABLE_SCHEMA +PLUGINS PLUGIN_NAME +PROCESSLIST ID +PROFILING QUERY_ID +REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA +ROUTINES ROUTINE_SCHEMA +SCHEMATA SCHEMA_NAME +SCHEMA_PRIVILEGES TABLE_SCHEMA +SEQUENCES SEQUENCE_SCHEMA +SESSION_STATUS VARIABLE_NAME +SESSION_VARIABLES VARIABLE_NAME +SPATIAL_REF_SYS SRID +SQL_FUNCTIONS FUNCTION +STATISTICS TABLE_SCHEMA +SYSTEM_VARIABLES VARIABLE_NAME +TABLES TABLE_SCHEMA +TABLESPACES TABLESPACE_NAME +TABLE_CONSTRAINTS CONSTRAINT_SCHEMA +TABLE_PRIVILEGES TABLE_SCHEMA +TABLE_STATISTICS TABLE_SCHEMA +TRIGGERS TRIGGER_SCHEMA +USERS USER +USER_PRIVILEGES GRANTEE +USER_STATISTICS USER +VIEWS TABLE_SCHEMA diff --git a/mysql-test/main/information_schema-big_embedded.test b/mysql-test/main/information_schema-big_embedded.test new file mode 100644 index 00000000000..0817a6e2be7 --- /dev/null +++ b/mysql-test/main/information_schema-big_embedded.test @@ -0,0 +1,43 @@ +-- source include/have_innodb.inc +-- source include/is_embedded.inc + +# check that CSV engine was compiled in, as the result of the test depends +# on the presence of the log tables (which are CSV-based). +--source include/have_csv.inc + +--echo # +--echo # Bug#18925: subqueries with MIN/MAX functions on INFORMATION_SCHEMA +--echo # + +--sorted_result +SELECT t.table_name, c1.column_name + FROM information_schema.tables t + INNER JOIN + information_schema.columns c1 + ON t.table_schema = c1.table_schema AND + t.table_name = c1.table_name + WHERE t.table_schema = 'information_schema' AND + c1.ordinal_position = + ( SELECT COALESCE(MIN(c2.ordinal_position),1) + FROM information_schema.columns c2 + WHERE c2.table_schema = t.table_schema AND + c2.table_name = t.table_name AND + c2.column_name LIKE '%SCHEMA%' + ) + AND t.table_name NOT LIKE 'innodb%' and t.table_name NOT LIKE "OPTIMIZER_TRACE%"; +--sorted_result +SELECT t.table_name, c1.column_name + FROM information_schema.tables t + INNER JOIN + information_schema.columns c1 + ON t.table_schema = c1.table_schema AND + t.table_name = c1.table_name + WHERE t.table_schema = 'information_schema' AND + c1.ordinal_position = + ( SELECT COALESCE(MIN(c2.ordinal_position),1) + FROM information_schema.columns c2 + WHERE c2.table_schema = 'information_schema' AND + c2.table_name = t.table_name AND + c2.column_name LIKE '%SCHEMA%' + ) + AND t.table_name NOT LIKE 'innodb%' and t.table_name NOT LIKE "OPTIMIZER_TRACE%"; diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result index e0bee79ee3c..7c939064410 100644 --- a/mysql-test/main/information_schema.result +++ b/mysql-test/main/information_schema.result @@ -87,6 +87,7 @@ SCHEMA_PRIVILEGES SEQUENCES SESSION_STATUS SESSION_VARIABLES +SLAVE_STATUS SPATIAL_REF_SYS SQL_FUNCTIONS STATISTICS @@ -960,6 +961,8 @@ PARTITIONS UPDATE_TIME datetime PARTITIONS CHECK_TIME datetime ROUTINES CREATED datetime ROUTINES LAST_ALTERED datetime +SLAVE_STATUS Master_last_event_time datetime +SLAVE_STATUS Slave_last_event_time datetime TABLES CREATE_TIME datetime TABLES UPDATE_TIME datetime TABLES CHECK_TIME datetime @@ -1336,8 +1339,8 @@ table_schema='information_schema' and or column_type = 'varchar(27)') group by column_type order by num; column_type group_concat(table_schema, '.', table_name) num -varchar(7) information_schema.ROUTINES,information_schema.VIEWS 2 -varchar(20) information_schema.ALL_PLUGINS,information_schema.ALL_PLUGINS,information_schema.ALL_PLUGINS,information_schema.FILES,information_schema.FILES,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PROFILING 9 +varchar(7) information_schema.ROUTINES,information_schema.VIEWS,information_schema.SLAVE_STATUS 3 +varchar(20) information_schema.ALL_PLUGINS,information_schema.ALL_PLUGINS,information_schema.ALL_PLUGINS,information_schema.FILES,information_schema.FILES,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PROFILING,information_schema.SLAVE_STATUS 10 create table t1(f1 char(1) not null, f2 char(9) not null) default character set utf8; select CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH from diff --git a/mysql-test/main/information_schema_all_engines.result b/mysql-test/main/information_schema_all_engines.result index b413c63b59d..745d03234e8 100644 --- a/mysql-test/main/information_schema_all_engines.result +++ b/mysql-test/main/information_schema_all_engines.result @@ -58,6 +58,7 @@ SCHEMA_PRIVILEGES SEQUENCES SESSION_STATUS SESSION_VARIABLES +SLAVE_STATUS SPATIAL_REF_SYS SQL_FUNCTIONS STATISTICS @@ -144,6 +145,7 @@ SCHEMA_PRIVILEGES TABLE_SCHEMA SEQUENCES SEQUENCE_SCHEMA SESSION_STATUS VARIABLE_NAME SESSION_VARIABLES VARIABLE_NAME +SLAVE_STATUS Connection_name SPATIAL_REF_SYS SRID SQL_FUNCTIONS FUNCTION STATISTICS TABLE_SCHEMA @@ -230,6 +232,7 @@ SCHEMA_PRIVILEGES TABLE_SCHEMA SEQUENCES SEQUENCE_SCHEMA SESSION_STATUS VARIABLE_NAME SESSION_VARIABLES VARIABLE_NAME +SLAVE_STATUS Connection_name SPATIAL_REF_SYS SRID SQL_FUNCTIONS FUNCTION STATISTICS TABLE_SCHEMA @@ -278,8 +281,6 @@ ENGINES information_schema.ENGINES 1 EVENTS information_schema.EVENTS 1 FILES information_schema.FILES 1 GEOMETRY_COLUMNS information_schema.GEOMETRY_COLUMNS 1 -GLOBAL_STATUS information_schema.GLOBAL_STATUS 1 -GLOBAL_VARIABLES information_schema.GLOBAL_VARIABLES 1 INDEX_STATISTICS information_schema.INDEX_STATISTICS 1 INNODB_BUFFER_PAGE information_schema.INNODB_BUFFER_PAGE 1 INNODB_BUFFER_PAGE_LRU information_schema.INNODB_BUFFER_PAGE_LRU 1 @@ -318,8 +319,7 @@ ROUTINES information_schema.ROUTINES 1 SCHEMATA information_schema.SCHEMATA 1 SCHEMA_PRIVILEGES information_schema.SCHEMA_PRIVILEGES 1 SEQUENCES information_schema.SEQUENCES 1 -SESSION_STATUS information_schema.SESSION_STATUS 1 -SESSION_VARIABLES information_schema.SESSION_VARIABLES 1 +SLAVE_STATUS information_schema.SLAVE_STATUS 1 SPATIAL_REF_SYS information_schema.SPATIAL_REF_SYS 1 STATISTICS information_schema.STATISTICS 1 SYSTEM_VARIABLES information_schema.SYSTEM_VARIABLES 1 @@ -395,6 +395,7 @@ Database: information_schema | SEQUENCES | | SESSION_STATUS | | SESSION_VARIABLES | +| SLAVE_STATUS | | SPATIAL_REF_SYS | | SQL_FUNCTIONS | | STATISTICS | @@ -471,6 +472,7 @@ Database: INFORMATION_SCHEMA | SEQUENCES | | SESSION_STATUS | | SESSION_VARIABLES | +| SLAVE_STATUS | | SPATIAL_REF_SYS | | SQL_FUNCTIONS | | STATISTICS | @@ -493,5 +495,5 @@ Wildcard: inf_rmation_schema | information_schema | SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') GROUP BY TABLE_SCHEMA; table_schema count(*) -information_schema 71 +information_schema 72 mysql 31 diff --git a/mysql-test/main/ps_change_master.test b/mysql-test/main/ps_change_master.test index 19040917bde..677ad46a787 100644 --- a/mysql-test/main/ps_change_master.test +++ b/mysql-test/main/ps_change_master.test @@ -32,8 +32,8 @@ EXECUTE stmt; EXECUTE stmt; DEALLOCATE PREPARE stmt; -let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); -let $master_user= query_get_value(SHOW SLAVE STATUS, Master_User, 1); +let $master_host= `select Master_Host from information_schema.slave_status`; +let $master_user= `select Master_user from information_schema.slave_status`; --echo # Master_Host : $master_host --echo # Master_User : $master_user diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index 287ea2d905a..85a02d6a6ef 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -388,6 +388,71 @@ def information_schema SESSION_STATUS VARIABLE_NAME 1 NULL NO varchar 64 192 NUL def information_schema SESSION_STATUS VARIABLE_VALUE 2 NULL NO varchar 4096 12288 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(4096) select NEVER NULL NO NO def information_schema SESSION_VARIABLES VARIABLE_NAME 1 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO def information_schema SESSION_VARIABLES VARIABLE_VALUE 2 NULL NO varchar 4096 12288 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(4096) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Connection_name 1 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Connect_Retry 7 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Executed_log_entries 59 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Exec_Master_Log_Pos 24 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Gtid_IO_Pos 46 NULL NO varchar 1024 3072 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(1024) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Gtid_Slave_Pos 62 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Last_Errno 21 NULL NO int NULL NULL 10 0 NULL NULL NULL int(4) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Last_Error 22 NULL YES varchar 20 60 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(20) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Last_IO_Errno 37 NULL NO int NULL NULL 10 0 NULL NULL NULL int(4) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Last_IO_Error 38 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Last_SQL_Errno 39 NULL NO int NULL NULL 10 0 NULL NULL NULL int(4) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Last_SQL_Error 40 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_Host 4 NULL YES varchar 255 765 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(255) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_last_event_time 63 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_Log_File 8 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_Port 6 NULL NO int NULL NULL 10 0 NULL NULL NULL int(7) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_Server_Id 42 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_Slave_time_diff 65 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(10) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_SSL_Allowed 29 NULL YES varchar 7 21 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(7) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_SSL_CA_File 30 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_SSL_CA_Path 31 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_SSL_Cert 32 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_SSL_Cipher 33 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_SSL_Crl 43 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_SSL_Crlpath 44 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_SSL_Key 34 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_SSL_Verify_Server_Cert 36 NULL NO varchar 3 9 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(3) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Master_User 5 NULL YES varchar 384 1152 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(384) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Max_relay_log_size 58 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Parallel_Mode 49 NULL NO varchar 15 45 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(15) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Read_Master_Log_Pos 9 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Relay_Log_File 10 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Relay_Log_Pos 11 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Relay_Log_Space 25 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Relay_Master_Log_File 12 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Do_DB 15 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Do_Domain_Ids 47 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Do_Table 17 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Ignore_DB 16 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Ignore_Domain_Ids 48 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Ignore_Server_Ids 41 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Ignore_Table 18 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Rewrite_DB 56 NULL NO varchar 1024 3072 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(1024) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Wild_Do_Table 19 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Replicate_Wild_Ignore_Table 20 NULL NO varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Retried_transactions 57 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Seconds_Behind_Master 35 NULL YES bigint NULL NULL 19 0 NULL NULL NULL bigint(10) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Skip_Counter 23 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Slave_DDL_Groups 53 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Slave_heartbeat_period 61 NULL NO float NULL NULL 9 3 NULL NULL NULL float(9,3) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Slave_IO_Running 13 NULL NO varchar 10 30 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(10) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Slave_IO_State 3 NULL YES varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Slave_last_event_time 64 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select NEVER NULL NO NO +def information_schema SLAVE_STATUS Slave_Non_Transactional_Groups 54 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Slave_received_heartbeats 60 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Slave_SQL_Running 14 NULL NO varchar 3 9 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(3) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Slave_SQL_Running_State 52 NULL YES varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Slave_SQL_State 2 NULL YES varchar 64 192 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(64) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Slave_Transactional_Groups 55 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(20) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS SQL_Delay 50 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS SQL_Remaining_Delay 51 NULL YES int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Until_Condition 26 NULL NO varchar 6 18 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(6) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Until_Log_File 27 NULL YES varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO +def information_schema SLAVE_STATUS Until_Log_Pos 28 NULL NO bigint NULL NULL 20 0 NULL NULL NULL bigint(10) unsigned select NEVER NULL NO NO +def information_schema SLAVE_STATUS Using_Gtid 45 NULL YES varchar 15 45 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(15) select NEVER NULL NO NO def information_schema SPATIAL_REF_SYS AUTH_NAME 2 NULL NO varchar 512 1536 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(512) select NEVER NULL NO NO def information_schema SPATIAL_REF_SYS AUTH_SRID 3 NULL NO int NULL NULL 10 0 NULL NULL NULL int(5) select NEVER NULL NO NO def information_schema SPATIAL_REF_SYS SRID 1 NULL NO smallint NULL NULL 5 0 NULL NULL NULL smallint(5) select NEVER NULL NO NO @@ -589,6 +654,7 @@ NULL bigint NULL NULL NULL datetime NULL NULL NULL decimal NULL NULL NULL double NULL NULL +NULL float NULL NULL NULL int NULL NULL NULL smallint NULL NULL NULL tinyint NULL NULL @@ -994,6 +1060,71 @@ NULL information_schema SEQUENCES INCREMENT bigint NULL NULL NULL NULL bigint(21 3.0000 information_schema SESSION_STATUS VARIABLE_VALUE varchar 4096 12288 utf8mb3 utf8mb3_general_ci varchar(4096) 3.0000 information_schema SESSION_VARIABLES VARIABLE_NAME varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) 3.0000 information_schema SESSION_VARIABLES VARIABLE_VALUE varchar 4096 12288 utf8mb3 utf8mb3_general_ci varchar(4096) +3.0000 information_schema SLAVE_STATUS Connection_name varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) +3.0000 information_schema SLAVE_STATUS Slave_SQL_State varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) +3.0000 information_schema SLAVE_STATUS Slave_IO_State varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) +3.0000 information_schema SLAVE_STATUS Master_Host varchar 255 765 utf8mb3 utf8mb3_general_ci varchar(255) +3.0000 information_schema SLAVE_STATUS Master_User varchar 384 1152 utf8mb3 utf8mb3_general_ci varchar(384) +NULL information_schema SLAVE_STATUS Master_Port int NULL NULL NULL NULL int(7) unsigned +NULL information_schema SLAVE_STATUS Connect_Retry int NULL NULL NULL NULL int(10) +3.0000 information_schema SLAVE_STATUS Master_Log_File varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +NULL information_schema SLAVE_STATUS Read_Master_Log_Pos bigint NULL NULL NULL NULL bigint(10) unsigned +3.0000 information_schema SLAVE_STATUS Relay_Log_File varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +NULL information_schema SLAVE_STATUS Relay_Log_Pos bigint NULL NULL NULL NULL bigint(10) unsigned +3.0000 information_schema SLAVE_STATUS Relay_Master_Log_File varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +3.0000 information_schema SLAVE_STATUS Slave_IO_Running varchar 10 30 utf8mb3 utf8mb3_general_ci varchar(10) +3.0000 information_schema SLAVE_STATUS Slave_SQL_Running varchar 3 9 utf8mb3 utf8mb3_general_ci varchar(3) +3.0000 information_schema SLAVE_STATUS Replicate_Do_DB varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) +3.0000 information_schema SLAVE_STATUS Replicate_Ignore_DB varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) +3.0000 information_schema SLAVE_STATUS Replicate_Do_Table varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) +3.0000 information_schema SLAVE_STATUS Replicate_Ignore_Table varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) +3.0000 information_schema SLAVE_STATUS Replicate_Wild_Do_Table varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) +3.0000 information_schema SLAVE_STATUS Replicate_Wild_Ignore_Table varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) +NULL information_schema SLAVE_STATUS Last_Errno int NULL NULL NULL NULL int(4) +3.0000 information_schema SLAVE_STATUS Last_Error varchar 20 60 utf8mb3 utf8mb3_general_ci varchar(20) +NULL information_schema SLAVE_STATUS Skip_Counter int NULL NULL NULL NULL int(10) unsigned +NULL information_schema SLAVE_STATUS Exec_Master_Log_Pos bigint NULL NULL NULL NULL bigint(10) unsigned +NULL information_schema SLAVE_STATUS Relay_Log_Space bigint NULL NULL NULL NULL bigint(10) unsigned +3.0000 information_schema SLAVE_STATUS Until_Condition varchar 6 18 utf8mb3 utf8mb3_general_ci varchar(6) +3.0000 information_schema SLAVE_STATUS Until_Log_File varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +NULL information_schema SLAVE_STATUS Until_Log_Pos bigint NULL NULL NULL NULL bigint(10) unsigned +3.0000 information_schema SLAVE_STATUS Master_SSL_Allowed varchar 7 21 utf8mb3 utf8mb3_general_ci varchar(7) +3.0000 information_schema SLAVE_STATUS Master_SSL_CA_File varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +3.0000 information_schema SLAVE_STATUS Master_SSL_CA_Path varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +3.0000 information_schema SLAVE_STATUS Master_SSL_Cert varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +3.0000 information_schema SLAVE_STATUS Master_SSL_Cipher varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +3.0000 information_schema SLAVE_STATUS Master_SSL_Key varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +NULL information_schema SLAVE_STATUS Seconds_Behind_Master bigint NULL NULL NULL NULL bigint(10) +3.0000 information_schema SLAVE_STATUS Master_SSL_Verify_Server_Cert varchar 3 9 utf8mb3 utf8mb3_general_ci varchar(3) +NULL information_schema SLAVE_STATUS Last_IO_Errno int NULL NULL NULL NULL int(4) +3.0000 information_schema SLAVE_STATUS Last_IO_Error varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +NULL information_schema SLAVE_STATUS Last_SQL_Errno int NULL NULL NULL NULL int(4) +3.0000 information_schema SLAVE_STATUS Last_SQL_Error varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +3.0000 information_schema SLAVE_STATUS Replicate_Ignore_Server_Ids varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +NULL information_schema SLAVE_STATUS Master_Server_Id int NULL NULL NULL NULL int(10) unsigned +3.0000 information_schema SLAVE_STATUS Master_SSL_Crl varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +3.0000 information_schema SLAVE_STATUS Master_SSL_Crlpath varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +3.0000 information_schema SLAVE_STATUS Using_Gtid varchar 15 45 utf8mb3 utf8mb3_general_ci varchar(15) +3.0000 information_schema SLAVE_STATUS Gtid_IO_Pos varchar 1024 3072 utf8mb3 utf8mb3_general_ci varchar(1024) +3.0000 information_schema SLAVE_STATUS Replicate_Do_Domain_Ids varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +3.0000 information_schema SLAVE_STATUS Replicate_Ignore_Domain_Ids varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +3.0000 information_schema SLAVE_STATUS Parallel_Mode varchar 15 45 utf8mb3 utf8mb3_general_ci varchar(15) +NULL information_schema SLAVE_STATUS SQL_Delay int NULL NULL NULL NULL int(10) unsigned +NULL information_schema SLAVE_STATUS SQL_Remaining_Delay int NULL NULL NULL NULL int(10) unsigned +3.0000 information_schema SLAVE_STATUS Slave_SQL_Running_State varchar 64 192 utf8mb3 utf8mb3_general_ci varchar(64) +NULL information_schema SLAVE_STATUS Slave_DDL_Groups bigint NULL NULL NULL NULL bigint(20) unsigned +NULL information_schema SLAVE_STATUS Slave_Non_Transactional_Groups bigint NULL NULL NULL NULL bigint(20) unsigned +NULL information_schema SLAVE_STATUS Slave_Transactional_Groups bigint NULL NULL NULL NULL bigint(20) unsigned +3.0000 information_schema SLAVE_STATUS Replicate_Rewrite_DB varchar 1024 3072 utf8mb3 utf8mb3_general_ci varchar(1024) +NULL information_schema SLAVE_STATUS Retried_transactions int NULL NULL NULL NULL int(10) unsigned +NULL information_schema SLAVE_STATUS Max_relay_log_size bigint NULL NULL NULL NULL bigint(10) unsigned +NULL information_schema SLAVE_STATUS Executed_log_entries int NULL NULL NULL NULL int(10) unsigned +NULL information_schema SLAVE_STATUS Slave_received_heartbeats int NULL NULL NULL NULL int(10) unsigned +NULL information_schema SLAVE_STATUS Slave_heartbeat_period float NULL NULL NULL NULL float(9,3) +3.0000 information_schema SLAVE_STATUS Gtid_Slave_Pos varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) +NULL information_schema SLAVE_STATUS Master_last_event_time datetime NULL NULL NULL NULL datetime +NULL information_schema SLAVE_STATUS Slave_last_event_time datetime NULL NULL NULL NULL datetime +NULL information_schema SLAVE_STATUS Master_Slave_time_diff bigint NULL NULL NULL NULL bigint(10) NULL information_schema SPATIAL_REF_SYS SRID smallint NULL NULL NULL NULL smallint(5) 3.0000 information_schema SPATIAL_REF_SYS AUTH_NAME varchar 512 1536 utf8mb3 utf8mb3_general_ci varchar(512) NULL information_schema SPATIAL_REF_SYS AUTH_SRID int NULL NULL NULL NULL int(5) diff --git a/mysql-test/suite/funcs_1/r/is_tables_is.result b/mysql-test/suite/funcs_1/r/is_tables_is.result index c3c53e149b4..21ab57f7595 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_is.result +++ b/mysql-test/suite/funcs_1/r/is_tables_is.result @@ -889,6 +889,31 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME SLAVE_STATUS +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 11 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8mb3_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +MAX_INDEX_LENGTH #MIL# +TEMPORARY Y +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME SPATIAL_REF_SYS TABLE_TYPE SYSTEM VIEW ENGINE MEMORY @@ -2130,6 +2155,31 @@ user_comment Separator ----------------------------------------------------- TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME SLAVE_STATUS +TABLE_TYPE SYSTEM VIEW +ENGINE MEMORY +VERSION 11 +ROW_FORMAT Fixed +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8mb3_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +MAX_INDEX_LENGTH #MIL# +TEMPORARY Y +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME SPATIAL_REF_SYS TABLE_TYPE SYSTEM VIEW ENGINE MEMORY diff --git a/mysql-test/suite/multi_source/info_logs.result b/mysql-test/suite/multi_source/info_logs.result index 36065116784..4dca25b8fc7 100644 --- a/mysql-test/suite/multi_source/info_logs.result +++ b/mysql-test/suite/multi_source/info_logs.result @@ -94,17 +94,17 @@ MASTER 2.2 # EOF # show all slaves status; -Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Replicate_Rewrite_DB Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos - Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 <read_master_log_pos> relay.000002 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space1> None 0 Yes 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 7 0 60.000 -MASTER 2.2 Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 <read_master_log_pos> relay-master@00202@002e2.000002 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space2> None 0 Yes 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 7 0 60.000 +Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Replicate_Rewrite_DB Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos Master_last_event_time Slave_last_event_time Master_Slave_time_diff + Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 <read_master_log_pos> relay.000002 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space1> None 0 Yes 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 7 0 60.000 NULL NULL NULL +MASTER 2.2 Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 <read_master_log_pos> relay-master@00202@002e2.000002 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space2> None 0 Yes 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 7 0 60.000 NULL NULL NULL include/wait_for_slave_to_start.inc set default_master_connection = 'MASTER 2.2'; include/wait_for_slave_to_start.inc set default_master_connection = ''; show all slaves status; -Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Replicate_Rewrite_DB Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos - Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 <read_master_log_pos> relay.000004 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space1> None 0 Yes 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 6 0 60.000 -MASTER 2.2 Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 <read_master_log_pos> relay-master@00202@002e2.000004 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space2> None 0 Yes 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 6 0 60.000 +Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Replicate_Rewrite_DB Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos Master_last_event_time Slave_last_event_time Master_Slave_time_diff + Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 <read_master_log_pos> relay.000004 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space1> None 0 Yes 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 6 0 60.000 NULL NULL NULL +MASTER 2.2 Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 <read_master_log_pos> relay-master@00202@002e2.000004 <relay_log_pos> master-bin.000001 Yes Yes 0 0 <read_master_log_pos> <relay_log_space2> None 0 Yes 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 6 0 60.000 NULL NULL NULL # # List of files matching '*info*' pattern # after slave server restart diff --git a/mysql-test/suite/multi_source/multi_source_slave_alias_replica.result b/mysql-test/suite/multi_source/multi_source_slave_alias_replica.result index 4c721a17428..182d9687cb9 100644 --- a/mysql-test/suite/multi_source/multi_source_slave_alias_replica.result +++ b/mysql-test/suite/multi_source/multi_source_slave_alias_replica.result @@ -82,6 +82,9 @@ Executed_log_entries 7 Slave_received_heartbeats 0 Slave_heartbeat_period 60.000 Gtid_Slave_Pos +Master_last_event_time NULL +Slave_last_event_time NULL +Master_Slave_time_diff NULL Connection_name slave2 Slave_SQL_State Slave has read all relay log; waiting for more updates Slave_IO_State Waiting for master to send event @@ -144,6 +147,9 @@ Executed_log_entries 7 Slave_received_heartbeats 0 Slave_heartbeat_period 60.000 Gtid_Slave_Pos +Master_last_event_time NULL +Slave_last_event_time NULL +Master_Slave_time_diff NULL "Command: STOP ALL SLAVES --> STOP ALL REPLICAS" STOP ALL REPLICAS; Warnings: diff --git a/mysql-test/suite/multi_source/simple.result b/mysql-test/suite/multi_source/simple.result index f9f43d44ca7..006d0aacfbd 100644 --- a/mysql-test/suite/multi_source/simple.result +++ b/mysql-test/suite/multi_source/simple.result @@ -80,6 +80,9 @@ Executed_log_entries 7 Slave_received_heartbeats 0 Slave_heartbeat_period 60.000 Gtid_Slave_Pos +Master_last_event_time NULL +Slave_last_event_time NULL +Master_Slave_time_diff NULL Connection_name slave2 Slave_SQL_State Slave has read all relay log; waiting for more updates Slave_IO_State Waiting for master to send event @@ -142,6 +145,9 @@ Executed_log_entries 7 Slave_received_heartbeats 0 Slave_heartbeat_period 60.000 Gtid_Slave_Pos +Master_last_event_time NULL +Slave_last_event_time NULL +Master_Slave_time_diff NULL # # MDEV:16437: merge 5.7 P_S replication instrumentation and tables # @@ -327,6 +333,9 @@ Executed_log_entries 7 Slave_received_heartbeats 0 Slave_heartbeat_period 60.000 Gtid_Slave_Pos +Master_last_event_time NULL +Slave_last_event_time NULL +Master_Slave_time_diff NULL Connection_name slave2 Slave_SQL_State Slave has read all relay log; waiting for more updates Slave_IO_State Waiting for master to send event @@ -389,6 +398,9 @@ Executed_log_entries 7 Slave_received_heartbeats 0 Slave_heartbeat_period 60.000 Gtid_Slave_Pos +Master_last_event_time NULL +Slave_last_event_time NULL +Master_Slave_time_diff NULL reset slave 'slave1' all; show all slaves status; Connection_name slave2 @@ -453,6 +465,9 @@ Executed_log_entries 7 Slave_received_heartbeats 0 Slave_heartbeat_period 60.000 Gtid_Slave_Pos +Master_last_event_time NULL +Slave_last_event_time NULL +Master_Slave_time_diff NULL stop all slaves; Warnings: Note 1938 SLAVE 'slave2' stopped @@ -519,6 +534,9 @@ Executed_log_entries 7 Slave_received_heartbeats 0 Slave_heartbeat_period 60.000 Gtid_Slave_Pos +Master_last_event_time NULL +Slave_last_event_time NULL +Master_Slave_time_diff NULL stop all slaves; include/reset_master_slave.inc disconnect slave; diff --git a/mysql-test/suite/multi_source/syntax.result b/mysql-test/suite/multi_source/syntax.result index ce60f48c831..7475ff76e58 100644 --- a/mysql-test/suite/multi_source/syntax.result +++ b/mysql-test/suite/multi_source/syntax.result @@ -5,7 +5,7 @@ Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File show slave '' status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Replicate_Rewrite_DB show all slaves status; -Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Replicate_Rewrite_DB Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos +Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Replicate_Rewrite_DB Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos Master_last_event_time Slave_last_event_time Master_Slave_time_diff # # Check error handling # diff --git a/mysql-test/suite/perfschema/r/relaylog.result b/mysql-test/suite/perfschema/r/relaylog.result index 7cc87530770..dc611b59b27 100644 --- a/mysql-test/suite/perfschema/r/relaylog.result +++ b/mysql-test/suite/perfschema/r/relaylog.result @@ -20,7 +20,7 @@ if (count_write > 0,"MANY", "NONE") as COUNT_WRITE, if (sum_number_of_bytes_read > 0, "MANY", "NONE") as SUM_NUMBER_OF_BYTES_READ, if (sum_number_of_bytes_write > 0, "MANY", "NONE") as SUM_NUMBER_OF_BYTES_WRITE from performance_schema.file_summary_by_instance -where file_name like "%master-%" order by file_name; +where file_name like "%master-%" and file_name not like "%sql/share%" order by file_name; FILE_NAME EVENT_NAME COUNT_READ COUNT_WRITE SUM_NUMBER_OF_BYTES_READ SUM_NUMBER_OF_BYTES_WRITE master-bin.000001 wait/io/file/sql/binlog MANY MANY MANY MANY master-bin.000001.idx wait/io/file/sql/gtid_index NONE MANY NONE MANY @@ -96,7 +96,7 @@ wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_index 0 0 0 0 0 connection slave; "============ Performance schema on slave ============" select * from performance_schema.file_summary_by_instance -where file_name like "%master-%" order by file_name; +where file_name like "%master-%" and file_name not like "%sql/share%" order by file_name; FILE_NAME EVENT_NAME OBJECT_INSTANCE_BEGIN COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT COUNT_READ SUM_TIMER_READ MIN_TIMER_READ AVG_TIMER_READ MAX_TIMER_READ SUM_NUMBER_OF_BYTES_READ COUNT_WRITE SUM_TIMER_WRITE MIN_TIMER_WRITE AVG_TIMER_WRITE MAX_TIMER_WRITE SUM_NUMBER_OF_BYTES_WRITE COUNT_MISC SUM_TIMER_MISC MIN_TIMER_MISC AVG_TIMER_MISC MAX_TIMER_MISC select substring(file_name, locate("slave-", file_name)) as FILE_NAME, diff --git a/mysql-test/suite/perfschema/t/relaylog.test b/mysql-test/suite/perfschema/t/relaylog.test index 12fc96a8b27..16f72efae98 100644 --- a/mysql-test/suite/perfschema/t/relaylog.test +++ b/mysql-test/suite/perfschema/t/relaylog.test @@ -43,7 +43,7 @@ select if (sum_number_of_bytes_read > 0, "MANY", "NONE") as SUM_NUMBER_OF_BYTES_READ, if (sum_number_of_bytes_write > 0, "MANY", "NONE") as SUM_NUMBER_OF_BYTES_WRITE from performance_schema.file_summary_by_instance - where file_name like "%master-%" order by file_name; + where file_name like "%master-%" and file_name not like "%sql/share%" order by file_name; select * from performance_schema.file_summary_by_instance where file_name like "%slave-%" order by file_name; @@ -96,7 +96,7 @@ sync_slave_with_master; -- echo "============ Performance schema on slave ============" select * from performance_schema.file_summary_by_instance - where file_name like "%master-%" order by file_name; + where file_name like "%master-%" and file_name not like "%sql/share%" order by file_name; select substring(file_name, locate("slave-", file_name)) as FILE_NAME, diff --git a/mysql-test/suite/rpl/r/master_last_event_time_row.result b/mysql-test/suite/rpl/r/master_last_event_time_row.result new file mode 100644 index 00000000000..2dd332007e8 --- /dev/null +++ b/mysql-test/suite/rpl/r/master_last_event_time_row.result @@ -0,0 +1,203 @@ +include/rpl_init.inc [topology=1->2->3] +# +# Initialize test data +# Ensure that all slaves has master_last_event_time == NULL +# +connection server_1; +SET STATEMENT sql_log_bin=0 FOR create table t1 (a int) engine=innodb; +include/save_master_pos.inc +connection server_2; +SET STATEMENT sql_log_bin=0 FOR create table t1 (a int) engine=innodb; +connection server_3; +SET STATEMENT sql_log_bin=0 FOR create table t1 (a int) engine=innodb; +# +# Test *_last_event_time is updated at proper place. +# Master_last_event_time should be updated by the IO thread when reading +# in a new transaction from the primary. +# Slave_last_event_time should be updated by the SQL thread +# 1) immediately upon seeing the first transaction if the replica is +# starting fresh, or +# 2) after committing a transaction. +# +connection server_2; +start slave io_thread; +include/sync_io_with_master.inc +master_time: (should be empty) +slave_time: (should be empty) +# Sleep 2s to create a time gap between the header events (i.e. +# Format_description and Gtid_list) and the transaction event to allow +# proving that header events should not update +# (Master|Slave)_last_event_time +connect server_1_1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +set @@timestamp= TIMESTAMP; +insert into t1 values (0); +include/save_master_pos.inc +connection server_2; +include/sync_io_with_master.inc +# For the first event, at execution start, Slave_last_event_time should +# be updated to be 1 second prior to the time that the first transaction +# was binlogged on the primary. This is to represent that the slave is +# otherwise up-to-date. Note the table is locked to prevent the +# transaction from committing (and thereby progressing +# Slave_last_event_time to represent commit-time). +connect server_2_2,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +lock tables t1 write; +connection server_2; +start slave sql_thread; +# Waiting for replica to start executing the transaction (yet get stuck on the table lock) +connection server_2_2; +unlock tables; +connection server_2; +include/wait_for_slave_param.inc [Relay_Master_Log_File] +include/wait_for_slave_param.inc [Exec_Master_Log_Pos] +# +# Test that changes are properly applied by server_2 and server_3 +# +connection server_1; +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +# Show that the server_2 received the insert from master +select * from t1; +a +0 +master <> NULL; Should be 1 +1 +master_time == slave_time ; Should be 1 +1 +connection server_3; +include/start_slave.inc +include/sync_with_master_gtid.inc +# Show that the server_3 received the insert from master +select * from t1; +a +0 +master <> NULL; Should be 1 +1 +master_time == slave_time ; Should be 1 +1 +include/stop_slave.inc +connection server_1; +# +# Test simple insert +# +connection server_1; +insert into t1 values (1+sleep(3)); +# +# Test that changes are properly applied by server_2 and server_3 +# +connection server_1; +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +# Show that the server_2 received the insert from master +select * from t1; +a +0 +1 +master <> NULL; Should be 1 +1 +master_time == slave_time ; Should be 1 +1 +connection server_3; +include/start_slave.inc +include/sync_with_master_gtid.inc +# Show that the server_3 received the insert from master +select * from t1; +a +0 +1 +master <> NULL; Should be 1 +1 +master_time == slave_time ; Should be 1 +1 +include/stop_slave.inc +connection server_1; +# +# Test insert with forced time +# +SET TIMESTAMP=unix_timestamp("2000-01-01"); +insert into t1 values (2+sleep(3)); +SET TIMESTAMP=DEFAULT; +# +# Test that changes are properly applied by server_2 and server_3 +# +connection server_1; +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +# Show that the server_2 received the insert from master +select * from t1; +a +0 +1 +2 +master <> NULL; Should be 1 +1 +master_time == slave_time ; Should be 1 +1 +connection server_3; +include/start_slave.inc +include/sync_with_master_gtid.inc +# Show that the server_3 received the insert from master +select * from t1; +a +0 +1 +2 +master <> NULL; Should be 1 +1 +master_time == slave_time ; Should be 1 +1 +include/stop_slave.inc +connection server_1; +# +# Test multi-transaction +# +begin; +insert into t1 values (3+sleep(3)); +insert into t1 values (4+sleep(3)); +commit; +# +# Test that changes are properly applied by server_2 and server_3 +# +connection server_1; +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +# Show that the server_2 received the insert from master +select * from t1; +a +0 +1 +2 +3 +4 +master <> NULL; Should be 1 +1 +master_time == slave_time ; Should be 1 +1 +connection server_3; +include/start_slave.inc +include/sync_with_master_gtid.inc +# Show that the server_3 received the insert from master +select * from t1; +a +0 +1 +2 +3 +4 +master <> NULL; Should be 1 +1 +master_time == slave_time ; Should be 1 +1 +include/stop_slave.inc +connection server_1; +# cleanup +connection server_3; +include/start_slave.inc +connection server_1; +drop table t1; +include/rpl_end.inc +# End of master_last_event_time_row diff --git a/mysql-test/suite/rpl/r/master_last_event_time_stmt.result b/mysql-test/suite/rpl/r/master_last_event_time_stmt.result new file mode 100644 index 00000000000..4b1e41a7704 --- /dev/null +++ b/mysql-test/suite/rpl/r/master_last_event_time_stmt.result @@ -0,0 +1,71 @@ +include/rpl_init.inc [topology=1->2->3] +connection server_3; +include/stop_slave.inc +connection server_1; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +alter table mysql.gtid_slave_pos engine=innodb; +create table t1 (a int) engine=aria; +create table t2 (a int) engine=innodb; +include/save_master_gtid.inc +# +# Ensure that the slave doesn't overwrite exec_time when binlogging +# +connection server_2; +include/sync_with_master_gtid.inc +include/stop_slave.inc +change master to master_delay=SLAVE_DELAY; +include/start_slave.inc +connection server_1; +# Sleep 2 to ensure DDL and DML have different binlog timestamps +connection server_2; +flush logs; +connection server_1; +set @@timestamp= TIMESTAMP; +insert into t1 values (sleep(2)); +include/save_master_gtid.inc +# Waiting for slave to delay and commit transaction.. +connection server_2; +include/sync_with_master_gtid.inc +# MYSQL_BINLOG slave_local_binlog > slave_outfile +include/assert_grep.inc [Ensure slave doesn't overwrite exec_time in the binlog event] +# +# Test that changes are properly applied by server_2 and server_3 +# +connection server_1; +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +# Show that the server_2 received the insert from master +select * from t1; +a +0 +master <> NULL; Should be 1 +1 +master_time == slave_time ; Should be 1 +1 +connection server_3; +include/start_slave.inc +include/sync_with_master_gtid.inc +# Show that the server_3 received the insert from master +select * from t1; +a +0 +master <> NULL; Should be 1 +1 +master_time == slave_time ; Should be 1 +1 +include/stop_slave.inc +connection server_1; +connection server_2; +include/stop_slave.inc +change master to master_delay=0; +include/start_slave.inc +connection server_3; +include/start_slave.inc +# +# Cleanup +connection server_1; +drop table t1; +drop table t2; +include/rpl_end.inc +# End of master_last_event_time_stmt diff --git a/mysql-test/suite/rpl/r/rpl_parallel_sbm.result b/mysql-test/suite/rpl/r/rpl_parallel_sbm.result index 75012c93f3b..c41de974588 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_sbm.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_sbm.result @@ -23,6 +23,11 @@ connection slave; # Waiting for transaction to arrive on slave and begin SQL Delay.. # Validating SBM is updated on event arrival.. # ..done +# MDEV-33856: New definition for Seconds_Behind_Master +# Validating Master_last_event_time is updated on event arrival.. +# ..done +# Validating Slave_last_event_time is still from the last transaction.. +# ..done # MDEV-32265. At time of STOP SLAVE, if the SQL Thread is currently # delaying a transaction; then when the reciprocal START SLAVE occurs, # if the event is still to be delayed, SBM should resume accordingly @@ -41,6 +46,9 @@ connection slave; connection server_2; UNLOCK TABLES; include/sync_with_master_gtid.inc +# MDEV-33856: New definition for Seconds_Behind_Master +# Ensuring Slave_last_event_time is now up-to-date once event is executed +# ..done # # Pt 2) If the worker threads have not entered an idle state, ensure # following events do not update SBM diff --git a/mysql-test/suite/rpl/t/master_last_event_time.inc b/mysql-test/suite/rpl/t/master_last_event_time.inc new file mode 100644 index 00000000000..0790d557a7b --- /dev/null +++ b/mysql-test/suite/rpl/t/master_last_event_time.inc @@ -0,0 +1,58 @@ +--echo # +--echo # Test that changes are properly applied by server_2 and server_3 +--echo # + +--connection server_1 +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc + +--echo # Show that the server_2 received the insert from master +select * from t1; + +--let $master_time= query_get_value(SHOW ALL SLAVES STATUS, Master_last_event_time, 1) +--let $slave_time= query_get_value(SHOW ALL SLAVES STATUS, Slave_last_event_time, 1) +--disable_query_log +--eval select "$master_time" <> "NULL" as "master <> NULL; Should be 1" + +if (`SELECT NOT "$master_time" <> "NULL"`) +{ + --echo MASTER: $master_time +} + +--eval select "$master_time" = "$slave_time" as "master_time == slave_time ; Should be 1" +if (`SELECT NOT "$master_time" = "$slave_time"`) +{ + --echo MASTER: $master_time SLAVE: $slave_time +} +--enable_query_log + +--connection server_3 +--sleep 1 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +--echo # Show that the server_3 received the insert from master +select * from t1; + +--let $master_time= query_get_value(SHOW ALL SLAVES STATUS, Master_last_event_time, 1) +--let $slave_time= query_get_value(SHOW ALL SLAVES STATUS, Slave_last_event_time, 1) +--disable_query_log + +--eval select "$master_time" <> "NULL" as "master <> NULL; Should be 1" +if (`SELECT NOT "$master_time" <> "NULL"`) +{ + --echo MASTER: $master_time +} + +--eval select "$master_time" = "$slave_time" as "master_time == slave_time ; Should be 1" +if (`SELECT NOT "$master_time" = "$slave_time"`) +{ + --echo MASTER: $master_time SLAVE: $slave_time +} +--enable_query_log + +# Reset things for next test +--source include/stop_slave.inc +--connection server_1 diff --git a/mysql-test/suite/rpl/t/master_last_event_time_row.cnf b/mysql-test/suite/rpl/t/master_last_event_time_row.cnf new file mode 100644 index 00000000000..65a4396edf3 --- /dev/null +++ b/mysql-test/suite/rpl/t/master_last_event_time_row.cnf @@ -0,0 +1,16 @@ +!include suite/rpl/my.cnf + +[mysqld.1] + +[mysqld.2] +log-slave-updates +binlog-checksum=CRC32 + +[mysqld.3] +log-slave-updates +binlog-checksum=CRC32 + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket + diff --git a/mysql-test/suite/rpl/t/master_last_event_time_row.test b/mysql-test/suite/rpl/t/master_last_event_time_row.test new file mode 100644 index 00000000000..92abe00d407 --- /dev/null +++ b/mysql-test/suite/rpl/t/master_last_event_time_row.test @@ -0,0 +1,168 @@ +# +# Row specific tests for master_last_event_time +# +--source include/have_binlog_format_row.inc +--source include/have_innodb.inc +--let $rpl_skip_start_slave=1 +--let $rpl_topology=1->2->3 +--source include/rpl_init.inc + +--echo # +--echo # Initialize test data +--echo # Ensure that all slaves has master_last_event_time == NULL +--echo # + +--connection server_1 +SET STATEMENT sql_log_bin=0 FOR create table t1 (a int) engine=innodb; +--source include/save_master_pos.inc +--connection server_2 +SET STATEMENT sql_log_bin=0 FOR create table t1 (a int) engine=innodb; +--connection server_3 +SET STATEMENT sql_log_bin=0 FOR create table t1 (a int) engine=innodb; + +--echo # +--echo # Test *_last_event_time is updated at proper place. +--echo # Master_last_event_time should be updated by the IO thread when reading +--echo # in a new transaction from the primary. +--echo # Slave_last_event_time should be updated by the SQL thread +--echo # 1) immediately upon seeing the first transaction if the replica is +--echo # starting fresh, or +--echo # 2) after committing a transaction. +--echo # + +--connection server_2 +start slave io_thread; +--source include/sync_io_with_master.inc + +# Ensure Master_last_event_time and Slave_last_event_time are not yet set +--let $master_time= `select Master_last_event_time from information_schema.slave_status` +--echo master_time: $master_time (should be empty) +--let $slave_time=`select Slave_last_event_time from information_schema.slave_status` +--echo slave_time: $slave_time (should be empty) + +--echo # Sleep 2s to create a time gap between the header events (i.e. +--echo # Format_description and Gtid_list) and the transaction event to allow +--echo # proving that header events should not update +--echo # (Master|Slave)_last_event_time +--sleep 2 + +--connect (server_1_1,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--let $t1_time_begin= `select truncate(@@timestamp,0)` +--replace_result $t1_time_begin TIMESTAMP +--eval set @@timestamp= $t1_time_begin +insert into t1 values (0); + +--source include/save_master_pos.inc + +--connection server_2 +--source include/sync_io_with_master.inc + +--let $mle_time= `select Master_last_event_time from information_schema.slave_status` +--let $mle_time_unix= `select truncate(unix_timestamp("$mle_time"),0)` +if (`SELECT ($mle_time_unix < $t1_time_begin)`) +{ + --echo # Expected timestamp (master binlog time): $t1_time_begin + --echo # Reported Master_last_event_time: $mle_time_unix ($mle_time) + --die Master_last_event_time did not correspond to time that the transaction was binlogged on primary +} + +--let $slave_time= `select Slave_last_event_time from information_schema.slave_status` +if (`select strcmp("$slave_time", "") != 0`) +{ + --echo # Slave_last_event_time: $slave_time + --die SQL thread was never started, Slave_last_event_time should be NULL +} + +# Check that we also get the values from show all slaves status +--let $time_diff= query_get_value(SHOW ALL SLAVES STATUS, Master_Slave_time_diff, 1) +if (`select strcmp("$time_diff", "NULL") != 0`) +{ + --echo # Master_Slave_time_diff: $time_diff + --die SQL thread was never started, Master_Slave_time_diff should be NULL +} + +--echo # For the first event, at execution start, Slave_last_event_time should +--echo # be updated to be 1 second prior to the time that the first transaction +--echo # was binlogged on the primary. This is to represent that the slave is +--echo # otherwise up-to-date. Note the table is locked to prevent the +--echo # transaction from committing (and thereby progressing +--echo # Slave_last_event_time to represent commit-time). + +--connect (server_2_2,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +lock tables t1 write; + +--connection server_2 +start slave sql_thread; + +--echo # Waiting for replica to start executing the transaction (yet get stuck on the table lock) +--let $wait_condition= SELECT count(*) FROM information_schema.processlist WHERE state LIKE 'Waiting for table metadata lock'; +--source include/wait_condition.inc + +--let $slave_time= query_get_value(SHOW ALL SLAVES STATUS, Slave_last_event_time, 1) +--let $slave_time_unix= `select truncate(unix_timestamp("$slave_time"),0)` +--let $expected_slave_time= `select ($t1_time_begin - 1)` +if ($slave_time_unix != $expected_slave_time) +{ + --echo # Master_last_event_time: $mle_time_unix ($mle_time) + --echo # Slave_last_event_time: $slave_time_unix ($slave_time) + --echo # Expected value: $expected_slave_time + --die SQL thread has not yet committed its first transaction, Slave_last_event_time should be 1s before that transaction +} + +# Master_Slave_time_diff isn't guaranteed to be 1 second, despite the +# hard-coded logic to subtract 1s from the first non-group event that comes in. +# This is because the Gtid and Xid events can be logged with different +# timestamps, and Slave_last_event_time is updated using the Gtid log event, +# and Master_last_event_time is updated using the Xid log event. So to ensure +# that Master_Slave_time_diff is updated correctly for the first transaction, +# it must also take into account the difference in timestamps of these events +--let $xid_gtid_time_diff=`SELECT $mle_time_unix - $t1_time_begin` +--let $time_diff= query_get_value(SHOW ALL SLAVES STATUS, Master_Slave_time_diff, 1) +if (`SELECT $time_diff != 1 + $xid_gtid_time_diff`) +{ + --echo # Master_Slave_time_diff: $time_diff + --echo # Xid Gtid Timestamp Difference: $xid_gtid_time_diff + --die SQL thread has not yet committed its first transaction, Master_Slave_time_diff should be updated to look up-to-date prior to this trx +} + +--connection server_2_2 +unlock tables; + +--connection server_2 +--source include/sync_with_master.inc +--source master_last_event_time.inc + +--echo # +--echo # Test simple insert +--echo # + +--connection server_1 +insert into t1 values (1+sleep(3)); +--source master_last_event_time.inc + +--echo # +--echo # Test insert with forced time +--echo # + +SET TIMESTAMP=unix_timestamp("2000-01-01"); +insert into t1 values (2+sleep(3)); +SET TIMESTAMP=DEFAULT; +--source master_last_event_time.inc + +--echo # +--echo # Test multi-transaction +--echo # + +begin; +insert into t1 values (3+sleep(3)); +insert into t1 values (4+sleep(3)); +commit; +--source master_last_event_time.inc + +--echo # cleanup +--connection server_3 +--source include/start_slave.inc +--connection server_1 +drop table t1; +--source include/rpl_end.inc +--echo # End of master_last_event_time_row diff --git a/mysql-test/suite/rpl/t/master_last_event_time_stmt.cnf b/mysql-test/suite/rpl/t/master_last_event_time_stmt.cnf new file mode 100644 index 00000000000..35b68f7906f --- /dev/null +++ b/mysql-test/suite/rpl/t/master_last_event_time_stmt.cnf @@ -0,0 +1,15 @@ +!include suite/rpl/my.cnf + +[mysqld.1] + +[mysqld.2] +log-slave-updates +binlog-checksum=CRC32 + +[mysqld.3] +log-slave-updates +binlog-checksum=CRC32 + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket diff --git a/mysql-test/suite/rpl/t/master_last_event_time_stmt.test b/mysql-test/suite/rpl/t/master_last_event_time_stmt.test new file mode 100644 index 00000000000..fe0f16a3db3 --- /dev/null +++ b/mysql-test/suite/rpl/t/master_last_event_time_stmt.test @@ -0,0 +1,84 @@ +# +# Statement specific tests for master_last_event_time +# +--source include/have_binlog_format_statement.inc +--source include/have_innodb.inc +--let $rpl_topology=1->2->3 +--source include/rpl_init.inc + +# Server_3 state is maintained by master_last_event_time.inc +--connection server_3 +--source include/stop_slave.inc + +--connection server_1 +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +alter table mysql.gtid_slave_pos engine=innodb; +create table t1 (a int) engine=aria; +create table t2 (a int) engine=innodb; +--source include/save_master_gtid.inc + +--echo # +--echo # Ensure that the slave doesn't overwrite exec_time when binlogging +--echo # + +--let $slave_delay= 3 + +--connection server_2 +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +--replace_result $slave_delay SLAVE_DELAY +--eval change master to master_delay=$slave_delay +--source include/start_slave.inc + +--connection server_1 +--echo # Sleep 2 to ensure DDL and DML have different binlog timestamps +--sleep 2 +--let $t1_time_begin= `select truncate(@@timestamp,0)` +--connection server_2 +flush logs; +--connection server_1 +--replace_result $t1_time_begin TIMESTAMP +--eval set @@timestamp= $t1_time_begin +--disable_warnings +insert into t1 values (sleep(2)); +--source include/save_master_gtid.inc +--enable_warnings + +--echo # Waiting for slave to delay and commit transaction.. +--connection server_2 +--source include/sync_with_master_gtid.inc + +# Slave will replicate the above with a row event which will be very fast +# compared to the master event. +# Check the exec time is not 0 (which is typical for very fast row events) + +--let $datadir= `select @@datadir` +--let $filename= query_get_value(SHOW MASTER STATUS, File, 1) +--let $slave_local_binlog=$datadir/$filename +--let $slave_outfile=$MYSQLTEST_VARDIR/tmp/slave_binlog.sql +--echo # MYSQL_BINLOG slave_local_binlog > slave_outfile +--exec $MYSQL_BINLOG $slave_local_binlog > $slave_outfile +--let $assert_count=0 +--let $assert_text= Ensure slave doesn't overwrite exec_time in the binlog event +--let $assert_select=exec_time=0 +--let $assert_file= $slave_outfile +--source include/assert_grep.inc + +--source master_last_event_time.inc + +--connection server_2 +--source include/stop_slave.inc +change master to master_delay=0; +--source include/start_slave.inc +--connection server_3 +--source include/start_slave.inc + +--echo # +--echo # Cleanup +--connection server_1 +drop table t1; +drop table t2; + +--source include/rpl_end.inc +--remove_file $slave_outfile +--echo # End of master_last_event_time_stmt diff --git a/mysql-test/suite/rpl/t/rpl_parallel_sbm.test b/mysql-test/suite/rpl/t/rpl_parallel_sbm.test index 90753caf143..2c9b4882c16 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_sbm.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_sbm.test @@ -61,6 +61,30 @@ if (`SELECT $sbm_trx1_arrive > ($seconds_since_idling + 1)`) } --echo # ..done +--echo # MDEV-33856: New definition for Seconds_Behind_Master +--echo # Validating Master_last_event_time is updated on event arrival.. +--let $mle_time_trx1_arrive= query_get_value(SHOW ALL SLAVES STATUS, Master_last_event_time, 1) +--let $mle_time_trx1_arrive_unix= `SELECT truncate(unix_timestamp("$mle_time_trx1_arrive"), 0)` +if (`SELECT $mle_time_trx1_arrive_unix < ($ts_trx_before_ins - 1)`) +{ + --echo # Master_last_event_time: $mle_time_trx1_arrive_unix ($mle_time_trx1_arrive) + --die Master_last_event_time was not updated for delayed replica at event arrival time +} +--echo # ..done + +--echo # Validating Slave_last_event_time is still from the last transaction.. +# Note we infer Slave_last_event_time via Master_Slave_time_diff +--let $time_diff_trx1_arrive= query_get_value(SHOW ALL SLAVES STATUS, Master_Slave_time_diff, 1) +if ($time_diff_trx1_arrive < 5) +{ + --let $slave_time_trx1_arrive= query_get_value(SHOW ALL SLAVES STATUS, Slave_last_event_time, 1) + --let $slave_time_trx1_arrive_unix= `SELECT truncate(unix_timestamp("$slave_time_trx1_arrive"), 0)` + --echo # Slave_last_event_time: $slave_time_trx1_arrive_unix ($slave_time_trx1_arrive) + --echo # Master_Slave_time_diff: $time_diff_trx1_arrive + --die Slave_last_event_time is too recent, should not be less than 5 seconds, ie. 3 from delay + 2 from sleep +} +--echo # ..done + --echo # MDEV-32265. At time of STOP SLAVE, if the SQL Thread is currently --echo # delaying a transaction; then when the reciprocal START SLAVE occurs, @@ -98,6 +122,24 @@ UNLOCK TABLES; --source include/sync_with_master_gtid.inc +--echo # MDEV-33856: New definition for Seconds_Behind_Master +--echo # Ensuring Slave_last_event_time is now up-to-date once event is executed +--let $slave_time_trx1_commit= query_get_value(SHOW ALL SLAVES STATUS, Slave_last_event_time, 1) +--let $slave_time_trx1_commit_unix= `SELECT truncate(unix_timestamp("$slave_time_trx1_commit"),0)` +if ($slave_time_trx1_commit_unix != $mle_time_trx1_arrive_unix) +{ + --echo # Slave_last_event_time: $slave_time_trx1_commit_unix ($slave_time_trx1_commit) + --echo # Master_last_event_time: $mle_time_trx1_arrive_unix ($mle_time_trx1_arrive) + --die Slave_last_event_time is not equal to Master_last_event_time despite being up-to-date +} +--let $time_diff_trx1_commit= query_get_value(SHOW ALL SLAVES STATUS, Master_Slave_time_diff, 1) +if ($time_diff_trx1_commit != 0) +{ + --echo # Master_Slave_time_diff: $time_diff_trx1_commit + --die Master_Slave_time_diff should be 0, as slave is up-to-date +} +--echo # ..done + --echo # --echo # Pt 2) If the worker threads have not entered an idle state, ensure --echo # following events do not update SBM diff --git a/sql/handler.h b/sql/handler.h index 37b403c942c..86862210fab 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1113,6 +1113,9 @@ enum enum_schema_tables SCH_USERS, SCH_USER_PRIVILEGES, SCH_VIEWS, +#ifdef HAVE_REPLICATION + SCH_SLAVE_STATUS, +#endif SCH_ENUM_SIZE }; diff --git a/sql/item.h b/sql/item.h index 6c69f33aecb..28014a1e135 100644 --- a/sql/item.h +++ b/sql/item.h @@ -4902,8 +4902,8 @@ class Item_partition_func_safe_string: public Item_string /** Item_empty_string -- is a utility class to put an item into List<Item> - which is then used in protocol.send_result_set_metadata() when sending SHOW output to - the client. + which is then used in protocol.send_result_set_metadata() when sending SHOW + output to the client. */ class Item_empty_string :public Item_partition_func_safe_string @@ -5284,6 +5284,17 @@ class Item_datetime_literal: public Item_temporal_literal set_maybe_null(cached_time.check_date(TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE)); } + Item_datetime_literal(THD *thd, const char *name_arg, + decimal_digits_t dec_arg): + Item_temporal_literal(thd, dec_arg), + cached_time(Datetime::zero()) + { + max_length= MAX_DATETIME_WIDTH + (decimals ? decimals + 1 : 0); + set_maybe_null(true); + // Set the name (see also a similar code in Item_int): + name.str= name_arg; + name.length= strlen(name.str); + } const Type_handler *type_handler() const override { return &type_handler_datetime2; } void print(String *str, enum_query_type query_type) override; diff --git a/sql/log.cc b/sql/log.cc index 1cc0fa77f08..63d9c756911 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1898,10 +1898,20 @@ static inline int binlog_commit_flush_xid_caches(THD *thd, binlog_cache_mngr *cache_mngr, bool all, my_xid xid) { + DBUG_ENTER("binlog_commit_flush_xid_caches"); DBUG_ASSERT(xid); // replaced former treatment of ONE-PHASE XA Xid_log_event end_evt(thd, xid, TRUE); - return (binlog_flush_cache(thd, cache_mngr, &end_evt, all, TRUE, TRUE)); + if (!thd->slave_thread && ! thd->user_time.val) + { + /* + Ensure that on the master the event time is the time of commit, + not the start of statement time. + */ + my_hrtime_t hrtime= my_hrtime(); + end_evt.when= hrtime_to_my_time(hrtime); + } + DBUG_RETURN(binlog_flush_cache(thd, cache_mngr, &end_evt, all, TRUE, TRUE)); } /** @@ -8224,6 +8234,7 @@ MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd, { group_commit_entry entry; Ha_trx_info *ha_info; + bool has_xid; DBUG_ENTER("MYSQL_BIN_LOG::write_transaction_to_binlog"); /* @@ -8251,13 +8262,16 @@ MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd, ha_info= all ? thd->transaction->all.ha_list : thd->transaction->stmt.ha_list; entry.ro_1pc= is_ro_1pc; entry.end_event= end_ev; - auto has_xid= entry.end_event->get_type_code() == XID_EVENT; + has_xid= entry.end_event->get_type_code() == XID_EVENT; for (; has_xid && !entry.need_unlog && ha_info; ha_info= ha_info->next()) { if (ha_info->is_started() && ha_info->ht() != binlog_hton && !ha_info->ht()->commit_checkpoint_request) + { entry.need_unlog= true; + break; + } } if (cache_mngr->stmt_cache.has_incident() || diff --git a/sql/log_event.cc b/sql/log_event.cc index 3802f76efe0..706a4903eb0 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -964,6 +964,18 @@ Log_event* Log_event::read_log_event(IO_CACHE* file, DBUG_RETURN(res); } +/* + Update thd->orig_exec_time +*/ + +inline void set_orig_exec_time_in_thd(my_time_t exec_time) +{ +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + THD *thd= current_thd; + if (likely(thd)) + thd->orig_exec_time= exec_time; +#endif +} /** Binlog format tolerance is in (buf, event_len, fdle) @@ -1104,10 +1116,12 @@ Log_event* Log_event::read_log_event(const uchar *buf, uint event_len, switch(event_type) { case QUERY_EVENT: ev= new Query_log_event(buf, event_len, fdle, QUERY_EVENT); + set_orig_exec_time_in_thd(((Query_log_event*) ev)->exec_time); break; case QUERY_COMPRESSED_EVENT: ev= new Query_compressed_log_event(buf, event_len, fdle, - QUERY_COMPRESSED_EVENT); + QUERY_COMPRESSED_EVENT); + set_orig_exec_time_in_thd(((Query_compressed_log_event*) ev)->exec_time); break; case ROTATE_EVENT: ev= new Rotate_log_event(buf, event_len, fdle); @@ -1194,6 +1208,7 @@ Log_event* Log_event::read_log_event(const uchar *buf, uint event_len, break; case EXECUTE_LOAD_QUERY_EVENT: ev= new Execute_load_query_log_event(buf, event_len, fdle); + set_orig_exec_time_in_thd(((Query_log_event*) ev)->exec_time); break; case INCIDENT_EVENT: ev= new Incident_log_event(buf, event_len, fdle); @@ -1747,6 +1762,26 @@ Query_log_event::Query_log_event(const uchar *buf, uint event_len, DBUG_VOID_RETURN; } + +/* + Get the time when the event had been executed on the master. + This works for both query events and load data events. +*/ + +#if Q_EXEC_TIME_OFFSET != L_EXEC_TIME_OFFSET +#error "Q_EXEC_TIME_OFFSET is not same as L_EXEC_TIME_OFFSET" +#endif + +time_t query_event_get_time(const uchar *buf, + const Format_description_log_event + *description_event) +{ + time_t when= uint4korr(buf); + buf+= description_event->common_header_len; + return when + uint4korr(buf + Q_EXEC_TIME_OFFSET); +} + + Query_compressed_log_event::Query_compressed_log_event(const uchar *buf, uint event_len, const Format_description_log_event diff --git a/sql/log_event.h b/sql/log_event.h index 3f707ee25c0..69ba7cde440 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -809,6 +809,10 @@ static inline bool LOG_EVENT_IS_ROW_V2(enum Log_event_type type) (type >= WRITE_ROWS_COMPRESSED_EVENT && type <= DELETE_ROWS_COMPRESSED_EVENT); } +static inline bool LOG_EVENT_IS_LOAD_DATA(enum Log_event_type type) +{ + return type == LOAD_EVENT || type == NEW_LOAD_EVENT; +} /* The number of types we handle in Format_description_log_event (UNKNOWN_EVENT @@ -1293,7 +1297,7 @@ class Log_event my_time_t when; ulong when_sec_part; /* The number of seconds the query took to run on the master. */ - ulong exec_time; + my_time_t exec_time; /* Number of bytes written by write() function */ size_t data_written; @@ -1414,8 +1418,8 @@ class Log_event log; used by SHOW BINLOG EVENTS, the binlog_dump thread on the master (reads master's binlog), the slave IO thread (reads the event sent by binlog_dump), the slave SQL thread (reads the event - from the relay log). If mutex is 0, the read will proceed without - mutex. We need the description_event to be able to parse the + from the relay log). + We need the description_event to be able to parse the event (to know the post-header's size); in fact in read_log_event we detect the event's type, then call the specific event's constructor and pass description_event as an argument. @@ -1438,8 +1442,6 @@ class Log_event Reads an event from a binlog or relay log. Used by the dump thread this method reads the event into a raw buffer without parsing it. - @Note If mutex is 0, the read will proceed without mutex. - @Note If a log name is given than the method will check if the given binlog is still active. @@ -5504,6 +5506,9 @@ int row_log_event_uncompress(const Format_description_log_event const uchar *src, ulong src_len, uchar* buf, ulong buf_size, bool *is_malloc, uchar **dst, ulong *newlen); +time_t query_event_get_time(const uchar *buf, + const Format_description_log_event + *description_event); bool is_parallel_retry_error(rpl_group_info *rgi, int err); diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index e2ab6a659cd..2699ec773f8 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -1328,8 +1328,6 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, { /* status_vars_len is set just before writing the event */ - time_t end_time; - #ifdef WITH_WSREP /* If Query_log_event will contain non trans keyword (not BEGIN, COMMIT, @@ -1348,8 +1346,14 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, memset(&host, 0, sizeof(host)); error_code= errcode; - end_time= my_time(0); - exec_time = (ulong) (end_time - thd_arg->start_time); + /* + For slave threads, remember the original master exec time. + This is needed to be able to calculate the master commit time. + */ + exec_time= ((thd->slave_thread) ? + thd->orig_exec_time : + (my_time(0) - thd_arg->start_time)); + /** @todo this means that if we have no catalog, then it is replicated as an existing catalog of length zero. is that safe? /sven @@ -3682,6 +3686,15 @@ int Xid_apply_log_event::do_apply_event(rpl_group_info *rgi) general_log_print(thd, COM_QUERY, get_query()); thd->variables.option_bits&= ~OPTION_GTID_BEGIN; + /* + Use the time from the current Xid_log_event for the generated + Xid_log_event in binlog_commit_flush_xid_caches(). + This ensures that the time for Xid_log_events does not change + and allows slaves to give a consistent value for + Slave_last_event_time. + */ + thd->start_time= when; + res= do_commit(); if (!res && rgi->gtid_pending) { diff --git a/sql/protocol.cc b/sql/protocol.cc index 1e27c996687..ca7803248c6 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -1417,33 +1417,6 @@ bool Protocol::store(I_List<i_string>* str_list) return store((char*) tmp.ptr(), tmp.length(), tmp.charset()); } - -/** - Send a set of strings as a string of key-value pairs with ',' in between. -*/ - -bool Protocol::store(I_List<i_string_pair>* str_list) -{ - char buf[256]; - const char *delimiter= ","; - String tmp(buf, sizeof(buf), &my_charset_bin); - size_t delim_len= 0; - I_List_iterator<i_string_pair> it(*str_list); - i_string_pair* s; - - tmp.length(0); - while ((s=it++)) - { - tmp.append(delimiter, delim_len); - tmp.append(s->key, strlen(s->key)); - tmp.append(STRING_WITH_LEN("->")); - tmp.append(s->val, strlen(s->val)); - delim_len= 1; - } - return store((char*) tmp.ptr(), tmp.length(), tmp.charset()); -} - - /**************************************************************************** Functions to handle the simple (default) protocol where everything is This protocol is the one that is used by default between the MySQL server diff --git a/sql/protocol.h b/sql/protocol.h index d1096b041af..0a55d1b1331 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -105,7 +105,7 @@ class Protocol bool send_result_set_row(List<Item> *row_items); bool store(I_List<i_string> *str_list); - bool store(I_List<i_string_pair> *str_list); + bool store_string_or_null(const char *from, CHARSET_INFO *cs); bool store_warning(const char *from, size_t length); String *storage_packet() { return packet; } diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 4f28f1f8edf..224f1c3ea16 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -1913,6 +1913,14 @@ void Domain_id_filter::store_ids(THD *thd) } } +void Domain_id_filter::store_ids(Field ***field) +{ + for (int i= DO_DOMAIN_IDS; i <= IGNORE_DOMAIN_IDS; i ++) + { + field_store_ids(*((*field)++), &m_domain_ids[i]); + } +} + /** Initialize the given domain_id list (DYNAMIC_ARRAY) with the space-separated list of numbers from the specified IO_CACHE where @@ -1987,20 +1995,10 @@ void update_change_master_ids(DYNAMIC_ARRAY *new_ids, DYNAMIC_ARRAY *old_ids) return; } -/** - Serialize and store the ids from the given ids DYNAMIC_ARRAY into the thd's - protocol buffer. - - @param thd [IN] thread handler - @param ids [IN] ids list - - @retval void -*/ - -void prot_store_ids(THD *thd, DYNAMIC_ARRAY *ids) +static size_t store_ids(DYNAMIC_ARRAY *ids, char *buff, size_t buff_len) { - char buff[FN_REFLEN]; - uint i, cur_len; + uint i; + size_t cur_len; for (i= 0, buff[0]= 0, cur_len= 0; i < ids->elements; i++) { @@ -2008,7 +2006,7 @@ void prot_store_ids(THD *thd, DYNAMIC_ARRAY *ids) char dbuff[FN_REFLEN]; get_dynamic(ids, (void *) &id, i); len= sprintf(dbuff, (i == 0 ? "%lu" : ", %lu"), id); - if (cur_len + len + 4 > FN_REFLEN) + if (cur_len + len + 4 > buff_len) { /* break the loop whenever remained space could not fit @@ -2019,8 +2017,33 @@ void prot_store_ids(THD *thd, DYNAMIC_ARRAY *ids) } cur_len+= sprintf(buff + cur_len, "%s", dbuff); } + return cur_len; +} + + +/** + Serialize and store the ids from the given ids DYNAMIC_ARRAY into the thd's + protocol buffer. + + @param thd [IN] thread handler + @param ids [IN] ids list + + @retval void +*/ + +void prot_store_ids(THD *thd, DYNAMIC_ARRAY *ids) +{ + char buff[FN_REFLEN]; + size_t cur_len= store_ids(ids, buff, sizeof(buff)); thd->protocol->store(buff, cur_len, &my_charset_bin); - return; +} + + +void field_store_ids(Field *field, DYNAMIC_ARRAY *ids) +{ + char buff[FN_REFLEN]; + size_t cur_len= store_ids(ids, buff, sizeof(buff)); + field->store(buff, cur_len, &my_charset_bin); } diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index a0f17a7dd01..37a5fc30099 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -105,7 +105,8 @@ class Domain_id_filter @retval void */ void store_ids(THD *thd); - + /* Same as above, but store the id's into a group of fields */ + void store_ids(Field ***field); /* Initialize the given domain id list (DYNAMIC_ARRAY) with the space-separated list of numbers from the specified IO_CACHE where @@ -430,7 +431,7 @@ int flush_master_info(Master_info* mi, void copy_filter_setting(Rpl_filter* dst_filter, Rpl_filter* src_filter); void update_change_master_ids(DYNAMIC_ARRAY *new_ids, DYNAMIC_ARRAY *old_ids); void prot_store_ids(THD *thd, DYNAMIC_ARRAY *ids); - +void field_store_ids(Field *field, DYNAMIC_ARRAY *ids); /* Multi master are handled trough this struct. Changes to this needs to be protected by LOCK_active_mi; diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index 51ca3b183ec..d279761767a 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -60,7 +60,10 @@ rpt_handle_event(rpl_parallel_thread::queued_event *qev, rgi->future_event_relay_log_pos= qev->future_event_relay_log_pos; strcpy(rgi->future_event_master_log_name, qev->future_event_master_log_name); if (event_can_update_last_master_timestamp(ev)) + { rgi->last_master_timestamp= ev->when + ev->exec_time; + thd->orig_exec_time= ev->exec_time; + } err= apply_event_and_update_pos_for_parallel(ev, thd, rgi); rli->executed_entries++; diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index f2247638c43..461540c0d3f 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -54,7 +54,9 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery, const char* thread_name) cur_log_old_open_count(0), error_on_rli_init_info(false), group_relay_log_pos(0), event_relay_log_pos(0), group_master_log_pos(0), log_space_total(0), ignore_log_space_limit(0), - last_master_timestamp(0), sql_thread_caught_up(true), slave_skip_counter(0), + sql_thread_caught_up(true), + last_master_timestamp(0), newest_master_timestamp(0), slave_timestamp(0), + slave_skip_counter(0), abort_pos_wait(0), slave_run_id(0), sql_driver_thd(), gtid_skip_flag(GTID_SKIP_NOT), inited(0), abort_slave(0), stop_for_until(0), slave_running(MYSQL_SLAVE_NOT_RUN), until_condition(UNTIL_NONE), @@ -1028,9 +1030,7 @@ void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos, potentially thousands of events are still queued up for worker threads waiting for execution. */ - if (rgi->last_master_timestamp && - rgi->last_master_timestamp > last_master_timestamp) - last_master_timestamp= rgi->last_master_timestamp; + set_if_bigger(last_master_timestamp, rgi->last_master_timestamp); } else { @@ -1041,6 +1041,7 @@ void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos, if (log_pos) // not 3.23 binlogs (no log_pos there) and not Stop_log_event group_master_log_pos= log_pos; } + set_if_bigger(slave_timestamp, rgi->last_master_timestamp); /* If the slave does not support transactions and replicates a transaction, diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index d20b0eb2ab4..9097e032de5 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -251,7 +251,6 @@ class Relay_log_info : public Slave_reporting_capability */ bool sql_force_rotate_relay; - my_time_t last_master_timestamp; /* The SQL driver thread sets this true while it is waiting at the end of the relay log for more events to arrive. SHOW SLAVE STATUS uses this to report @@ -259,6 +258,19 @@ class Relay_log_info : public Slave_reporting_capability */ bool sql_thread_caught_up; + /* Last executed timestamp */ + my_time_t last_master_timestamp; + /* + Latest when + exec_time read from the master (by io_thread). + 0 if there has been no new update events since the slave started. + */ + time_t newest_master_timestamp; + /* + When + exec_time of the last committed event on the slave. + In case of delayed slave and slave_timestamp is not set + then set to when + exec_time -1 of the first seen event. + */ + time_t slave_timestamp; void clear_until_condition(); /** Reset the delay. @@ -395,7 +407,7 @@ class Relay_log_info : public Slave_reporting_capability /* Invalidate cached until_log_name and group_relay_log_name comparison - result. Should be called after any update of group_realy_log_name if + result. Should be called after any update of group_relay_log_name if there chances that sql_thread is running. */ inline void notify_group_relay_log_name_update() diff --git a/sql/slave.cc b/sql/slave.cc index 4d8b475aca6..61e2d0d731b 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -172,7 +172,7 @@ static int queue_event(Master_info *mi,const uchar *buf, ulong event_len); static int terminate_slave_thread(THD *, mysql_mutex_t *, mysql_cond_t *, volatile uint *, bool); static bool check_io_slave_killed(Master_info *mi, const char *info); -static bool send_show_master_info_data(THD *, Master_info *, bool, String *); + /* Function to set the slave's max_allowed_packet based on the value of slave_max_allowed_packet. @@ -1477,40 +1477,6 @@ bool net_request_file(NET* net, const char* fname) #endif /* HAVE_REPLICATION */ -bool Sql_cmd_show_slave_status::execute(THD *thd) -{ -#ifndef HAVE_REPLICATION - my_ok(thd); - return false; -#else - DBUG_ENTER("Sql_cmd_show_slave_status::execute"); - bool res= true; - - /* Accept one of two privileges */ - if (check_global_access(thd, PRIV_STMT_SHOW_SLAVE_STATUS)) - goto error; - if (is_show_all_slaves_stat()) - { - mysql_mutex_lock(&LOCK_active_mi); - res= show_all_master_info(thd); - mysql_mutex_unlock(&LOCK_active_mi); - } - else - { - LEX_MASTER_INFO *lex_mi= &thd->lex->mi; - Master_info *mi; - if ((mi= get_master_info(&lex_mi->connection_name, - Sql_condition::WARN_LEVEL_ERROR))) - { - res= show_master_info(thd, mi, 0); - mi->release(); - } - } -error: - DBUG_RETURN(res); -#endif -} - int init_strvar_from_file(char *var, int max_size, IO_CACHE *f, const char *default_val) { @@ -2874,287 +2840,6 @@ int register_slave_on_master(MYSQL* mysql, Master_info *mi, } -/** - Execute a SHOW SLAVE STATUS statement. - - @param thd Pointer to THD object for the client thread executing the - statement. - - @param mi Pointer to Master_info object for the IO thread. - - @retval FALSE success - @retval TRUE failure -*/ - -bool show_master_info(THD *thd, Master_info *mi, bool full) -{ - DBUG_ENTER("show_master_info"); - String gtid_pos; - List<Item> field_list; - - if (full && rpl_global_gtid_slave_state->tostring(>id_pos, NULL, 0)) - DBUG_RETURN(TRUE); - show_master_info_get_fields(thd, &field_list, full, gtid_pos.length()); - if (thd->protocol->send_result_set_metadata(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(TRUE); - if (send_show_master_info_data(thd, mi, full, >id_pos)) - DBUG_RETURN(TRUE); - my_eof(thd); - DBUG_RETURN(FALSE); -} - -void show_master_info_get_fields(THD *thd, List<Item> *field_list, - bool full, size_t gtid_pos_length) -{ - Master_info *mi; - MEM_ROOT *mem_root= thd->mem_root; - DBUG_ENTER("show_master_info_get_fields"); - - if (full) - { - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Connection_name", - MAX_CONNECTION_NAME), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Slave_SQL_State", 30), - mem_root); - } - - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Slave_IO_State", 30), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Master_Host", sizeof(mi->host)), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Master_User", sizeof(mi->user)), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Master_Port", 7, MYSQL_TYPE_LONG), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Connect_Retry", 10, - MYSQL_TYPE_LONG), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Master_Log_File", FN_REFLEN), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Read_Master_Log_Pos", 10, - MYSQL_TYPE_LONGLONG), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Relay_Log_File", FN_REFLEN), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Relay_Log_Pos", 10, - MYSQL_TYPE_LONGLONG), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Relay_Master_Log_File", - FN_REFLEN), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Slave_IO_Running", 3), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Slave_SQL_Running", 3), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Replicate_Do_DB", 20), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Replicate_Ignore_DB", 20), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Replicate_Do_Table", 20), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Replicate_Ignore_Table", 23), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Replicate_Wild_Do_Table", 24), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Replicate_Wild_Ignore_Table", - 28), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Last_Errno", 4, MYSQL_TYPE_LONG), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Last_Error", 20), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Skip_Counter", 10, - MYSQL_TYPE_LONG), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Exec_Master_Log_Pos", 10, - MYSQL_TYPE_LONGLONG), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Relay_Log_Space", 10, - MYSQL_TYPE_LONGLONG), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Until_Condition", 6), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Until_Log_File", FN_REFLEN), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Until_Log_Pos", 10, - MYSQL_TYPE_LONGLONG), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Master_SSL_Allowed", 7), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Master_SSL_CA_File", - sizeof(mi->ssl_ca)), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Master_SSL_CA_Path", - sizeof(mi->ssl_capath)), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Master_SSL_Cert", - sizeof(mi->ssl_cert)), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Master_SSL_Cipher", - sizeof(mi->ssl_cipher)), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Master_SSL_Key", - sizeof(mi->ssl_key)), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Seconds_Behind_Master", 10, - MYSQL_TYPE_LONGLONG), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Master_SSL_Verify_Server_Cert", - 3), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Last_IO_Errno", 4, - MYSQL_TYPE_LONG), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Last_IO_Error", 20), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Last_SQL_Errno", 4, - MYSQL_TYPE_LONG), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Last_SQL_Error", 20), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Replicate_Ignore_Server_Ids", - FN_REFLEN), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Master_Server_Id", sizeof(ulong), - MYSQL_TYPE_LONG), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Master_SSL_Crl", - sizeof(mi->ssl_crl)), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Master_SSL_Crlpath", - sizeof(mi->ssl_crlpath)), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Using_Gtid", - sizeof("Current_Pos")-1), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Gtid_IO_Pos", 30), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Replicate_Do_Domain_Ids", - FN_REFLEN), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Replicate_Ignore_Domain_Ids", - FN_REFLEN), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Parallel_Mode", - sizeof("conservative")-1), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "SQL_Delay", 10, - MYSQL_TYPE_LONG)); - field_list->push_back(new (mem_root) - Item_return_int(thd, "SQL_Remaining_Delay", 8, - MYSQL_TYPE_LONG)); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Slave_SQL_Running_State", - 20)); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Slave_DDL_Groups", 20, - MYSQL_TYPE_LONGLONG), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Slave_Non_Transactional_Groups", 20, - MYSQL_TYPE_LONGLONG), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Slave_Transactional_Groups", 20, - MYSQL_TYPE_LONGLONG), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Replicate_Rewrite_DB", 23), - mem_root); - - /* - Note, we must never, _ever_, add extra rows to this output of SHOW SLAVE - STATUS, except here at the end before the extra rows of SHOW ALL SLAVES - STATUS. Otherwise, we break backwards compatibility with applications or - scripts that parse the output! - - This also means that we cannot add _any_ new rows in a GA version if a - different row was already added in a later MariaDB version, as this would - make it impossible to merge the change up while preserving the order of - rows. - */ - - if (full) - { - field_list->push_back(new (mem_root) - Item_return_int(thd, "Retried_transactions", 10, - MYSQL_TYPE_LONG), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Max_relay_log_size", 10, - MYSQL_TYPE_LONGLONG), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Executed_log_entries", 10, - MYSQL_TYPE_LONG), - mem_root); - field_list->push_back(new (mem_root) - Item_return_int(thd, "Slave_received_heartbeats", 10, - MYSQL_TYPE_LONG), - mem_root); - field_list->push_back(new (mem_root) - Item_float(thd, "Slave_heartbeat_period", 0.0, 3, 10), - mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Gtid_Slave_Pos", - (uint)gtid_pos_length), - mem_root); - } - DBUG_VOID_RETURN; -} - /* Text for Slave_IO_Running */ static const LEX_CSTRING slave_running[]= { @@ -3171,146 +2856,170 @@ static const LEX_CSTRING msg_ignored= { STRING_WITH_LEN("Ignored") }; #endif -static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, - String *gtid_pos) +inline void store_string_or_null(Field **field, const char *str) +{ + if (str) + (*field)->store(str, strlen(str), &my_charset_bin); + else + (*field)->set_null(); +} + +inline void store_string(Field **field, const char *str) +{ + (*field)->store(str, strlen(str), &my_charset_bin); +} + +inline void store_string(Field **field, const LEX_CSTRING *str) { - DBUG_ENTER("send_show_master_info_data"); + (*field)->store(str->str, str->length, &my_charset_bin); +} + - if (mi->host[0]) +void store_list(Field **field, I_List<i_string>* str_list) +{ + char buf[256]; + String tmp(buf, sizeof(buf), &my_charset_bin); + uint32 len; + I_List_iterator<i_string> it(*str_list); + i_string* s; + + tmp.length(0); + while ((s=it++)) { - DBUG_PRINT("info",("host is set: '%s'", mi->host)); - String *packet= &thd->packet; - Protocol *protocol= thd->protocol; - Rpl_filter *rpl_filter= mi->rpl_filter; - StringBuffer<256> tmp; - const char *msg; + tmp.append(s->ptr, strlen(s->ptr)); + tmp.append(','); + } + if ((len= tmp.length())) + len--; // Remove last ',' + (*field)->store((char*) tmp.ptr(), len, tmp.charset()); +} - protocol->prepare_for_resend(); - /* - slave_running can be accessed without run_lock but not other - non-volotile members like mi->io_thd, which is guarded by the mutex. - */ - if (full) - protocol->store(mi->connection_name.str, mi->connection_name.length, - &my_charset_bin); - mysql_mutex_lock(&mi->run_lock); - if (full) - { - /* - Show what the sql driver replication thread is doing - This is only meaningful if there is only one slave thread. - */ - msg= (mi->rli.sql_driver_thd ? - mi->rli.sql_driver_thd->get_proc_info() : ""); - protocol->store_string_or_null(msg, &my_charset_bin); - } - msg= mi->io_thd ? mi->io_thd->get_proc_info() : ""; - protocol->store_string_or_null(msg, &my_charset_bin); +/* + Store master info for information_schema_tables +*/ - mysql_mutex_unlock(&mi->run_lock); +void store_master_info(THD *thd, Master_info *mi, TABLE *table, + String *gtid_pos) +{ + Field **field= table->field; + const char *msg; + Rpl_filter *rpl_filter= mi->rpl_filter; + StringBuffer<256> tmp; + time_t master_timestamp, slave_timestamp; + DBUG_ENTER("store_master_info_data"); - mysql_mutex_lock(&mi->data_lock); - mysql_mutex_lock(&mi->rli.data_lock); - /* err_lock is to protect mi->last_error() */ - mysql_mutex_lock(&mi->err_lock); - /* err_lock is to protect mi->rli.last_error() */ - mysql_mutex_lock(&mi->rli.err_lock); - - DBUG_EXECUTE_IF("hold_sss_with_err_lock", { - DBUG_ASSERT(!debug_sync_set_action( - thd, STRING_WITH_LEN("now SIGNAL sss_got_err_lock " - "WAIT_FOR sss_continue"))); + table->clear_null_bits(); + + (*field++)->store(mi->connection_name.str, mi->connection_name.length, + &my_charset_bin); + + mysql_mutex_lock(&mi->run_lock); + msg= (mi->rli.sql_driver_thd ? + mi->rli.sql_driver_thd->get_proc_info() : ""); + store_string_or_null(field++, msg); + msg= mi->io_thd ? mi->io_thd->get_proc_info() : ""; + store_string_or_null(field++, msg); + mysql_mutex_unlock(&mi->run_lock); + + mysql_mutex_lock(&mi->data_lock); + mysql_mutex_lock(&mi->rli.data_lock); + /* err_lock is to protect mi->last_error() */ + mysql_mutex_lock(&mi->err_lock); + /* err_lock is to protect mi->rli.last_error() */ + mysql_mutex_lock(&mi->rli.err_lock); + + DBUG_EXECUTE_IF("hold_sss_with_err_lock", { + DBUG_ASSERT(!debug_sync_set_action(thd, + STRING_WITH_LEN("now SIGNAL sss_got_err_lock " + "WAIT_FOR sss_continue"))); DBUG_SET("-d,hold_sss_with_err_lock"); }); - protocol->store_string_or_null(mi->host, &my_charset_bin); - protocol->store_string_or_null(mi->user, &my_charset_bin); - protocol->store((uint32) mi->port); - protocol->store((uint32) mi->connect_retry); - protocol->store(mi->master_log_name, strlen(mi->master_log_name), + store_string_or_null(field++, mi->host); + store_string_or_null(field++, mi->user); + (*field++)->store((uint32) mi->port); + (*field++)->store((uint32) mi->connect_retry); + (*field++)->store(mi->master_log_name, strlen(mi->master_log_name), &my_charset_bin); - protocol->store((ulonglong) mi->master_log_pos); - msg= (mi->rli.group_relay_log_name + - dirname_length(mi->rli.group_relay_log_name)); - protocol->store(msg, strlen(msg), &my_charset_bin); - protocol->store((ulonglong) mi->rli.group_relay_log_pos); - protocol->store(mi->rli.group_master_log_name, - strlen(mi->rli.group_master_log_name), - &my_charset_bin); - protocol->store(&slave_running[mi->slave_running], &my_charset_bin); - protocol->store(mi->rli.slave_running ? &msg_yes : &msg_no, &my_charset_bin); - protocol->store(rpl_filter->get_do_db()); - protocol->store(rpl_filter->get_ignore_db()); - - rpl_filter->get_do_table(&tmp); - protocol->store(&tmp); - rpl_filter->get_ignore_table(&tmp); - protocol->store(&tmp); - rpl_filter->get_wild_do_table(&tmp); - protocol->store(&tmp); - rpl_filter->get_wild_ignore_table(&tmp); - protocol->store(&tmp); - - protocol->store(mi->rli.last_error().number); - protocol->store_string_or_null(mi->rli.last_error().message, - &my_charset_bin); - protocol->store((uint32) mi->rli.slave_skip_counter); - protocol->store((ulonglong) mi->rli.group_master_log_pos); - protocol->store((ulonglong) mi->rli.log_space_total); - - msg= (mi->rli.until_condition==Relay_log_info::UNTIL_NONE ? "None" : - (mi->rli.until_condition==Relay_log_info::UNTIL_MASTER_POS? "Master": - (mi->rli.until_condition==Relay_log_info::UNTIL_RELAY_POS? "Relay": - "Gtid"))); - protocol->store(msg, strlen(msg), &my_charset_bin); - protocol->store_string_or_null(mi->rli.until_log_name, &my_charset_bin); - protocol->store((ulonglong) mi->rli.until_log_pos); + (*field++)->store((ulonglong) mi->master_log_pos, true); + msg= (mi->rli.group_relay_log_name + + dirname_length(mi->rli.group_relay_log_name)); + store_string(field++, msg); + (*field++)->store((ulonglong) mi->rli.group_relay_log_pos, true); + store_string(field++, mi->rli.group_master_log_name); + store_string(field++, &slave_running[mi->slave_running]); + store_string(field++, mi->rli.slave_running ? &msg_yes : &msg_no); + store_list(field++, rpl_filter->get_do_db()); + store_list(field++, rpl_filter->get_ignore_db()); + + rpl_filter->get_do_table(&tmp); + (*field++)->store(tmp.ptr(), tmp.length(), &my_charset_bin); + rpl_filter->get_ignore_table(&tmp); + (*field++)->store(tmp.ptr(), tmp.length(), &my_charset_bin); + rpl_filter->get_wild_do_table(&tmp); + (*field++)->store(tmp.ptr(), tmp.length(), &my_charset_bin); + rpl_filter->get_wild_ignore_table(&tmp); + (*field++)->store(tmp.ptr(), tmp.length(), &my_charset_bin); + + (*field++)->store(mi->rli.last_error().number); + store_string_or_null(field++, mi->rli.last_error().message); + (*field++)->store((uint32) mi->rli.slave_skip_counter); + (*field++)->store((ulonglong) mi->rli.group_master_log_pos, true); + (*field++)->store((ulonglong) mi->rli.log_space_total, true); + + msg= (mi->rli.until_condition==Relay_log_info::UNTIL_NONE ? "None" : + (mi->rli.until_condition==Relay_log_info::UNTIL_MASTER_POS? "Master": + (mi->rli.until_condition==Relay_log_info::UNTIL_RELAY_POS? "Relay": + "Gtid"))); + (*field++)->store(msg, strlen(msg), &my_charset_bin); + store_string_or_null(field++, mi->rli.until_log_name); + (*field++)->store((ulonglong) mi->rli.until_log_pos, true); #ifdef HAVE_OPENSSL - protocol->store(mi->ssl ? &msg_yes : &msg_no, &my_charset_bin); + (*field++)->store(mi->ssl ? &msg_yes : &msg_no, &my_charset_bin); #else - protocol->store(mi->ssl ? &msg_ignored: &msg_no, &my_charset_bin); + (*field++)->store(mi->ssl ? &msg_ignored: &msg_no, &my_charset_bin); #endif - protocol->store_string_or_null(mi->ssl_ca, &my_charset_bin); - protocol->store_string_or_null(mi->ssl_capath, &my_charset_bin); - protocol->store_string_or_null(mi->ssl_cert, &my_charset_bin); - protocol->store_string_or_null(mi->ssl_cipher, &my_charset_bin); - protocol->store_string_or_null(mi->ssl_key, &my_charset_bin); + store_string_or_null(field++, mi->ssl_ca); + store_string_or_null(field++, mi->ssl_capath); + store_string_or_null(field++, mi->ssl_cert); + store_string_or_null(field++, mi->ssl_cipher); + store_string_or_null(field++, mi->ssl_key); - /* - Seconds_Behind_Master: if SQL thread is running and I/O thread is - connected, we can compute it otherwise show NULL (i.e. unknown). - */ - if ((mi->slave_running == MYSQL_SLAVE_RUN_READING) && - mi->rli.slave_running) - { - long time_diff; - bool idle; - time_t stamp= mi->rli.last_master_timestamp; + /* + Seconds_Behind_Master: if SQL thread is running and I/O thread is + connected, we can compute it otherwise show NULL (i.e. unknown). + */ + if ((mi->slave_running == MYSQL_SLAVE_RUN_READING) && + mi->rli.slave_running) + { + long time_diff; + bool idle; + time_t stamp= mi->rli.last_master_timestamp; - if (!stamp) - idle= true; - else - { - idle= mi->rli.sql_thread_caught_up; + if (!stamp) + idle= true; + else + { + idle= mi->rli.sql_thread_caught_up; - /* - The idleness of the SQL thread is needed for the parallel slave - because events can be ignored before distribution to a worker thread. - That is, Seconds_Behind_Master should still be calculated and visible - while the slave is processing ignored events, such as those skipped - due to slave_skip_counter. - */ - if (mi->using_parallel() && idle && - !rpl_parallel::workers_idle(&mi->rli)) - idle= false; - } - if (idle) - time_diff= 0; - else - { - time_diff= ((long)(time(0) - stamp) - mi->clock_diff_with_master); + /* + The idleness of the SQL thread is needed for the parallel slave + because events can be ignored before distribution to a worker thread. + That is, Seconds_Behind_Master should still be calculated and visible + while the slave is processing ignored events, such as those skipped + due to slave_skip_counter. + */ + if (mi->using_parallel() && idle && + !rpl_parallel::workers_idle(&mi->rli)) + idle= false; + } + if (idle) + time_diff= 0; + else + { + time_diff= ((long)(time(0) - stamp) - mi->clock_diff_with_master); /* Apparently on some systems time_diff can be <0. Here are possible reasons related to MySQL: @@ -3331,102 +3040,121 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, last_master_timestamp == 0 (an "impossible" timestamp 1970) is a special marker to say "consider we have caught up". */ - if (time_diff < 0) - time_diff= 0; - } - protocol->store((longlong)time_diff); - } - else - { - protocol->store_null(); + if (time_diff < 0) + time_diff= 0; } - protocol->store(mi->ssl_verify_server_cert? &msg_yes : &msg_no, + (*field++)->store((longlong)time_diff, true); + } + else + (*field++)->set_null(); + + (*field++)->store(mi->ssl_verify_server_cert? &msg_yes : &msg_no, &my_charset_bin); - // Last_IO_Errno - protocol->store(mi->last_error().number); - // Last_IO_Error - protocol->store_string_or_null(mi->last_error().message, &my_charset_bin); - // Last_SQL_Errno - protocol->store(mi->rli.last_error().number); - // Last_SQL_Error - protocol->store_string_or_null(mi->rli.last_error().message, - &my_charset_bin); - // Replicate_Ignore_Server_Ids - prot_store_ids(thd, &mi->ignore_server_ids); - // Master_Server_id - protocol->store((uint32) mi->master_id); - // SQL_Delay - // Master_Ssl_Crl - protocol->store_string_or_null(mi->ssl_crl, &my_charset_bin); - // Master_Ssl_Crlpath - protocol->store_string_or_null(mi->ssl_crlpath, &my_charset_bin); - // Using_Gtid - protocol->store_string_or_null(mi->using_gtid_astext(mi->using_gtid), - &my_charset_bin); - // Gtid_IO_Pos - { - mi->gtid_current_pos.to_string(&tmp); - protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin); - } + // Last_IO_Errno + (*field++)->store(mi->last_error().number); + // Last_IO_Error + store_string_or_null(field++, mi->last_error().message); + // Last_SQL_Errno + (*field++)->store(mi->rli.last_error().number); + // Last_SQL_Error + store_string_or_null(field++, mi->rli.last_error().message); + // Replicate_Ignore_Server_Ids + field_store_ids((*field++), &mi->ignore_server_ids); + // Master_Server_id + (*field++)->store((uint32) mi->master_id); + // SQL_Delay + // Master_Ssl_Crl + store_string_or_null(field++, mi->ssl_crl); + // Master_Ssl_Crlpath + store_string_or_null(field++, mi->ssl_crlpath); + // Using_Gtid + store_string_or_null(field++, mi->using_gtid_astext(mi->using_gtid)); + // Gtid_IO_Pos + { + mi->gtid_current_pos.to_string(&tmp); + (*field++)->store(tmp.ptr(), tmp.length(), &my_charset_bin); + } - // Replicate_Do_Domain_Ids & Replicate_Ignore_Domain_Ids - mi->domain_id_filter.store_ids(thd); + // Replicate_Do_Domain_Ids & Replicate_Ignore_Domain_Ids + mi->domain_id_filter.store_ids(&field); - // Parallel_Mode - { - const char *mode_name= get_type(&slave_parallel_mode_typelib, - mi->parallel_mode); - protocol->store(mode_name, strlen(mode_name), &my_charset_bin); - } + // Parallel_Mode + { + const char *mode_name= get_type(&slave_parallel_mode_typelib, + mi->parallel_mode); + (*field++)->store(mode_name, strlen(mode_name), &my_charset_bin); + } + + (*field++)->store((uint32) mi->rli.get_sql_delay()); + // SQL_Remaining_Delay + // THD::proc_info is not protected by any lock, so we read it once + // to ensure that we use the same value throughout this function. + const char *slave_sql_running_state= + mi->rli.sql_driver_thd ? mi->rli.sql_driver_thd->proc_info : ""; + if (slave_sql_running_state == stage_sql_thd_waiting_until_delay.m_name) + { + time_t t= my_time(0), sql_delay_end= mi->rli.get_sql_delay_end(); + (*field++)->store((uint32)(t < sql_delay_end ? sql_delay_end - t : 0)); + } + else + (*field++)->set_null(); + // Slave_SQL_Running_State + store_string_or_null(field++, slave_sql_running_state); + + (*field++)->store(mi->total_ddl_groups, true); + (*field++)->store(mi->total_non_trans_groups, true); + (*field++)->store(mi->total_trans_groups, true); + rpl_filter->get_rewrite_db(&tmp); + (*field++)->store(tmp.ptr(), tmp.length(), &my_charset_bin); + + (*field++)->store((uint32) mi->rli.retried_trans, true); + (*field++)->store((ulonglong) mi->rli.max_relay_log_size, true); + (*field++)->store(mi->rli.executed_entries, true); + (*field++)->store((uint) mi->received_heartbeats, true); + (*field++)->store((double) mi->heartbeat_period); + (*field++)->store(gtid_pos->ptr(), gtid_pos->length(), &my_charset_bin); - protocol->store((uint32) mi->rli.get_sql_delay()); - // SQL_Remaining_Delay - // THD::proc_info is not protected by any lock, so we read it once - // to ensure that we use the same value throughout this function. - const char *slave_sql_running_state= - mi->rli.sql_driver_thd ? mi->rli.sql_driver_thd->proc_info : ""; - if (slave_sql_running_state == stage_sql_thd_waiting_until_delay.m_name) + /* + newest_master_timestamp is a guard for both newest_master_timestamp and + slave_timestamp. This is needed as newest_master_timestamp is only + updated when a commit is read while slave_timestamp is updated at + first event read from the relay log, which can happen before + newest_master_timestamp is read. + The below code also protects against a concurrent reset_slave(). + */ + if ((master_timestamp= mi->rli.newest_master_timestamp)) + { + (*field++)->store_timestamp((my_time_t) master_timestamp, 0); + if ((slave_timestamp= mi->rli.slave_timestamp)) { - time_t t= my_time(0), sql_delay_end= mi->rli.get_sql_delay_end(); - protocol->store((uint32)(t < sql_delay_end ? sql_delay_end - t : 0)); + (*field++)->store_timestamp((my_time_t) slave_timestamp, 0); + (*field++)->store((uint) (master_timestamp - slave_timestamp), true); } else - protocol->store_null(); - // Slave_SQL_Running_State - protocol->store_string_or_null(slave_sql_running_state, &my_charset_bin); - - protocol->store(mi->total_ddl_groups); - protocol->store(mi->total_non_trans_groups); - protocol->store(mi->total_trans_groups); - protocol->store(rpl_filter->get_rewrite_db()); - - if (full) { - protocol->store((uint32) mi->rli.retried_trans); - protocol->store((ulonglong) mi->rli.max_relay_log_size); - protocol->store(mi->rli.executed_entries); - protocol->store((uint32) mi->received_heartbeats); - protocol->store_double(mi->heartbeat_period, 3); - protocol->store(gtid_pos->ptr(), gtid_pos->length(), &my_charset_bin); + (*field++)->set_null(); + (*field++)->set_null(); } - - mysql_mutex_unlock(&mi->rli.err_lock); - mysql_mutex_unlock(&mi->err_lock); - mysql_mutex_unlock(&mi->rli.data_lock); - mysql_mutex_unlock(&mi->data_lock); - - if (my_net_write(&thd->net, (uchar*) thd->packet.ptr(), packet->length())) - DBUG_RETURN(TRUE); } - DBUG_RETURN(FALSE); + else + { + (*field++)->set_null(); + (*field++)->set_null(); + (*field++)->set_null(); + } + mysql_mutex_unlock(&mi->rli.err_lock); + mysql_mutex_unlock(&mi->err_lock); + mysql_mutex_unlock(&mi->rli.data_lock); + mysql_mutex_unlock(&mi->data_lock); + DBUG_VOID_RETURN; } /* Used to sort connections by name */ -static int cmp_mi_by_name(const Master_info **arg1, - const Master_info **arg2) +int cmp_mi_by_name(const Master_info **arg1, + const Master_info **arg2) { return Lex_ident_master_info::charset_info()->strnncoll( (*arg1)->connection_name, @@ -3434,72 +3162,6 @@ static int cmp_mi_by_name(const Master_info **arg1, } -/** - Execute a SHOW FULL SLAVE STATUS statement. - - @param thd Pointer to THD object for the client thread executing the - statement. - - Elements are sorted according to the original connection_name. - - @retval FALSE success - @retval TRUE failure - - @note - master_info_index is protected by LOCK_active_mi. -*/ - -bool show_all_master_info(THD* thd) -{ - uint i, elements; - String gtid_pos; - Master_info **tmp; - List<Item> field_list; - DBUG_ENTER("show_all_master_info"); - mysql_mutex_assert_owner(&LOCK_active_mi); - - gtid_pos.length(0); - if (rpl_append_gtid_state(>id_pos, true)) - { - my_error(ER_OUT_OF_RESOURCES, MYF(0)); - DBUG_RETURN(TRUE); - } - - show_master_info_get_fields(thd, &field_list, 1, gtid_pos.length()); - if (thd->protocol->send_result_set_metadata(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(TRUE); - - if (!master_info_index || - !(elements= master_info_index->master_info_hash.records)) - goto end; - - /* - Sort lines to get them into a predicted order - (needed for test cases and to not confuse users) - */ - if (!(tmp= (Master_info**) thd->alloc(sizeof(Master_info*) * elements))) - DBUG_RETURN(TRUE); - - for (i= 0; i < elements; i++) - { - tmp[i]= (Master_info *) my_hash_element(&master_info_index-> - master_info_hash, i); - } - my_qsort(tmp, elements, sizeof(Master_info*), (qsort_cmp) cmp_mi_by_name); - - for (i= 0; i < elements; i++) - { - if (send_show_master_info_data(thd, tmp[i], 1, >id_pos)) - DBUG_RETURN(TRUE); - } - -end: - my_eof(thd); - DBUG_RETURN(FALSE); -} - - void set_slave_thread_options(THD* thd) { DBUG_ENTER("set_slave_thread_options"); @@ -4353,13 +4015,32 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli, the user might be surprised to see a claim that the slave is up to date long before those queued events are actually executed. */ - if ((!rli->mi->using_parallel()) && - event_can_update_last_master_timestamp(ev)) + if (event_can_update_last_master_timestamp(ev)) { - rli->last_master_timestamp= ev->when + ev->exec_time; - rli->sql_thread_caught_up= false; - } + if ((!rli->mi->using_parallel())) + { + rli->last_master_timestamp= ev->when + (time_t) ev->exec_time; + rli->sql_thread_caught_up= false; + /* + For slave_timestamp, we update slave_timestamp at the end of the + transaction, so we follow the pattern of the parallel slave and + cache the timestamp of the last-event of the transaction within the + RGI, and then use it to update slave_timestamp at commit-time. + */ + if (Log_event::is_group_event(typ)) + serial_rgi->last_master_timestamp= rli->last_master_timestamp; + } + + if (unlikely(!rli->slave_timestamp) && Log_event::is_group_event(typ)) + { + /* + First event for this slave. Assume that all the slave was up to date + with the master just before the current event. + */ + rli->slave_timestamp= (time_t) ev->when + (time_t) ev->exec_time-1; + } + } /* This tests if the position of the beginning of the current event hits the UNTIL barrier. @@ -7027,6 +6708,23 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len) } else { + /* + replay_log.description_event_for_exec can be null if the slave thread + is getting killed + */ + if (LOG_EVENT_IS_QUERY((Log_event_type) buf[EVENT_TYPE_OFFSET]) || + LOG_EVENT_IS_LOAD_DATA((Log_event_type) buf[EVENT_TYPE_OFFSET])) + { + time_t exec_time= query_event_get_time(buf, rli->relay_log. + description_event_for_queue); + set_if_bigger(rli->newest_master_timestamp, exec_time); + } + else if (((Log_event_type) buf[EVENT_TYPE_OFFSET]) == XID_EVENT) + { + /* XID_EVENT is used for COMMIT */ + time_t commit_time= uint4korr(buf); + set_if_bigger(rli->newest_master_timestamp, commit_time); + } if (mi->do_accept_own_server_id) { int2store(const_cast<uchar*>(buf + FLAGS_OFFSET), diff --git a/sql/slave.h b/sql/slave.h index 02de9135c2a..5dd7d6e262b 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -279,7 +279,9 @@ void slave_background_kill_request(THD *to_kill); void slave_background_gtid_pos_create_request (rpl_slave_state::gtid_pos_table *table_entry); void slave_background_gtid_pending_delete_request(void); - +void store_master_info(THD *thd, Master_info *mi, TABLE *table, + String *gtid_pos); +int cmp_mi_by_name(const Master_info **arg1, const Master_info **arg2); extern Master_info *active_mi; /* active_mi for multi-master */ extern Master_info *default_master_info; /* To replace active_mi */ extern Master_info_index *master_info_index; diff --git a/sql/sql_class.h b/sql/sql_class.h index 2d671139a6c..05c9c4e8012 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3168,6 +3168,7 @@ class THD: public THD_count, /* this must be first */ ulonglong start_utime, utime_after_lock, utime_after_query; /* This can be used by handlers to send signals to the SQL level */ ulonglong replication_flags; + my_time_t orig_exec_time; // Exec time for last read binlog event // Process indicator struct { /* diff --git a/sql/sql_cmd.h b/sql/sql_cmd.h index bedd7e118f0..c9681c25d9f 100644 --- a/sql/sql_cmd.h +++ b/sql/sql_cmd.h @@ -397,26 +397,6 @@ class Sql_cmd_dml : public Sql_cmd }; -class Sql_cmd_show_slave_status: public Sql_cmd -{ -protected: - bool show_all_slaves_status; -public: - Sql_cmd_show_slave_status() - :show_all_slaves_status(false) - {} - - Sql_cmd_show_slave_status(bool status_all) - :show_all_slaves_status(status_all) - {} - - enum_sql_command sql_command_code() const { return SQLCOM_SHOW_SLAVE_STAT; } - - bool execute(THD *thd); - bool is_show_all_slaves_stat() { return show_all_slaves_status; } -}; - - class Sql_cmd_create_table_like: public Sql_cmd, public Storage_engine_name { diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 93756d8d80d..0b1f3cf8e15 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -499,6 +499,8 @@ struct LEX_MASTER_INFO int sql_delay; bool is_demotion_opt; bool is_until_before_gtids; + bool show_all_slaves; + /* Enum is used for making it possible to detect if the user changed variable or if it should be left at old value diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 507a068b731..01fb010e974 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3916,6 +3916,7 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt) case SQLCOM_SHOW_COLLATIONS: case SQLCOM_SHOW_STORAGE_ENGINES: case SQLCOM_SHOW_PROFILE: + case SQLCOM_SHOW_SLAVE_STAT: case SQLCOM_SELECT: { #ifdef WITH_WSREP @@ -5829,7 +5830,6 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt) DBUG_ASSERT(first_table == all_tables && first_table != 0); /* fall through */ case SQLCOM_ALTER_SEQUENCE: - case SQLCOM_SHOW_SLAVE_STAT: case SQLCOM_SIGNAL: case SQLCOM_RESIGNAL: case SQLCOM_GET_DIAGNOSTICS: diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 6261ba46cac..4a0f55562d7 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1861,30 +1861,6 @@ static int mysql_test_show_grants(Prepared_statement *stmt) #ifndef EMBEDDED_LIBRARY -/** - Validate and prepare for execution SHOW SLAVE STATUS statement. - - @param stmt prepared statement - - @retval - FALSE success - @retval - TRUE error, error message is set in THD -*/ - -static int mysql_test_show_slave_status(Prepared_statement *stmt, - bool show_all_slaves_stat) -{ - DBUG_ENTER("mysql_test_show_slave_status"); - THD *thd= stmt->thd; - List<Item> fields; - - show_master_info_get_fields(thd, &fields, show_all_slaves_stat, 0); - - DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields)); -} - - /** Validate and prepare for execution SHOW BINLOG STATUS statement. @@ -2309,6 +2285,7 @@ static bool check_prepared_statement(Prepared_statement *stmt) case SQLCOM_SHOW_STATUS_FUNC: case SQLCOM_SHOW_STATUS_PACKAGE: case SQLCOM_SHOW_STATUS_PACKAGE_BODY: + case SQLCOM_SHOW_SLAVE_STAT: case SQLCOM_SELECT: res= mysql_test_select(stmt, tables); if (res == 2) @@ -2345,21 +2322,6 @@ static bool check_prepared_statement(Prepared_statement *stmt) break; #endif /* NO_EMBEDDED_ACCESS_CHECKS */ #ifndef EMBEDDED_LIBRARY - case SQLCOM_SHOW_SLAVE_STAT: - { - DBUG_ASSERT(thd->lex->m_sql_cmd); - Sql_cmd_show_slave_status *cmd; - cmd= dynamic_cast<Sql_cmd_show_slave_status*>(thd->lex->m_sql_cmd); - DBUG_ASSERT(cmd); - if ((res= mysql_test_show_slave_status(stmt, - cmd->is_show_all_slaves_stat())) - == 2) - { - /* Statement and field info has already been sent */ - DBUG_RETURN(FALSE); - } - break; - } case SQLCOM_SHOW_BINLOG_STAT: if ((res= mysql_test_show_binlog_status(stmt)) == 2) { diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 8ca252c37c6..ba8266d46e9 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -3700,6 +3700,8 @@ int reset_slave(THD *thd, Master_info* mi) mi->rli.clear_until_condition(); mi->rli.clear_sql_delay(); mi->rli.slave_skip_counter= 0; + mi->rli.newest_master_timestamp= 0; + mi->rli.slave_timestamp= 0; // close master_info_file, relay_log_info_file, set mi->inited=rli->inited=0 end_master_info(mi); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index aa494b90d36..d7d798eb36f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -47,6 +47,8 @@ #include "sql_derived.h" #include "sql_statistics.h" #include "sql_connect.h" +#include "sql_repl.h" // rpl_load_gtid_state +#include "rpl_mi.h" // master_info_index #include "authors.h" #include "contributors.h" #include "sql_partition.h" @@ -8836,6 +8838,90 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) } +#ifdef HAVE_REPLICATION +int fill_slave_status(THD *thd, TABLE_LIST *tables, COND *cond) +{ + String gtid_pos; + Master_info **tmp; + TABLE *table= tables->table; + uint elements, i; + bool single_slave= (thd->lex->sql_command == SQLCOM_SHOW_SLAVE_STAT && + !thd->lex->mi.show_all_slaves); + DBUG_ENTER("fill_slave_status"); + + if (check_global_access(thd, PRIV_STMT_SHOW_SLAVE_STATUS)) + DBUG_RETURN(TRUE); + + gtid_pos.length(0); + if (rpl_append_gtid_state(>id_pos, true)) + { + my_error(ER_OUT_OF_RESOURCES, MYF(0)); + DBUG_RETURN(TRUE); + } + + if (!master_info_index || + !(elements= master_info_index->master_info_hash.records)) + { + /* No registered slaves */ + return 0; + } + + /* + Sort lines to get them into a predicted order + (needed for test cases and to not confuse users) + */ + if (!(tmp= (Master_info**) thd->alloc(sizeof(Master_info*) * elements))) + goto error; + + if (single_slave) + { + LEX_MASTER_INFO *lex_mi= &thd->lex->mi; + Master_info *mi; + if ((mi= get_master_info(&lex_mi->connection_name, + Sql_condition::WARN_LEVEL_ERROR))) + { + bool res= 0; + if (mi->host[0]) + { + store_master_info(thd, mi, table, >id_pos); + res= schema_table_store_record(thd, table); + } + mi->release(); + if (res) + goto error; + } + } + else + { + mysql_mutex_lock(&LOCK_active_mi); + for (i= 0; i < elements; i++) + { + tmp[i]= (Master_info *) my_hash_element(&master_info_index-> + master_info_hash, i); + } + my_qsort(tmp, elements, sizeof(Master_info*), (qsort_cmp) cmp_mi_by_name); + + for (i= 0; i < elements; i++) + { + if (tmp[i]->host[0]) + { + store_master_info(thd, tmp[i], table, >id_pos); + if (schema_table_store_record(thd, table)) + { + mysql_mutex_unlock(&LOCK_active_mi); + goto error; + } + } + } + mysql_mutex_unlock(&LOCK_active_mi); + } + DBUG_RETURN(0); + +error: + DBUG_RETURN(1); +} +#endif + /* For old SHOW compatibility. It is used when old SHOW doesn't have generated column names @@ -8862,12 +8948,11 @@ static int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) LEX_CSTRING field_name= field_info->name(); Item_field *field= new (thd->mem_root) Item_field(thd, context, field_name); - if (field) - { - field->set_name(thd, field_info->old_name()); - if (add_item_to_list(thd, field)) - return 1; - } + if (!field) + return 1; + field->set_name(thd, field_info->old_name()); + if (add_item_to_list(thd, field)) + return 1; } } return 0; @@ -8922,14 +9007,14 @@ int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) buffer.append(')'); } Item_field *field= new (thd->mem_root) Item_field(thd, context, field_name); - if (add_item_to_list(thd, field)) + if (!field || add_item_to_list(thd, field)) return 1; field->set_name(thd, &buffer); if (thd->lex->verbose) { field_info= &schema_table->fields_info[3]; field= new (thd->mem_root) Item_field(thd, context, field_info->name()); - if (add_item_to_list(thd, field)) + if (! field || add_item_to_list(thd, field)) return 1; field->set_name(thd, field_info->old_name()); } @@ -8953,12 +9038,11 @@ int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) continue; Item_field *field= new (thd->mem_root) Item_field(thd, context, field_info->name()); - if (field) - { - field->set_name(thd, field_info->old_name()); - if (add_item_to_list(thd, field)) - return 1; - } + if (!field) + return 1; + field->set_name(thd, field_info->old_name()); + if (add_item_to_list(thd, field)) + return 1; } return 0; } @@ -8976,17 +9060,15 @@ int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) field_info= &schema_table->fields_info[*field_num]; Item_field *field= new (thd->mem_root) Item_field(thd, context, field_info->name()); - if (field) - { - field->set_name(thd, field_info->old_name()); - if (add_item_to_list(thd, field)) - return 1; - } + if (!field) + return 1; + field->set_name(thd, field_info->old_name()); + if (add_item_to_list(thd, field)) + return 1; } return 0; } - int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) { int fields_arr[]= {2, 3, 4, 27, 24, 23, 22, 26, 28, 29, 30, -1}; @@ -8999,10 +9081,44 @@ int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) field_info= &schema_table->fields_info[*field_num]; Item_field *field= new (thd->mem_root) Item_field(thd, context, field_info->name()); - if (field) + if (!field) + return 1; + field->set_name(thd, field_info->old_name()); + if (add_item_to_list(thd, field)) + return 1; + } + return 0; +} + + +static int make_slave_status_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) +{ + ST_FIELD_INFO *field_info= schema_table->fields_info; + Name_resolution_context *context= &thd->lex->first_select_lex()->context; + DBUG_ASSERT(thd->lex->sql_command == SQLCOM_SHOW_SLAVE_STAT); + bool all_slaves= thd->lex->mi.show_all_slaves; + ulonglong used_fields= ~0ULL; + + if (!all_slaves) + { + /* Remove 2 first fields and all fields above and including field 55 */ + used_fields&= ~((1ULL << 0) | (1ULL << 1)); + used_fields&= ((1ULL << 56)-1); + } + + for (uint i=0; !field_info->end_marker(); field_info++, i++) + { + /* + We have all_slaves here to take into account that we some day may have + more than 64 fields in the list. If all_slaves is set we should show + all fields. + */ + if (all_slaves || (used_fields & ((1ULL << i)))) { - field->set_name(thd, field_info->old_name()); - if (add_item_to_list(thd, field)) + LEX_CSTRING field_name= field_info->name(); + Item_field *field= new (thd->mem_root) + Item_field(thd, context, field_name); + if (!field || add_item_to_list(thd, field)) return 1; } } @@ -10249,10 +10365,7 @@ ST_FIELD_INFO files_fields_info[]= void init_fill_schema_files_row(TABLE* table) { - int i; - for(i=0; !Show::files_fields_info[i].end_marker(); i++) - table->field[i]->set_null(); - + table->set_null_bits(); table->field[IS_FILES_STATUS]->set_notnull(); table->field[IS_FILES_STATUS]->store("NORMAL", 6, system_charset_info); } @@ -10414,8 +10527,78 @@ ST_FIELD_INFO check_constraints_fields_info[]= CEnd() }; -}; // namespace Show +ST_FIELD_INFO slave_status_info[]= +{ + Column("Connection_name", Name(), NOT_NULL), + Column("Slave_SQL_State", Varchar(64), NULLABLE), + Column("Slave_IO_State", Varchar(64), NULLABLE), + Column("Master_Host", Varchar(HOSTNAME_LENGTH), NULLABLE), + Column("Master_User", Varchar(USERNAME_LENGTH), NULLABLE), + Column("Master_Port", ULong(7), NOT_NULL), + Column("Connect_Retry", SLong(10), NOT_NULL), + Column("Master_Log_File", Varchar(FN_REFLEN), NOT_NULL), + Column("Read_Master_Log_Pos", ULonglong(10), NOT_NULL), + Column("Relay_Log_File", Varchar(FN_REFLEN), NOT_NULL), + Column("Relay_Log_Pos", ULonglong(10), NOT_NULL), + Column("Relay_Master_Log_File", Varchar(FN_REFLEN), NOT_NULL), + Column("Slave_IO_Running", Varchar(10), NOT_NULL), + Column("Slave_SQL_Running", Varchar(3), NOT_NULL), + Column("Replicate_Do_DB", Name(), NOT_NULL), + Column("Replicate_Ignore_DB", Name(), NOT_NULL), + Column("Replicate_Do_Table", Name(), NOT_NULL), + Column("Replicate_Ignore_Table", Name(), NOT_NULL), + Column("Replicate_Wild_Do_Table", Name(), NOT_NULL), + Column("Replicate_Wild_Ignore_Table", Name(), NOT_NULL), + Column("Last_Errno", SLong(4), NOT_NULL), + Column("Last_Error", Varchar(20), NULLABLE), + Column("Skip_Counter", ULong(10), NOT_NULL), + Column("Exec_Master_Log_Pos", ULonglong(10), NOT_NULL), + Column("Relay_Log_Space", ULonglong(10), NOT_NULL), + Column("Until_Condition", Varchar(6), NOT_NULL), + Column("Until_Log_File", Varchar(FN_REFLEN), NULLABLE), + Column("Until_Log_Pos", ULonglong(10), NOT_NULL), + Column("Master_SSL_Allowed", Varchar(7), NULLABLE), + Column("Master_SSL_CA_File", Varchar(FN_REFLEN), NULLABLE), + Column("Master_SSL_CA_Path", Varchar(FN_REFLEN), NULLABLE), + Column("Master_SSL_Cert", Varchar(FN_REFLEN), NULLABLE), + Column("Master_SSL_Cipher", Varchar(FN_REFLEN), NULLABLE), + Column("Master_SSL_Key", Varchar(FN_REFLEN), NULLABLE), + Column("Seconds_Behind_Master", SLonglong(10), NULLABLE), + Column("Master_SSL_Verify_Server_Cert", Varchar(3), NOT_NULL), + Column("Last_IO_Errno", SLong(4), NOT_NULL), + Column("Last_IO_Error", Varchar(MYSQL_ERRMSG_SIZE), NULLABLE), + Column("Last_SQL_Errno", SLong(4), NOT_NULL), + Column("Last_SQL_Error", Varchar(MYSQL_ERRMSG_SIZE), NULLABLE), + Column("Replicate_Ignore_Server_Ids", Varchar(FN_REFLEN), NOT_NULL), + Column("Master_Server_Id", ULong(10), NOT_NULL), + Column("Master_SSL_Crl", Varchar(FN_REFLEN), NULLABLE), + Column("Master_SSL_Crlpath", Varchar(FN_REFLEN), NULLABLE), + Column("Using_Gtid", Varchar(15), NULLABLE), + Column("Gtid_IO_Pos", Varchar(1024), NOT_NULL), + Column("Replicate_Do_Domain_Ids", Varchar(FN_REFLEN), NOT_NULL), + Column("Replicate_Ignore_Domain_Ids", Varchar(FN_REFLEN), NOT_NULL), + Column("Parallel_Mode", Varchar(15), NOT_NULL), + Column("SQL_Delay", ULong(10), NOT_NULL), + Column("SQL_Remaining_Delay", ULong(10), NULLABLE), + Column("Slave_SQL_Running_State", Varchar(64), NULLABLE), + Column("Slave_DDL_Groups", ULonglong(20), NOT_NULL), + Column("Slave_Non_Transactional_Groups", ULonglong(20), NOT_NULL), + Column("Slave_Transactional_Groups", ULonglong(20), NOT_NULL), + Column("Replicate_Rewrite_DB",Varchar(1024), NOT_NULL), + Column("Retried_transactions", ULong(10), NOT_NULL), + Column("Max_relay_log_size", ULonglong(10), NOT_NULL), + Column("Executed_log_entries", ULong(10), NOT_NULL), + Column("Slave_received_heartbeats", ULong(10), NOT_NULL), + Column("Slave_heartbeat_period", Float(703), NOT_NULL), // 3 decimals + Column("Gtid_Slave_Pos", Varchar(FN_REFLEN), NOT_NULL), + Column("Master_last_event_time", Datetime(0), NULLABLE), + Column("Slave_last_event_time", Datetime(0), NULLABLE), + Column("Master_Slave_time_diff", SLonglong(10), NULLABLE), + CEnd() +}; + +}; // namespace Show namespace Show { @@ -10565,6 +10748,10 @@ ST_SCHEMA_TABLE schema_tables[]= {"VIEWS"_Lex_ident_i_s_table, Show::view_fields_info, 0, get_all_tables, 0, get_schema_views_record, 1, 2, 0, OPEN_VIEW_ONLY|OPTIMIZE_I_S_TABLE|I_S_EXTENDED_ERROR_HANDLING}, +#ifdef HAVE_REPLICATION + {"SLAVE_STATUS"_Lex_ident_i_s_table, Show::slave_status_info, 0, + fill_slave_status, make_slave_status_old_format, 0, 1, 0, 0, 0 }, +#endif {Lex_ident_i_s_table(), 0, 0, 0, 0, 0, 0, 0, 0, 0} }; diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 0c505c29503..dc5daac0341 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -3971,12 +3971,22 @@ Field *Type_handler_float::make_schema_field(MEM_ROOT *root, TABLE *table, const ST_FIELD_INFO &def) const { LEX_CSTRING name= def.name(); + uint32 len= def.char_length(); + uint dec= NOT_FIXED_DEC; + if (len >= 100) + { + dec= def.decimal_scale(); + uint prec= def.decimal_precision(); + /* Field defined in sql_show.cc with decimals */ + len= my_decimal_precision_to_length(prec, dec, 0); + } + return new (root) - Field_float(addr.ptr(), def.char_length(), - addr.null_ptr(), addr.null_bit(), - Field::NONE, &name, - (uint8) NOT_FIXED_DEC, - 0/*zerofill*/, def.unsigned_flag()); + Field_float(addr.ptr(), len, + addr.null_ptr(), addr.null_bit(), + Field::NONE, &name, + dec, + 0/*zerofill*/, def.unsigned_flag()); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0d76b57d6c0..f17c6b23c93 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -14225,17 +14225,19 @@ show_param: } | ALL SLAVES STATUS_SYM { - if (!(Lex->m_sql_cmd= new (thd->mem_root) - Sql_cmd_show_slave_status(true))) + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_SLAVE_STAT; + lex->mi.show_all_slaves= 1; + if (prepare_schema_table(thd, lex, 0, SCH_SLAVE_STATUS)) MYSQL_YYABORT; - Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; } | SLAVE optional_connection_name STATUS_SYM optional_for_channel { - if (!(Lex->m_sql_cmd= new (thd->mem_root) - Sql_cmd_show_slave_status())) + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_SLAVE_STAT; + lex->mi.show_all_slaves= 0; + if (prepare_schema_table(thd, lex, 0, SCH_SLAVE_STATUS)) MYSQL_YYABORT; - Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; } | CREATE PROCEDURE_SYM sp_name { diff --git a/sql/table.h b/sql/table.h index bd5c11d9430..5648edd2667 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1646,6 +1646,16 @@ struct TABLE bool fill_item_list(List<Item> *item_list) const; void reset_item_list(List<Item> *item_list, uint skip) const; void clear_column_bitmaps(void); + inline void clear_null_bits() + { + if (s->null_bytes) + bzero(null_flags, s->null_bytes); + } + inline void set_null_bits() + { + if (s->null_bytes) + bfill(null_flags, s->null_bytes, 255); + } void prepare_for_position(void); MY_BITMAP *prepare_for_keyread(uint index, MY_BITMAP *map); MY_BITMAP *prepare_for_keyread(uint index) @@ -3494,8 +3504,7 @@ inline void mark_as_null_row(TABLE *table) { table->null_row=1; table->status|=STATUS_NULL_ROW; - if (table->s->null_bytes) - bfill(table->null_flags,table->s->null_bytes,255); + table->set_null_bits(); } /* -- 2.39.2
participants (1)
-
Kristian Nielsen