diff --git a/mysql-test/r/mysqld--help-notwin.result b/mysql-test/r/mysqld--help-notwin.result index 4ee073bcb2bc..7d4b4d6ba938 100644 --- a/mysql-test/r/mysqld--help-notwin.result +++ b/mysql-test/r/mysqld--help-notwin.result @@ -2340,6 +2340,10 @@ The following options may be given as the first argument: to TRUE, the plugin will flag associated authenticated accounts to be mapped to proxy users when the server option check_proxy_users is enabled. + --show-binlogs-encryption + Scan binlogs to determine encryption property during show + binlogs + (Defaults to on; use --skip-show-binlogs-encryption to disable.) --show-create-table-contain-privacy-policy Controls if the the SHOW CREATE TABLE command should display the PRIVACY_POLICY of the table @@ -3447,6 +3451,7 @@ session-track-system-variables time_zone,autocommit,character_set_client,charact session-track-transaction-info OFF set-read-only-on-shutdown FALSE sha256-password-proxy-users FALSE +show-binlogs-encryption TRUE show-create-table-contain-privacy-policy FALSE show-create-table-verbosity FALSE show-gipk-in-create-table-and-information-schema TRUE diff --git a/mysql-test/suite/binlog_nogtid/r/binlog_persist_only_variables.result b/mysql-test/suite/binlog_nogtid/r/binlog_persist_only_variables.result index e91d413f4d3b..03312e13558c 100644 --- a/mysql-test/suite/binlog_nogtid/r/binlog_persist_only_variables.result +++ b/mysql-test/suite/binlog_nogtid/r/binlog_persist_only_variables.result @@ -198,6 +198,7 @@ Warning 1287 '@@rpl_stop_slave_timeout' is deprecated and will be removed in a f Warning 1287 '@@rpl_stop_slave_timeout' is deprecated and will be removed in a future release. Please use rpl_stop_replica_timeout instead. SET PERSIST_ONLY rpl_wait_for_semi_sync_ack = @@GLOBAL.rpl_wait_for_semi_sync_ack; SET PERSIST_ONLY session_track_gtids = @@GLOBAL.session_track_gtids; +SET PERSIST_ONLY show_binlogs_encryption = @@GLOBAL.show_binlogs_encryption; SET PERSIST_ONLY skip_master_info_check_for_read_only_error_msg_extra = @@GLOBAL.skip_master_info_check_for_read_only_error_msg_extra; SET PERSIST_ONLY skip_replica_start = @@GLOBAL.skip_replica_start; SET PERSIST_ONLY skip_slave_start = @@GLOBAL.skip_slave_start; @@ -416,6 +417,7 @@ RESET PERSIST rpl_slave_flow_control; RESET PERSIST rpl_stop_replica_timeout; RESET PERSIST rpl_wait_for_semi_sync_ack; RESET PERSIST session_track_gtids; +RESET PERSIST show_binlogs_encryption; RESET PERSIST skip_master_info_check_for_read_only_error_msg_extra; RESET PERSIST skip_replica_start; RESET PERSIST slave_check_before_image_consistency; diff --git a/mysql-test/suite/binlog_nogtid/r/binlog_persist_variables.result b/mysql-test/suite/binlog_nogtid/r/binlog_persist_variables.result index aaf578efeffe..4a8ce74f5a83 100644 --- a/mysql-test/suite/binlog_nogtid/r/binlog_persist_variables.result +++ b/mysql-test/suite/binlog_nogtid/r/binlog_persist_variables.result @@ -181,6 +181,7 @@ Warning 1287 '@@rpl_stop_slave_timeout' is deprecated and will be removed in a f Warning 1287 '@@rpl_stop_slave_timeout' is deprecated and will be removed in a future release. Please use rpl_stop_replica_timeout instead. SET PERSIST rpl_wait_for_semi_sync_ack = @@GLOBAL.rpl_wait_for_semi_sync_ack; SET PERSIST session_track_gtids = @@GLOBAL.session_track_gtids; +SET PERSIST show_binlogs_encryption = @@GLOBAL.show_binlogs_encryption; SET PERSIST skip_master_info_check_for_read_only_error_msg_extra = @@GLOBAL.skip_master_info_check_for_read_only_error_msg_extra; SET PERSIST skip_replica_start = @@GLOBAL.skip_replica_start; ERROR HY000: Variable 'skip_replica_start' is a read only variable @@ -437,6 +438,7 @@ Warnings: Warning 3615 Variable rpl_stop_slave_timeout does not exist in persisted config file RESET PERSIST IF EXISTS rpl_wait_for_semi_sync_ack; RESET PERSIST IF EXISTS session_track_gtids; +RESET PERSIST IF EXISTS show_binlogs_encryption; RESET PERSIST IF EXISTS skip_master_info_check_for_read_only_error_msg_extra; RESET PERSIST IF EXISTS skip_replica_start; Warnings: diff --git a/mysql-test/suite/sys_vars/r/show_binlogs_encryption_basic.result b/mysql-test/suite/sys_vars/r/show_binlogs_encryption_basic.result new file mode 100644 index 000000000000..cfa528e4db3c --- /dev/null +++ b/mysql-test/suite/sys_vars/r/show_binlogs_encryption_basic.result @@ -0,0 +1,49 @@ +SET @start_global_value = @@global.show_binlogs_encryption; +SELECT @start_global_value; +@start_global_value +1 +SELECT @@session.show_binlogs_encryption; +ERROR HY000: Variable 'show_binlogs_encryption' is a GLOBAL variable +SET GLOBAL show_binlogs_encryption=1; +SET GLOBAL show_binlogs_encryption=0; +SET GLOBAL show_binlogs_encryption=true; +SET GLOBAL show_binlogs_encryption=false; +SET GLOBAL show_binlogs_encryption=on; +SET GLOBAL show_binlogs_encryption=off; +SET GLOBAL show_binlogs_encryption=1.1; +ERROR 42000: Incorrect argument type to variable 'show_binlogs_encryption' +SET GLOBAL show_binlogs_encryption="foo"; +ERROR 42000: Variable 'show_binlogs_encryption' can't be set to the value of 'foo' +SET GLOBAL show_binlogs_encryption=-1; +ERROR 42000: Variable 'show_binlogs_encryption' can't be set to the value of '-1' +RESET MASTER; +CREATE TABLE t1 (pk INT, PRIMARY KEY (pk)) ENGINE=INNODB; +INSERT INTO t1 VALUES (1); +FLUSH LOGS; +INSERT INTO t1 VALUES (2); +FLUSH LOGS; +SET GLOBAL show_binlogs_encryption=1; +SHOW MASTER LOGS; +Log_name File_size Encrypted +1.000001 # No +1.000002 # No +1.000003 # No +SHOW MASTER LOGS WITH GTID; +Log_name File_size Encrypted Prev_gtid_set +1.000001 # No # [empty] +1.000002 # No # uuid:1-2 +1.000003 # No # uuid:1-3 +SET GLOBAL show_binlogs_encryption=0; +SHOW MASTER LOGS; +Log_name File_size Encrypted +1.000001 # NULL +1.000002 # NULL +1.000003 # No +SHOW MASTER LOGS WITH GTID; +Log_name File_size Encrypted Prev_gtid_set +1.000001 # NULL # [empty] +1.000002 # NULL # uuid:1-2 +1.000003 # No # uuid:1-3 +DROP TABLE t1; +RESET MASTER; +SET GLOBAL show_binlogs_encryption = @start_global_value; diff --git a/mysql-test/suite/sys_vars/t/show_binlogs_encryption_basic-master.opt b/mysql-test/suite/sys_vars/t/show_binlogs_encryption_basic-master.opt new file mode 100644 index 000000000000..15b5bed4596c --- /dev/null +++ b/mysql-test/suite/sys_vars/t/show_binlogs_encryption_basic-master.opt @@ -0,0 +1 @@ +--log-bin=1 --gtid_mode=ON --enforce_gtid_consistency diff --git a/mysql-test/suite/sys_vars/t/show_binlogs_encryption_basic.test b/mysql-test/suite/sys_vars/t/show_binlogs_encryption_basic.test new file mode 100644 index 000000000000..fef7fc62dedc --- /dev/null +++ b/mysql-test/suite/sys_vars/t/show_binlogs_encryption_basic.test @@ -0,0 +1,64 @@ +-- source include/load_sysvars.inc + +SET @start_global_value = @@global.show_binlogs_encryption; +SELECT @start_global_value; + +# +# exists as global only +# +--Error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@session.show_binlogs_encryption; + +# +# correct types +# +SET GLOBAL show_binlogs_encryption=1; +SET GLOBAL show_binlogs_encryption=0; +SET GLOBAL show_binlogs_encryption=true; +SET GLOBAL show_binlogs_encryption=false; +SET GLOBAL show_binlogs_encryption=on; +SET GLOBAL show_binlogs_encryption=off; + +# +# incorrect types +# +--error ER_WRONG_TYPE_FOR_VAR +SET GLOBAL show_binlogs_encryption=1.1; +--error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL show_binlogs_encryption="foo"; +--error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL show_binlogs_encryption=-1; + +RESET MASTER; + +CREATE TABLE t1 (pk INT, PRIMARY KEY (pk)) ENGINE=INNODB; +INSERT INTO t1 VALUES (1); +FLUSH LOGS; +INSERT INTO t1 VALUES (2); +FLUSH LOGS; + +SET GLOBAL show_binlogs_encryption=1; +let $master_uuid=`select @@server_uuid;`; +replace_result $master_uuid uuid; replace_column 2 #; +SHOW MASTER LOGS; + +let $master_uuid=`select @@server_uuid;`; +replace_result $master_uuid uuid; replace_column 2 #; +SHOW MASTER LOGS WITH GTID; + +SET GLOBAL show_binlogs_encryption=0; +let $master_uuid=`select @@server_uuid;`; +replace_result $master_uuid uuid; replace_column 2 #; +SHOW MASTER LOGS; + +let $master_uuid=`select @@server_uuid;`; +replace_result $master_uuid uuid; replace_column 2 #; +SHOW MASTER LOGS WITH GTID; + +DROP TABLE t1; + +RESET MASTER; +# +# cleanup +# +SET GLOBAL show_binlogs_encryption = @start_global_value; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a18d160c6811..54a3ffc819bb 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1337,6 +1337,7 @@ bool opt_partial_revokes; // Initialized through Sys_var bool set_read_only_on_shutdown = false; extern bool fix_read_only(sys_var *self, THD *thd, enum_var_type type); extern bool fix_super_read_only(sys_var *self, THD *thd, enum_var_type type); +bool show_binlogs_encryption = true; mysql_mutex_t LOCK_default_password_lifetime; mysql_mutex_t LOCK_mandatory_roles; diff --git a/sql/mysqld.h b/sql/mysqld.h index d871e37b063c..fe8f033610db 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -481,6 +481,7 @@ extern long zstd_net_compression_level; extern long lz4f_net_compression_level; extern bool enable_blind_replace; extern bool set_read_only_on_shutdown; +extern bool show_binlogs_encryption; /* SHOW STATS var: Name of current timer */ extern const char *timer_in_use; diff --git a/sql/rpl_source.cc b/sql/rpl_source.cc index ee09aa42d6a1..bd96e8f29d21 100644 --- a/sql/rpl_source.cc +++ b/sql/rpl_source.cc @@ -1646,19 +1646,27 @@ bool show_binlogs(THD *thd, bool with_gtid) { /* this is an old log, open it and find the size */ if ((file = mysql_file_open(key_file_binlog, fname, O_RDONLY, MYF(0))) >= 0) { - unsigned char magic[Rpl_encryption_header::ENCRYPTION_MAGIC_SIZE]; - if (mysql_file_read(file, magic, BINLOG_MAGIC_SIZE, MYF(0)) == 4 && - memcmp(magic, Rpl_encryption_header::ENCRYPTION_MAGIC, - Rpl_encryption_header::ENCRYPTION_MAGIC_SIZE) == 0) { - /* Encryption header size is already accounted in the file_length */ - encrypted_header_size = 1; + /* Skip the encryption check to improve performance */ + if (!show_binlogs_encryption) { + encrypted_header_size = -1; + } else { + unsigned char magic[Rpl_encryption_header::ENCRYPTION_MAGIC_SIZE]; + if (mysql_file_read(file, magic, BINLOG_MAGIC_SIZE, MYF(0)) == 4 && + memcmp(magic, Rpl_encryption_header::ENCRYPTION_MAGIC, + Rpl_encryption_header::ENCRYPTION_MAGIC_SIZE) == 0) { + /* Encryption header size is already accounted in the file_length */ + encrypted_header_size = 1; + } } file_length = (ulonglong)mysql_file_seek(file, 0L, MY_SEEK_END, MYF(0)); mysql_file_close(file, MYF(0)); } } protocol->store(file_length); - protocol->store(encrypted_header_size ? "Yes" : "No", &my_charset_bin); + protocol->store(encrypted_header_size < 0 + ? "NULL" + : encrypted_header_size ? "Yes" : "No", + &my_charset_bin); if (with_gtid) { const auto previous_gtid_set_map = diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 9072626aca07..0b2c1a4d355b 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -9572,3 +9572,7 @@ static Sys_var_uint Sys_response_attrs_contain_warnings_bytes( "comma. The default value is 0 which disables this feature", SESSION_VAR(response_attrs_contain_warnings_bytes), CMD_LINE(OPT_ARG), VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1)); +static Sys_var_bool Sys_show_binlogs_encryption( + "show_binlogs_encryption", + "Scan binlogs to determine encryption property during show binlogs", + GLOBAL_VAR(show_binlogs_encryption), CMD_LINE(OPT_ARG), DEFAULT(true));