diff --git a/mysql-test/include/show_slave_status.inc b/mysql-test/include/show_slave_status.inc index 429ed8a5abdee..c91e76f1ec54e 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 61c4ca308cc67..75fb07fe31781 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 b5e65ef2cb4c9..1be9b7e944d39 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 8c93cc79f647a..cad4078deb565 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 89d7d877fb298..8baaaab6e0c0b 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 0000000000000..839f84cd5ee4a --- /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 0000000000000..09739a343835e --- /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 e0bee79ee3cf9..7c939064410b6 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 b413c63b59d67..745d03234e8a2 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 19040917bde53..677ad46a78778 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 640ea339a5634..ae45f793e826f 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 @@ -591,6 +656,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 @@ -996,6 +1062,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 c3c53e149b45e..21ab57f75953b 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 3606511678401..4dca25b8fc7bb 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 relay.000002 master-bin.000001 Yes Yes 0 0 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 relay-master@00202@002e2.000002 master-bin.000001 Yes Yes 0 0 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 relay.000002 master-bin.000001 Yes Yes 0 0 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 relay-master@00202@002e2.000002 master-bin.000001 Yes Yes 0 0 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 relay.000004 master-bin.000001 Yes Yes 0 0 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 relay-master@00202@002e2.000004 master-bin.000001 Yes Yes 0 0 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 relay.000004 master-bin.000001 Yes Yes 0 0 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 relay-master@00202@002e2.000004 master-bin.000001 Yes Yes 0 0 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 4c721a1742878..182d9687cb922 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 f9f43d44ca7d2..006d0aacfbdb9 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 ce60f48c83112..7475ff76e587d 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 7cc87530770ca..b60975be0590c 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 diff --git a/mysql-test/suite/perfschema/t/relaylog.test b/mysql-test/suite/perfschema/t/relaylog.test index 12fc96a8b2718..512aedf4c76ee 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; 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 0000000000000..2dd332007e849 --- /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 0000000000000..b1dbcd6a03e8e --- /dev/null +++ b/mysql-test/suite/rpl/r/master_last_event_time_stmt.result @@ -0,0 +1,131 @@ +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 +# Sleep 1 to ensure setup DDL and test statements have different binlog timestamps +connection server_2; +set @old_par_thds= @@global.slave_parallel_threads; +# +# 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_2; +include/stop_slave.inc +set @@global.slave_parallel_threads= 0; +include/start_slave.inc +connection server_2; +flush logs; +connection server_1; +# Only sleep on master so the real execution time on the slave is less +insert into t1 values (sleep(if(@@global.server_id=1, 2, 0))); +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 serial slave doesn't overwrite exec_time in the binlog event (0s)] +include/assert_grep.inc [Ensure serial slave doesn't overwrite exec_time in the binlog event (1s)] +# +# 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 +set @@global.slave_parallel_threads= @old_par_thds; +include/start_slave.inc +connection server_2; +include/stop_slave.inc +set @@global.slave_parallel_threads= 1; +include/start_slave.inc +connection server_2; +flush logs; +connection server_1; +# Only sleep on master so the real execution time on the slave is less +insert into t1 values (sleep(if(@@global.server_id=1, 2, 0))); +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 parallel slave doesn't overwrite exec_time in the binlog event (0s)] +include/assert_grep.inc [Ensure parallel slave doesn't overwrite exec_time in the binlog event (1s)] +# +# 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 +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 +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 +set @@global.slave_parallel_threads= @old_par_thds; +include/start_slave.inc +# +# Cleanup +connection server_2; +include/stop_slave.inc +change master to master_delay=0; +include/start_slave.inc +connection server_3; +include/start_slave.inc +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 75012c93f3b7c..c41de974588c3 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 0000000000000..8a116025af04f --- /dev/null +++ b/mysql-test/suite/rpl/t/master_last_event_time.inc @@ -0,0 +1,57 @@ +--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 +--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 0000000000000..65a4396edf343 --- /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 0000000000000..92abe00d40702 --- /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 0000000000000..35b68f7906f72 --- /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 0000000000000..fea091bce80b4 --- /dev/null +++ b/mysql-test/suite/rpl/t/master_last_event_time_stmt.test @@ -0,0 +1,116 @@ +# +# 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 # Sleep 1 to ensure setup DDL and test statements have different binlog timestamps + --sleep 1 + +--connection server_2 +set @old_par_thds= @@global.slave_parallel_threads; + + +--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 + +--let $serial_slave_const=2 +--let $parallel_slave_const=1 +--let $mode_ctr= 2 +while ($mode_ctr) +{ + --connection server_2 + --source include/stop_slave.inc + if ($mode_ctr == $parallel_slave_const) + { + --let $mode_name= parallel + set @@global.slave_parallel_threads= 1; + } + if ($mode_ctr == $serial_slave_const) + { + --let $mode_name= serial + set @@global.slave_parallel_threads= 0; + } + --source include/start_slave.inc + + --connection server_2 + flush logs; + --connection server_1 + --disable_warnings + --echo # Only sleep on master so the real execution time on the slave is less + insert into t1 values (sleep(if(@@global.server_id=1, 2, 0))); + --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 + + --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 $mode_name slave doesn't overwrite exec_time in the binlog event (0s) + --let $assert_select=exec_time=0 + --let $assert_file= $slave_outfile + --source include/assert_grep.inc + + # Double-check in the unlikely case execution time could be rounded to 1 + --let $assert_text= Ensure $mode_name slave doesn't overwrite exec_time in the binlog event (1s) + --let $assert_select=exec_time=1 + --let $assert_file= $slave_outfile + --source include/assert_grep.inc + + --source master_last_event_time.inc + + --connection server_2 + --source include/stop_slave.inc + set @@global.slave_parallel_threads= @old_par_thds; + --source include/start_slave.inc + + --dec $mode_ctr +} + +--echo # +--echo # Cleanup + +--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 + +--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 90753caf1431f..2c9b4882c1668 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 2c526ae07480f..9e002b640e85c 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 3de7af7757d6e..4513a4edd555f 100644 --- a/sql/item.h +++ b/sql/item.h @@ -4928,8 +4928,8 @@ class Item_partition_func_safe_string: public Item_string /** Item_empty_string -- is a utility class to put an item into List - 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 @@ -5310,6 +5310,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 f9a09cde6a55b..6dd0be652db35 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1899,10 +1899,22 @@ 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->rgi_slave && !thd->user_time.val) + { + /* + For transactions binlogged without explicit COMMIT queries, e.g. + autocommit InnoDB transactions, ensure that the end-time of the + transaction still exists in the binlog by setting the timestamp + of the Xid_log_event to be the time of commit. + */ + 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)); } /** @@ -8265,13 +8277,18 @@ 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; - for (; has_xid && !entry.need_unlog && ha_info; ha_info= ha_info->next()) + if (!entry.need_unlog && end_ev->get_type_code() == XID_EVENT) { - if (ha_info->is_started() && ha_info->ht() != binlog_hton && - !ha_info->ht()->commit_checkpoint_request) - entry.need_unlog= true; + for (; 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 3974435601cf8..250e814283890 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -963,7 +963,6 @@ Log_event* Log_event::read_log_event(IO_CACHE* file, DBUG_RETURN(res); } - /** Binlog format tolerance is in (buf, event_len, fdle) constructors. @@ -1106,7 +1105,7 @@ Log_event* Log_event::read_log_event(const uchar *buf, uint event_len, break; case QUERY_COMPRESSED_EVENT: ev= new Query_compressed_log_event(buf, event_len, fdle, - QUERY_COMPRESSED_EVENT); + QUERY_COMPRESSED_EVENT); break; case ROTATE_EVENT: ev= new Rotate_log_event(buf, event_len, fdle); @@ -1746,6 +1745,29 @@ 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_end_time(const uchar *buf, + const Format_description_log_event *description_event) +{ + time_t when; + DBUG_ASSERT(LOG_EVENT_IS_QUERY((Log_event_type) buf[EVENT_TYPE_OFFSET]) || + LOG_EVENT_IS_LOAD_DATA((Log_event_type) buf[EVENT_TYPE_OFFSET])); + 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 fd03110afe808..909fde1a76e81 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. @@ -5524,6 +5526,8 @@ 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_end_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 ff5eb1c8c1a2a..f3bf55e82b80d 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,13 @@ 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->rgi_slave) ? thd->rgi_slave->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 @@ -3687,6 +3690,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 1e27c996687ec..ca7803248c63b 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -1417,33 +1417,6 @@ bool Protocol::store(I_List* 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* str_list) -{ - char buf[256]; - const char *delimiter= ","; - String tmp(buf, sizeof(buf), &my_charset_bin); - size_t delim_len= 0; - I_List_iterator 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 d1096b041af3f..0a55d1b13315e 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -105,7 +105,7 @@ class Protocol bool send_result_set_row(List *row_items); bool store(I_List *str_list); - bool store(I_List *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 45c3a187326f7..52d6717419053 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 a0f17a7dd011a..37a5fc30099c9 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 bdf089cb5d988..29651a5bc9d08 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -3588,6 +3588,12 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev, qev->rgi= e->current_group_info; } + /* + The original execution time of the event from the master is stored on the + serial_rgi, so copy it to our new one for parallel execution. + */ + qev->rgi->orig_exec_time= serial_rgi->orig_exec_time; + /* Queue the event for processing. */ diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 22354e2d998f9..499223f2c354b 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), @@ -1029,9 +1031,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 { @@ -1042,6 +1042,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, @@ -2156,6 +2157,7 @@ rpl_group_info::reinit(Relay_log_info *rli) gtid_ev_flags_extra= 0; gtid_ev_sa_seq_no= 0; last_master_timestamp = 0; + orig_exec_time= 0; gtid_ignore_duplicate_state= GTID_DUPLICATE_NULL; speculation= SPECULATE_NO; rpt= NULL; diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index d20b0eb2ab4b8..7bbb5b33daf8e 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() @@ -840,6 +852,13 @@ struct rpl_group_info */ my_time_t last_master_timestamp; + /* + The exec_time of the transaction from the master's binlog. It is used with + log_slave_updates to preserve execution time value from the master when + re-binlogging on the slave. + */ + my_time_t orig_exec_time; + /* Information to be able to re-try an event group in case of a deadlock or other temporary error. diff --git a/sql/slave.cc b/sql/slave.cc index 5ba8d388f2eb3..0fac29721d52f 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -171,7 +171,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. @@ -1473,40 +1473,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) { @@ -2870,287 +2836,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 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 *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[]= { @@ -3167,146 +2852,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* str_list) +{ + char buf[256]; + String tmp(buf, sizeof(buf), &my_charset_bin); + uint32 len; + I_List_iterator 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: @@ -3327,102 +3036,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, @@ -3430,72 +3158,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 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"); @@ -4321,6 +3983,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli, #endif /* WITH_WSREP */ int exec_res; Log_event_type typ= ev->get_type_code(); + serial_rgi->orig_exec_time= ev->exec_time; DBUG_EXECUTE_IF( "pause_sql_thread_on_next_event", @@ -4349,13 +4012,34 @@ 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, so initialize Slave_last_event_time with + a value one second before the new event to appear as if it is + otherwise up-to-date with the master. In effect, this will initialize + Master_Slave_time_diff to be 1. + */ + 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. @@ -7020,6 +6704,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 end_time= query_event_get_end_time( + buf, rli->relay_log.description_event_for_queue); + set_if_bigger(rli->newest_master_timestamp, end_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(buf + FLAGS_OFFSET), diff --git a/sql/slave.h b/sql/slave.h index 02de9135c2a10..5dd7d6e262b91 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_cmd.h b/sql/sql_cmd.h index baa779e961075..f83c8191c5f1e 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 override { return SQLCOM_SHOW_SLAVE_STAT; } - - bool execute(THD *thd) override; - 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 3f4af2fa9405f..8c6f3172d9d54 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 3b46ce6a847ae..35d0d56b68216 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 2c9ef0812962f..3dc770cf96926 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 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(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 895ff090da6ec..cbdef5bea2133 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 3e658b1e4440f..73df0d6bf7855 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,15 +9081,93 @@ 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; +} + + +#ifdef HAVE_REPLICATION + +/* + Constants for columns that are present in + SHOW ALL SLAVES STATUS + that are not in SHOW SLAVE STATUS. Specifically, columns 0 and 1, and + everything at and above 56. + 0: Connection_name + 1: Slave_SQL_State + 56: Retried_transactions +*/ +#define SLAVE_STATUS_COL_CONNECTION_NAME 0 +#define SLAVE_STATUS_COL_SLAVE_SQL_STATE 1 +#define SLAVE_STATUS_COL_RETRIED_TRANSACTIONS 56 + +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 (Connection_name and Slave_SQL_State) and all + fields above and including field 56 (Retried_transactions) + */ + used_fields&= ~((1ULL << SLAVE_STATUS_COL_CONNECTION_NAME) | + (1ULL << SLAVE_STATUS_COL_SLAVE_SQL_STATE)); + used_fields&= ((1ULL << SLAVE_STATUS_COL_RETRIED_TRANSACTIONS) - 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); + DBUG_ASSERT(all_slaves || (i > SLAVE_STATUS_COL_SLAVE_SQL_STATE && + i < SLAVE_STATUS_COL_RETRIED_TRANSACTIONS)); + if (!field || add_item_to_list(thd, field)) return 1; } +#ifndef DBUG_OFF + else + { + switch (i) + { + case SLAVE_STATUS_COL_CONNECTION_NAME: + DBUG_ASSERT(strncmp(field_info->name().str, + C_STRING_WITH_LEN("Connection_name")) == 0); + break; + case SLAVE_STATUS_COL_SLAVE_SQL_STATE: + DBUG_ASSERT(strncmp(field_info->name().str, + C_STRING_WITH_LEN("Slave_SQL_State")) == 0); + break; + case SLAVE_STATUS_COL_RETRIED_TRANSACTIONS: + DBUG_ASSERT(strncmp(field_info->name().str, + C_STRING_WITH_LEN("Retried_transactions")) == 0); + break; + default: + DBUG_ASSERT(i > SLAVE_STATUS_COL_RETRIED_TRANSACTIONS); + } + } +#endif } return 0; } +#endif /* @@ -10249,10 +10409,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 +10571,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 +10792,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 ef9d03a8beafc..5626c8477f56e 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -4058,12 +4058,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 0d76b57d6c0ee..b71e42572c174 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -14225,17 +14225,23 @@ 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; +#ifdef HAVE_REPLICATION + if (prepare_schema_table(thd, lex, 0, SCH_SLAVE_STATUS)) MYSQL_YYABORT; - Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; +#endif } | 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; +#ifdef HAVE_REPLICATION + if (prepare_schema_table(thd, lex, 0, SCH_SLAVE_STATUS)) MYSQL_YYABORT; - Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; +#endif } | CREATE PROCEDURE_SYM sp_name { diff --git a/sql/table.h b/sql/table.h index a77c24ec4192e..525a67879bfcb 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1620,6 +1620,16 @@ struct TABLE bool fill_item_list(List *item_list) const; void reset_item_list(List *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) @@ -3468,8 +3478,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(); } /*