Skip to content

Commit 42e1815

Browse files
committed
MDEV-16952 Introduce SET GLOBAL innodb_max_purge_lag_wait
Let us introduce a dummy variable innodb_max_purge_lag_wait for waiting that the InnoDB history list length is below the user-specified limit. Specifically, SET GLOBAL innodb_max_purge_lag_wait=0; should wait for all history to be purged. This could be useful when upgrading from an older version to MariaDB 10.3 or later, to avoid hitting MDEV-15912. Note: the history cannot be purged if there exist transactions that may see old versions. Reviewed by: Vladislav Vaintroub
1 parent 8761571 commit 42e1815

File tree

3 files changed

+47
-16
lines changed

3 files changed

+47
-16
lines changed
Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,17 @@
11
# Wait for everything to be purged.
22
# The user should have set innodb_purge_rseg_truncate_frequency=1.
33

4+
--disable_query_log
45
if (!$wait_all_purged)
56
{
6-
let $wait_all_purged= 0;
7+
SET GLOBAL innodb_max_purge_lag_wait= 0;
78
}
8-
let $remaining_expect= `select concat('InnoDB ',$wait_all_purged)`;
9-
10-
let $wait_counter= 600;
11-
while ($wait_counter)
9+
if ($wait_all_purged)
1210
{
13-
--replace_regex /.*History list length ([0-9]+).*/\1/
14-
let $remaining= `SHOW ENGINE INNODB STATUS`;
15-
if ($remaining == $remaining_expect)
16-
{
17-
let $wait_counter= 0;
18-
}
19-
if ($wait_counter)
20-
{
21-
real_sleep 0.1;
22-
dec $wait_counter;
23-
}
11+
eval SET GLOBAL innodb_max_purge_lag_wait= $wait_all_purged;
2412
}
13+
--enable_query_log
14+
15+
--replace_regex /.*History list length ([0-9]+).*/\1/
16+
let $remaining= `SHOW ENGINE INNODB STATUS`;
2517
echo $remaining transactions not purged;

mysql-test/suite/sys_vars/r/sysvars_innodb.result

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,6 +1686,18 @@ NUMERIC_BLOCK_SIZE 0
16861686
ENUM_VALUE_LIST NULL
16871687
READ_ONLY NO
16881688
COMMAND_LINE_ARGUMENT REQUIRED
1689+
VARIABLE_NAME INNODB_MAX_PURGE_LAG_WAIT
1690+
SESSION_VALUE NULL
1691+
DEFAULT_VALUE 4294967295
1692+
VARIABLE_SCOPE GLOBAL
1693+
VARIABLE_TYPE INT UNSIGNED
1694+
VARIABLE_COMMENT Wait until History list length is below the specified limit
1695+
NUMERIC_MIN_VALUE 0
1696+
NUMERIC_MAX_VALUE 4294967295
1697+
NUMERIC_BLOCK_SIZE 0
1698+
ENUM_VALUE_LIST NULL
1699+
READ_ONLY NO
1700+
COMMAND_LINE_ARGUMENT REQUIRED
16891701
VARIABLE_NAME INNODB_MAX_UNDO_LOG_SIZE
16901702
SESSION_VALUE NULL
16911703
DEFAULT_VALUE 10485760

storage/innobase/handler/ha_innodb.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,27 @@ enum default_row_format_enum {
271271
DEFAULT_ROW_FORMAT_DYNAMIC = 2,
272272
};
273273

274+
/** A dummy variable */
275+
static uint innodb_max_purge_lag_wait;
276+
277+
/** Wait for trx_sys_t::rseg_history_len to be below a limit. */
278+
static void innodb_max_purge_lag_wait_update(THD *thd, st_mysql_sys_var *,
279+
void *, const void *limit)
280+
{
281+
const uint l= *static_cast<const uint*>(limit);
282+
if (trx_sys->rseg_history_len <= l)
283+
return;
284+
mysql_mutex_unlock(&LOCK_global_system_variables);
285+
while (trx_sys->rseg_history_len > l)
286+
{
287+
if (thd_kill_level(thd))
288+
break;
289+
srv_wake_purge_thread_if_not_active();
290+
os_thread_sleep(100000);
291+
}
292+
mysql_mutex_lock(&LOCK_global_system_variables);
293+
}
294+
274295
static
275296
void set_my_errno(int err)
276297
{
@@ -20147,6 +20168,11 @@ static MYSQL_SYSVAR_ULONG(max_purge_lag_delay, srv_max_purge_lag_delay,
2014720168
0L, /* Minimum value */
2014820169
10000000UL, 0); /* Maximum value */
2014920170

20171+
static MYSQL_SYSVAR_UINT(max_purge_lag_wait, innodb_max_purge_lag_wait,
20172+
PLUGIN_VAR_RQCMDARG,
20173+
"Wait until History list length is below the specified limit",
20174+
NULL, innodb_max_purge_lag_wait_update, UINT_MAX, 0, UINT_MAX, 0);
20175+
2015020176
static MYSQL_SYSVAR_BOOL(rollback_on_timeout, innobase_rollback_on_timeout,
2015120177
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
2015220178
"Roll back the complete transaction on lock wait timeout, for 4.x compatibility (disabled by default)",
@@ -21195,6 +21221,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
2119521221
MYSQL_SYSVAR(flushing_avg_loops),
2119621222
MYSQL_SYSVAR(max_purge_lag),
2119721223
MYSQL_SYSVAR(max_purge_lag_delay),
21224+
MYSQL_SYSVAR(max_purge_lag_wait),
2119821225
MYSQL_SYSVAR(old_blocks_pct),
2119921226
MYSQL_SYSVAR(old_blocks_time),
2120021227
MYSQL_SYSVAR(open_files),

0 commit comments

Comments
 (0)