From 685b0b0def797108f689c833ebae7cc656b36038 Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Wed, 16 Jul 2025 21:25:00 +0200 Subject: [PATCH] Binlog-in-engine: Implement dynamically changing binlog max size Signed-off-by: Kristian Nielsen --- .../binlog_flush_purge.result | 10 ++++++++++ .../binlog_in_engine/binlog_flush_purge.test | 12 +++++++++++ .../binlog_in_engine/rpl_gtid_index.test | 1 - sql/handler.h | 2 ++ sql/log.cc | 2 ++ storage/innobase/handler/ha_innodb.cc | 1 + storage/innobase/handler/innodb_binlog.cc | 20 ++++++++++++------- storage/innobase/include/innodb_binlog.h | 1 + 8 files changed, 41 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/binlog_in_engine/binlog_flush_purge.result b/mysql-test/suite/binlog_in_engine/binlog_flush_purge.result index 59ebd0c2714..287cbe03834 100644 --- a/mysql-test/suite/binlog_in_engine/binlog_flush_purge.result +++ b/mysql-test/suite/binlog_in_engine/binlog_flush_purge.result @@ -164,4 +164,14 @@ SELECT @@GLOBAL.gtid_binlog_state; SELECT @@GLOBAL.gtid_binlog_state; @@GLOBAL.gtid_binlog_state 0-1-2508,1-1-1003 +SET @old_max_size= @@GLOBAL.max_binlog_size; +SET GLOBAL max_binlog_size= 1048576; +FLUSH BINARY LOGS; +SHOW BINARY LOGS; +Log_name File_size +binlog-000030.ibb 8192 +binlog-000031.ibb 8192 +binlog-000032.ibb 262144 +binlog-000033.ibb 1048576 +SET GLOBAL max_binlog_size= @old_max_size; DROP TABLE t1; diff --git a/mysql-test/suite/binlog_in_engine/binlog_flush_purge.test b/mysql-test/suite/binlog_in_engine/binlog_flush_purge.test index d91485c738a..effae20d85f 100644 --- a/mysql-test/suite/binlog_in_engine/binlog_flush_purge.test +++ b/mysql-test/suite/binlog_in_engine/binlog_flush_purge.test @@ -247,6 +247,18 @@ SELECT @@GLOBAL.gtid_binlog_state; --source include/restart_mysqld.inc SELECT @@GLOBAL.gtid_binlog_state; + +# Test dynamically changing the max binlog size. +SET @old_max_size= @@GLOBAL.max_binlog_size; +--let $binlog_size= 1048576 +eval SET GLOBAL max_binlog_size= $binlog_size; +FLUSH BINARY LOGS; +--let $binlog_name= binlog-000033.ibb +--source include/wait_for_engine_binlog.inc +SHOW BINARY LOGS; +SET GLOBAL max_binlog_size= @old_max_size; + + DROP TABLE t1; # No need to restore @@GLOBAL.slave_connections_needed_for_purge, as we diff --git a/mysql-test/suite/binlog_in_engine/rpl_gtid_index.test b/mysql-test/suite/binlog_in_engine/rpl_gtid_index.test index 4fd62417c7d..9ed6cb5e9f2 100644 --- a/mysql-test/suite/binlog_in_engine/rpl_gtid_index.test +++ b/mysql-test/suite/binlog_in_engine/rpl_gtid_index.test @@ -16,7 +16,6 @@ --source suite/rpl/include/rpl_gtid_index.inc --echo *** Switch to a larger binlog size -# ToDo: Fix that in current code, changing max_binlog_size dynamically is silently ignored. SET @old_binlog_size= @@GLOBAL.max_binlog_size; SET GLOBAL max_binlog_size= 16*1024*1024; --let $NUM_POS= 1000 diff --git a/sql/handler.h b/sql/handler.h index 70720d6213e..2de9a1c16cd 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1547,6 +1547,8 @@ struct handlerton /* Optional implementation of binlog in the engine. */ bool (*binlog_init)(size_t binlog_size, const char *directory); + /* Dynamically changing the binlog max size. */ + void (*set_binlog_max_size)(size_t binlog_size); /* Binlog an event group that doesn't go through commit_ordered. */ bool (*binlog_write_direct_ordered)(IO_CACHE *cache, handler_binlog_event_group_info *binlog_info, diff --git a/sql/log.cc b/sql/log.cc index 4d8a57f07a7..ad31aa6a98c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -10614,6 +10614,8 @@ void MYSQL_BIN_LOG::set_max_size(ulong max_size_arg) mysql_mutex_lock(&LOCK_log); if (is_open()) max_size= max_size_arg; + if (opt_binlog_engine_hton) + (*opt_binlog_engine_hton->set_binlog_max_size)((size_t)max_size_arg); mysql_mutex_unlock(&LOCK_log); DBUG_VOID_RETURN; } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 5562be483f3..be02d19f666 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4132,6 +4132,7 @@ static int innodb_init(void* p) innobase_hton->update_optimizer_costs= innobase_update_optimizer_costs; innobase_hton->binlog_init= innodb_binlog_init; + innobase_hton->set_binlog_max_size= ibb_set_max_size; innobase_hton->binlog_write_direct_ordered= innobase_binlog_write_direct_ordered; innobase_hton->binlog_write_direct= innobase_binlog_write_direct; diff --git a/storage/innobase/handler/innodb_binlog.cc b/storage/innobase/handler/innodb_binlog.cc index b892bec3733..e238d7bb13a 100644 --- a/storage/innobase/handler/innodb_binlog.cc +++ b/storage/innobase/handler/innodb_binlog.cc @@ -1262,13 +1262,8 @@ binlog_sync_initial() } -/* - Open the InnoDB binlog implementation. - This is called from server binlog layer if the user configured the binlog to - use the innodb implementation (with --binlog-storage-engine=innodb). -*/ -bool -innodb_binlog_init(size_t binlog_size, const char *directory) +void +ibb_set_max_size(size_t binlog_size) { uint64_t pages= binlog_size >> ibb_page_size_shift; if (UNIV_LIKELY(pages > (uint64_t)UINT32_MAX)) { @@ -1283,7 +1278,18 @@ innodb_binlog_init(size_t binlog_size, const char *directory) (pages << ibb_page_size_shift)); } innodb_binlog_size_in_pages= (uint32_t)pages; +} + +/* + Open the InnoDB binlog implementation. + This is called from server binlog layer if the user configured the binlog to + use the innodb implementation (with --binlog-storage-engine=innodb). +*/ +bool +innodb_binlog_init(size_t binlog_size, const char *directory) +{ + ibb_set_max_size(binlog_size); if (!directory || !directory[0]) directory= "."; else if (strlen(directory) + BINLOG_NAME_MAX_LEN > OS_FILE_MAX_PATH) diff --git a/storage/innobase/include/innodb_binlog.h b/storage/innobase/include/innodb_binlog.h index d7cc7815e54..c120c67701d 100644 --- a/storage/innobase/include/innodb_binlog.h +++ b/storage/innobase/include/innodb_binlog.h @@ -225,6 +225,7 @@ extern bool is_binlog_name(const char *name, uint64_t *out_idx); extern int get_binlog_header(const char *binlog_path, byte *page_buf, lsn_t &out_lsn, bool &out_empty) noexcept; extern void innodb_binlog_startup_init(); +extern void ibb_set_max_size(size_t binlog_size); extern bool innodb_binlog_init(size_t binlog_size, const char *directory); extern void innodb_binlog_close(bool shutdown); extern bool ibb_write_header_page(mtr_t *mtr, uint64_t file_no,