Skip to content

Commit

Permalink
Skip reading binlog files during show binary logs
Browse files Browse the repository at this point in the history
Summary:
SHOW BINARY LOGS requires reading each binlog file
to determine if it is encrypted. This scan holds the index lock, which
can block binlog rotation when the current binlog has reached capacity.

Allow reading the binlog file to be disabled during show binary logs.

Reviewed By: abhinav04sharma

Differential Revision: D28124075
  • Loading branch information
Herman Lee committed Nov 18, 2023
1 parent f674306 commit 862d1ac
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 7 deletions.
5 changes: 5 additions & 0 deletions mysql-test/r/mysqld--help-notwin.result
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
49 changes: 49 additions & 0 deletions mysql-test/suite/sys_vars/r/show_binlogs_encryption_basic.result
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--log-bin=1 --gtid_mode=ON --enforce_gtid_consistency
64 changes: 64 additions & 0 deletions mysql-test/suite/sys_vars/t/show_binlogs_encryption_basic.test
Original file line number Diff line number Diff line change
@@ -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;
1 change: 1 addition & 0 deletions sql/mysqld.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions sql/mysqld.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
22 changes: 15 additions & 7 deletions sql/rpl_source.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
4 changes: 4 additions & 0 deletions sql/sys_vars.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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));

0 comments on commit 862d1ac

Please sign in to comment.