Commit 53c6c823 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-33464 Crash when innodb_max_undo_log_size is set to innodb_page_size*4294967296

purge_sys_t::truncating_tablespace(): Clamp the
innodb_max_undo_log_size to the maximum number of pages
before converting the result into a 32-bit unsigned integer.

This fixes up commit f8c88d90 (MDEV-33213).

In later major versions, we would use 32-bit unsigned integer here
due to commit ca501ffb
and the code would crash also on 64-bit processors.

Reviewed by: Debarun Banerjee
parent 691f9239
...@@ -25,6 +25,7 @@ delete from t1; ...@@ -25,6 +25,7 @@ delete from t1;
connection con2; connection con2;
delete from t2; delete from t2;
connection con1; connection con1;
SET GLOBAL innodb_max_undo_log_size = @@GLOBAL.innodb_page_size * 4294967296;
SET GLOBAL innodb_undo_log_truncate = 1; SET GLOBAL innodb_undo_log_truncate = 1;
commit; commit;
disconnect con1; disconnect con1;
...@@ -33,6 +34,8 @@ commit; ...@@ -33,6 +34,8 @@ commit;
disconnect con2; disconnect con2;
connection default; connection default;
SET GLOBAL innodb_max_purge_lag_wait=0; SET GLOBAL innodb_max_purge_lag_wait=0;
SET GLOBAL innodb_max_undo_log_size=DEFAULT;
SET GLOBAL innodb_max_purge_lag_wait=0;
set global innodb_fast_shutdown=0; set global innodb_fast_shutdown=0;
# restart # restart
drop table t1, t2; drop table t1, t2;
...@@ -42,6 +42,7 @@ connection con1; reap; send delete from t1; ...@@ -42,6 +42,7 @@ connection con1; reap; send delete from t1;
connection con2; reap; delete from t2; connection con2; reap; delete from t2;
connection con1; reap; connection con1; reap;
SET GLOBAL innodb_max_undo_log_size = @@GLOBAL.innodb_page_size * 4294967296;
SET GLOBAL innodb_undo_log_truncate = 1; SET GLOBAL innodb_undo_log_truncate = 1;
commit; disconnect con1; commit; disconnect con1;
connection con2; commit; disconnect con2; connection con2; commit; disconnect con2;
...@@ -52,6 +53,8 @@ connection default; ...@@ -52,6 +53,8 @@ connection default;
let $trx_before= `SHOW ENGINE INNODB STATUS`; let $trx_before= `SHOW ENGINE INNODB STATUS`;
let $trx_before= `select substr('$trx_before',9)+2`; let $trx_before= `select substr('$trx_before',9)+2`;
SET GLOBAL innodb_max_purge_lag_wait=0;
SET GLOBAL innodb_max_undo_log_size=DEFAULT;
SET GLOBAL innodb_max_purge_lag_wait=0; SET GLOBAL innodb_max_purge_lag_wait=0;
set global innodb_fast_shutdown=0; set global innodb_fast_shutdown=0;
--source include/restart_mysqld.inc --source include/restart_mysqld.inc
......
...@@ -669,7 +669,9 @@ fil_space_t *purge_sys_t::truncating_tablespace() ...@@ -669,7 +669,9 @@ fil_space_t *purge_sys_t::truncating_tablespace()
if (space || srv_undo_tablespaces_active < 2 || !srv_undo_log_truncate) if (space || srv_undo_tablespaces_active < 2 || !srv_undo_log_truncate)
return space; return space;
const ulint size= ulint(srv_max_undo_log_size >> srv_page_size_shift); const uint32_t size=
uint32_t(std::min(ulonglong{std::numeric_limits<uint32_t>::max()},
srv_max_undo_log_size >> srv_page_size_shift));
for (ulint i= truncate_undo_space.last, j= i;; ) for (ulint i= truncate_undo_space.last, j= i;; )
{ {
if (fil_space_t *s= undo_truncate_try(srv_undo_space_id_start + i, size)) if (fil_space_t *s= undo_truncate_try(srv_undo_space_id_start + i, size))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment