Skip to content

Commit df61143

Browse files
committed
bug#36694848 Configure ndb binlog cache size
Problem: The ndbcluster plugin subscribes to all changes that occur in NDB and writes them epoch by epoch to binary log. Each epoch received from NDB might consist of a large number of changes which are all written to the binlog transaction cache before flushing them to the binary log. In order to properly dimension and configure the system the binlog transaction cache used by the ndb binlog injector must be possible to configure separately from sessions that normally write transactions of smaller size. Currently it is only possible to configure the cache size for all sessions which leads to improper resource allocation for a MySQL Server used for writing binary log of changes in NDB. Solution: Make it possible to configure the binlog transaction cache size used for ndb binlog injector with a new system variable: --ndb-log-cache-size=<value> The new variable can be changed at runtime and it's default value is set to 64MB. All in all the new variable is very much like --binlog- cache-size, just that it only affects the transaction cache used by ndb binlog injector when writing binary log of changes in NDB. Change-Id: Ia6b7ddd238a132fdf74248a5616a06316197ba63
1 parent e5b1a95 commit df61143

28 files changed

+221
-12
lines changed

mysql-test/suite/ndb/r/ndb_basic.result

+1
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ ndb_join_pushdown #
172172
ndb_log_apply_status #
173173
ndb_log_bin #
174174
ndb_log_binlog_index #
175+
ndb_log_cache_size #
175176
ndb_log_empty_epochs #
176177
ndb_log_empty_update #
177178
ndb_log_exclusive_reads #

mysql-test/suite/ndb/r/ndb_basic_3rpl.result

+1
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ ndb_join_pushdown #
172172
ndb_log_apply_status #
173173
ndb_log_bin #
174174
ndb_log_binlog_index #
175+
ndb_log_cache_size #
175176
ndb_log_empty_epochs #
176177
ndb_log_empty_update #
177178
ndb_log_exclusive_reads #

mysql-test/suite/ndb/r/ndb_basic_4rpl.result

+1
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ ndb_join_pushdown #
172172
ndb_log_apply_status #
173173
ndb_log_bin #
174174
ndb_log_binlog_index #
175+
ndb_log_cache_size #
175176
ndb_log_empty_epochs #
176177
ndb_log_empty_update #
177178
ndb_log_exclusive_reads #

mysql-test/suite/ndb/r/ndb_basic_ndbd.result

+1
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ ndb_join_pushdown #
172172
ndb_log_apply_status #
173173
ndb_log_bin #
174174
ndb_log_binlog_index #
175+
ndb_log_cache_size #
175176
ndb_log_empty_epochs #
176177
ndb_log_empty_update #
177178
ndb_log_exclusive_reads #

mysql-test/suite/ndb/t/concurrent_grants.cnf

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ ndbcluster
4444
ndb-wait-connected=30
4545
ndb-wait-setup=120
4646
ndb-extra-logging=99
47+
# Use smaller than default cache size to save resources
48+
ndb-log-cache-size=32768
4749

4850
[mysqld.1.1]
4951
ndb-cluster-connection-pool=1

mysql-test/suite/ndb/t/ndb_addnode_withbinlog.cnf

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ ndb-cluster-connection-pool=3
1616
ndb-extra-logging=99
1717
log-bin=mysql-binlog
1818
ndb-log-bin=1
19+
# Use smaller than default cache size to save resources
20+
ndb-log-cache-size=32768
1921
# Enable load data local functionality
2022
local-infile=true
2123

mysql-test/suite/ndb_binlog/my.cnf

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ ndb-extra-logging=99
2121
local-infile=true
2222

2323
ndb-log-bin=1
24+
# Use smaller than default cache size to save resources
25+
ndb-log-cache-size=32768
2426

2527
# Run this suite with binlog-format=ROW by default
2628
binlog-format= row

mysql-test/suite/ndb_binlog/r/ndb_binlog_cache.result

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
1+
SET @save_ndb_log_cache_size = @@global.ndb_log_cache_size;
2+
SELECT @save_ndb_log_cache_size;
3+
@save_ndb_log_cache_size
4+
32768
5+
SET @@global.ndb_log_cache_size=4096;
6+
SET SESSION ndb_log_cache_size=32768;
7+
ERROR HY000: Variable 'ndb_log_cache_size' is a GLOBAL variable and should be set with SET GLOBAL
8+
SELECT @@global.ndb_log_cache_size;
9+
@@global.ndb_log_cache_size
10+
4096
111
SELECT @@global.binlog_cache_size;
212
@@global.binlog_cache_size
3-
4096
13+
32768
414
SELECT @@global.binlog_stmt_cache_size;
515
@@global.binlog_stmt_cache_size
616
32768
@@ -36,5 +46,24 @@ INSERT INTO t1 VALUES (7, repeat(0x41, 4096), repeat(0x42, 4096));
3646
include/assert.inc [There were >0 writes to IO_CACHE]
3747
# Check that error log contains message indicating cache spill
3848
include/assert.inc [Binary log cache data overflowed to disk]
49+
include/assert.inc [The IO_CACHE should spill to disk]
50+
#
51+
# Check that ndb_log_cache_size can be reconfigured at runtime and the
52+
# large write which previously caused cache spill now fits. This is done
53+
# by increasing cache size and doing the large write again.
54+
SET @@global.ndb_log_cache_size=1024*1024;
55+
BEGIN;
56+
INSERT INTO t1 VALUES (8, repeat(0x41, 1024), repeat(0x42, 1024));
57+
INSERT INTO t1 VALUES (9, repeat(0x41, 1024), repeat(0x42, 1024));
58+
INSERT INTO t1 VALUES (10, repeat(0x41, 1024), repeat(0x42, 1024));
59+
INSERT INTO t1 VALUES (11, repeat(0x41, 1024), repeat(0x42, 1024));
60+
INSERT INTO t1 VALUES (12, repeat(0x41, 1024), repeat(0x42, 1024));
61+
INSERT INTO t1 VALUES (13, repeat(0x41, 1024), repeat(0x42, 1024));
62+
INSERT INTO t1 VALUES (14, repeat(0x41, 1024), repeat(0x42, 1024));
63+
INSERT INTO t1 VALUES (15, repeat(0x41, 1024), repeat(0x42, 1024));
64+
COMMIT;
65+
# Wait for ndb_binlog thread...
66+
include/assert.inc [Write with large cache didn't trigger cache overflow]
67+
SET @@global.ndb_log_cache_size=@save_ndb_log_cache_size;
3968

4069
DROP TABLE t1;

mysql-test/suite/ndb_binlog/t/ndb_binlog_cache.cnf

-8
This file was deleted.

mysql-test/suite/ndb_binlog/t/ndb_binlog_cache.test

+54
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,22 @@
66
-- source include/have_ndb.inc
77
-- source include/have_binlog_format_mixed_or_row.inc
88

9+
# Save original value to allow restoring config before test end
10+
SET @save_ndb_log_cache_size = @@global.ndb_log_cache_size;
11+
SELECT @save_ndb_log_cache_size;
12+
13+
# Configure lowest possible ndb binlog injector cache size to make it possible
14+
# to exceed the size and trigger a "disk spill" further down
15+
SET @@global.ndb_log_cache_size=4096;
16+
17+
# Show that ndb_log_cache_size is a global variable
18+
--error ER_GLOBAL_VARIABLE
19+
SET SESSION ndb_log_cache_size=32768;
20+
921
-- let $cache_qry = SELECT COUNT_WRITE FROM performance_schema.file_summary_by_event_name WHERE event_name LIKE "%io_cache%"
1022

23+
# Check configured values required by test
24+
SELECT @@global.ndb_log_cache_size;
1125
SELECT @@global.binlog_cache_size;
1226
SELECT @@global.binlog_stmt_cache_size;
1327
SELECT NAME, ENABLED FROM performance_schema.setup_instruments WHERE name LIKE "%file/sql/io_cache%";
@@ -69,10 +83,50 @@ save_master_pos;
6983
-- let $assert_cond= [$qry, warnings, 1] >= 1
7084
-- source include/assert.inc
7185

86+
# The temporary file used for extending the cache in the above case can be
87+
# seen in performance_schema by quering the file_instances table, the file
88+
# has "ML" as file name prefix:
89+
# SELECT * FROM performance_schema.file_instances
90+
# WHERE EVENT_NAME = "wait/io/file/sql/io_cache";
91+
# FILE_NAME EVENT_NAME OPEN_COUNT
92+
# /tmp/mysqld.1.1/MLfd=66 wait/io/file/sql/io_cache 1
93+
--let $assert_cond = OPEN_COUNT >= 1 FROM performance_schema.file_instances WHERE EVENT_NAME = "wait/io/file/sql/io_cache"
94+
--let $assert_text = The IO_CACHE should spill to disk
95+
--source include/assert.inc
96+
7297
# Supress the provoked message
7398
-- disable_query_log ONCE
7499
call mtr.add_suppression(".*Binary log cache data overflowed to disk.*");
75100

101+
--echo #
102+
--echo # Check that ndb_log_cache_size can be reconfigured at runtime and the
103+
--echo # large write which previously caused cache spill now fits. This is done
104+
--echo # by increasing cache size and doing the large write again.
105+
106+
SET @@global.ndb_log_cache_size=1024*1024;
107+
BEGIN;
108+
INSERT INTO t1 VALUES (8, repeat(0x41, 1024), repeat(0x42, 1024));
109+
INSERT INTO t1 VALUES (9, repeat(0x41, 1024), repeat(0x42, 1024));
110+
INSERT INTO t1 VALUES (10, repeat(0x41, 1024), repeat(0x42, 1024));
111+
INSERT INTO t1 VALUES (11, repeat(0x41, 1024), repeat(0x42, 1024));
112+
INSERT INTO t1 VALUES (12, repeat(0x41, 1024), repeat(0x42, 1024));
113+
INSERT INTO t1 VALUES (13, repeat(0x41, 1024), repeat(0x42, 1024));
114+
INSERT INTO t1 VALUES (14, repeat(0x41, 1024), repeat(0x42, 1024));
115+
INSERT INTO t1 VALUES (15, repeat(0x41, 1024), repeat(0x42, 1024));
116+
COMMIT;
117+
--source suite/ndb/include/ndb_binlog_wait_own_changes.inc
118+
119+
-- let $after_writes_with_large_cache = `$cache_qry`
120+
#echo after_writes_with_large_cache: $after_writes_with_large_cache;
121+
122+
-- let $assert_text= Write with large cache didn't trigger cache overflow
123+
-- let $assert_cond= $after_writes = $after_writes_with_large_cache
124+
-- source include/assert.inc
125+
126+
# Restore changed config to original value
127+
SET @@global.ndb_log_cache_size=@save_ndb_log_cache_size;
128+
129+
76130
-- echo
77131

78132
DROP TABLE t1;

mysql-test/suite/ndb_binlog/t/ndb_binlog_default_format.cnf

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ ndb-wait-setup=120
2020
ndb-cluster-connection-pool=3
2121
ndb-extra-logging=99
2222
ndb-log-bin=1
23+
# Use smaller than default cache size to save resources
24+
ndb-log-cache-size=32768
2325

2426
# Will be "auto upgraded" to MIXED
2527
binlog-format=STATEMENT

mysql-test/suite/ndb_binlog/t/ndb_binlog_log_reads.cnf

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ ndb-wait-setup=120
1919
ndb-cluster-connection-pool=1
2020
ndb-log-bin=1
2121
binlog-format=row
22-
22+
# Use smaller than default cache size to save resources
23+
ndb-log-cache-size=32768
2324
ndb-log-empty-update
2425

2526
# Enable load data local functionality

mysql-test/suite/ndb_binlog/t/ndb_binlog_variant_ddl.cnf

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ ndb-wait-setup=120
1919
ndb-cluster-connection-pool=1
2020
ndb-log-bin=1
2121
binlog-format=row
22+
# Use smaller than default cache size to save resources
23+
ndb-log-cache-size=32768
2224

2325
[cluster_config.mysqld.1.1]
2426
NodeId=49

mysql-test/suite/ndb_binlog/t/ndb_binlog_variants.cnf

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ ndb-wait-setup=120
1919
ndb-cluster-connection-pool=1
2020
ndb-log-bin=1
2121
binlog-format=row
22+
# Use smaller than default cache size to save resources
23+
ndb-log-cache-size=32768
2224

2325
# Enable load data local functionality
2426
local-infile=true

mysql-test/suite/ndb_ddl/util_tables_drop.cnf

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22

33
[mysqld]
44
ndb-log-bin=1
5+
# Use smaller than default cache size to save resources
6+
ndb-log-cache-size=32768

mysql-test/suite/ndb_rpl/my.cnf

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ ndb-wait-setup=120
2626
ndb-cluster-connection-pool=3
2727
replica-allow-batching
2828
ndb-log-bin=1
29+
# Use smaller than default cache size to save resources
30+
ndb-log-cache-size=32768
2931

3032
# Enable load data local functionality
3133
local-infile=true

mysql-test/suite/ndb_rpl/t/ndb_rpl_3_cluster.cnf

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ ndb-table-temporary=1
3838
ndb-extra-logging=99
3939
binlog-format=row
4040
replica-parallel-workers=1
41+
# Use smaller than default cache size to save resources
42+
ndb-log-cache-size=32768
4143

4244
[cluster_config.mysqld.1.cluster1]
4345
NodeId=49

mysql-test/suite/ndb_rpl/t/ndb_rpl_3site_no_log_updates.cnf

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ log-replica-updates= OFF
3535
log-error-verbosity= 3
3636
binlog-format= row
3737
replica-parallel-workers= 1
38+
# Use smaller than default cache size to save resources
39+
ndb-log-cache-size=32768
3840

3941
[cluster_config.mysqld.1.cluster1]
4042
NodeId= 10

mysql-test/suite/ndb_rpl/t/ndb_rpl_log_updates.cnf

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ ndb-extra-logging=99
3838
log-error-verbosity=3
3939
binlog-format=row
4040
replica-parallel-workers=1
41+
# Use smaller than default cache size to save resources
42+
ndb-log-cache-size=32768
4143

4244
[cluster_config.mysqld.1.cluster1]
4345
NodeId=10

mysql-test/suite/ndb_rpl/t/ndb_rpl_multi_binlog_update.cnf

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ ndb-wait-setup=120
2929
# Default log-replica-updates to off and turn it on
3030
# only selectively for some of the servers in config
3131
log-replica-updates=0
32+
# Use smaller than default cache size to save resources
33+
ndb-log-cache-size=32768
3234

3335

3436
[cluster_config.mysqld.1.1]

mysql-test/suite/ndb_rpl/t/ndb_rpl_stored_grants.cnf

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ ndb-log-orig
2424
ndb-log-bin=1
2525
replica-parallel-workers=1
2626
replicate-ignore-table=test.abc
27+
# Use smaller than default cache size to save resources
28+
ndb-log-cache-size=32768
2729

2830
[mysqld.1.cluster1]
2931
server_id= 1

mysql-test/suite/ndb_tls/ndb_basic.result

+1
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ ndb_join_pushdown #
172172
ndb_log_apply_status #
173173
ndb_log_bin #
174174
ndb_log_binlog_index #
175+
ndb_log_cache_size #
175176
ndb_log_empty_epochs #
176177
ndb_log_empty_update #
177178
ndb_log_exclusive_reads #

mysql-test/suite/rpl_ndb/my.cnf

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ log-bin= master-bin
3131
# for performance reasons
3232
ndb-table-temporary=1
3333
ndb-log-bin=1
34+
# Use smaller than default cache size to save resources
35+
ndb-log-cache-size=32768
3436
replica-parallel-workers=1
3537

3638
ndb-extra-logging=99

sql/binlog.cc

+16
Original file line numberDiff line numberDiff line change
@@ -8386,6 +8386,22 @@ int THD::binlog_setup_trx_data() {
83868386
return 0;
83878387
}
83888388

8389+
bool THD::binlog_configure_trx_cache_size(ulong new_size) {
8390+
// Check expected block size.
8391+
assert((new_size % IO_SIZE) == 0);
8392+
8393+
binlog_cache_mngr *const cache_mngr = thd_get_cache_mngr(this);
8394+
if (cache_mngr == nullptr || !cache_mngr->is_binlog_empty()) {
8395+
// Must exist and be empty
8396+
return true;
8397+
}
8398+
8399+
// Close and reopen with new value
8400+
Binlog_cache_storage *const cache = cache_mngr->get_trx_cache();
8401+
cache->close();
8402+
return cache->open(new_size, max_binlog_cache_size);
8403+
}
8404+
83898405
/**
83908406
83918407
*/

sql/sql_class.h

+18
Original file line numberDiff line numberDiff line change
@@ -1721,6 +1721,24 @@ class THD : public MDL_context_owner,
17211721

17221722
int binlog_setup_trx_data();
17231723

1724+
/**
1725+
* @brief Configure size of binlog transaction cache. Used to configure the
1726+
* size of an individual cache, normally to a value that differs from the
1727+
* default `binlog_cache_size` which controls the size otherwise.
1728+
*
1729+
* @note Assumes that the binlog cache manager already exist (i.e created
1730+
* by call to binlog_setup_trx_data()) and is empty.
1731+
*
1732+
* @param new_size The new size of cache. Value exceeding
1733+
* `max_binlog_cache_size` will be clamped and warning logged. Value must be
1734+
* a multiple of IO_SIZE which is the block size for all binlog cache size
1735+
* related variables.
1736+
*
1737+
* @return true if new cache size can't be configured, in that case the cache
1738+
* is not usable.
1739+
*/
1740+
bool binlog_configure_trx_cache_size(ulong new_size);
1741+
17241742
/*
17251743
Public interface to write RBR events to the binlog
17261744
*/

storage/ndb/plugin/ha_ndbcluster.cc

+32
Original file line numberDiff line numberDiff line change
@@ -18186,6 +18186,37 @@ static MYSQL_SYSVAR_ULONG(
1818618186
0 /* block */
1818718187
);
1818818188

18189+
// Overrides --binlog-cache-size for the ndb binlog thread
18190+
ulong opt_ndb_log_cache_size;
18191+
static void fix_ndb_log_cache_size(THD *thd, SYS_VAR *, void *val_ptr,
18192+
const void *checked) {
18193+
ulong new_size = *static_cast<const ulong *>(checked);
18194+
18195+
// Cap the max value in the same way as other binlog cache size variables
18196+
if (new_size > max_binlog_cache_size) {
18197+
push_warning_printf(
18198+
thd, Sql_condition::SL_WARNING, ER_BINLOG_CACHE_SIZE_GREATER_THAN_MAX,
18199+
"Option ndb_log_cache_size (%lu) is greater than max_binlog_cache_size "
18200+
"(%lu); setting ndb_log_cache_size equal to max_binlog_cache_size.",
18201+
(ulong)new_size, (ulong)max_binlog_cache_size);
18202+
new_size = static_cast<ulong>(max_binlog_cache_size);
18203+
}
18204+
*(static_cast<ulong *>(val_ptr)) = new_size;
18205+
}
18206+
18207+
static MYSQL_SYSVAR_ULONG(
18208+
log_cache_size, /* name */
18209+
opt_ndb_log_cache_size, /* var */
18210+
PLUGIN_VAR_RQCMDARG,
18211+
"Size of the binary log transaction cache used by NDB binlog",
18212+
nullptr, /* check func. */
18213+
fix_ndb_log_cache_size, /* update func. */
18214+
64 * 1024 * 1024, /* default */
18215+
IO_SIZE, /* min */
18216+
ULONG_MAX, /* max */
18217+
IO_SIZE /* block */
18218+
);
18219+
1818918220
bool opt_ndb_clear_apply_status;
1819018221
static MYSQL_SYSVAR_BOOL(
1819118222
clear_apply_status, /* name */
@@ -18599,6 +18630,7 @@ static SYS_VAR *system_variables[] = {
1859918630
MYSQL_SYSVAR(log_transaction_compression),
1860018631
MYSQL_SYSVAR(log_transaction_compression_level_zstd),
1860118632
MYSQL_SYSVAR(log_purge_rate),
18633+
MYSQL_SYSVAR(log_cache_size),
1860218634
MYSQL_SYSVAR(log_fail_terminate),
1860318635
MYSQL_SYSVAR(log_transaction_dependency),
1860418636
MYSQL_SYSVAR(clear_apply_status),

0 commit comments

Comments
 (0)