Skip to content

Commit 6c0eb29

Browse files
Thirunarayanansanja-byelkin
authored andcommitted
MDEV-34200 InnoDB tries to write to read-only system tablespace
in buf_dblwr_t::init_or_load_pages() - InnoDB fails to set the TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED flag in transaction system header page while recreating the undo log tablespaces buf_dblwr_t::init_or_load_pages(): Tries to reset the space id and try to write into doublewrite buffer even when read_only mode is enabled. In srv_all_undo_tablespaces_open(), InnoDB should try to open the extra unused undo tablespaces instead of trying to creating it.
1 parent d2c9d86 commit 6c0eb29

File tree

7 files changed

+88
-7
lines changed

7 files changed

+88
-7
lines changed

mysql-test/suite/innodb/r/row_format_redundant.result

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
SET GLOBAL innodb_fast_shutdown=0;
2-
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
2+
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb_undo_directory=MYSQLTEST_VARDIR/tmp/undo_dir --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
33
#
44
# Bug#21644827 - FTS, ASSERT !SRV_READ_ONLY_MODE || M_IMPL.M_LOG_MODE ==
55
# MTR_LOG_NO_REDO
@@ -25,7 +25,7 @@ c varchar(150), index k1(c(99), b(56)), index k2(b(5), c(10))) engine=InnoDB
2525
row_format=redundant;
2626
insert into t3 values(444, 'dddd', 'bbbbb', 'aaaaa');
2727
insert into t3 values(555, 'eeee', 'ccccc', 'aaaaa');
28-
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --innodb-read-only
28+
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb_undo_directory=MYSQLTEST_VARDIR/tmp/undo_dir --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --innodb-read-only
2929
SELECT COUNT(*) FROM t1;
3030
COUNT(*)
3131
4096
@@ -41,14 +41,14 @@ TRUNCATE TABLE t2;
4141
ERROR HY000: Table 't2' is read only
4242
TRUNCATE TABLE t3;
4343
ERROR HY000: Table 't3' is read only
44-
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --skip-innodb-fast-shutdown
44+
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb_undo_directory=MYSQLTEST_VARDIR/tmp/undo_dir --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --skip-innodb-fast-shutdown
4545
TRUNCATE TABLE t1;
4646
TRUNCATE TABLE t2;
4747
TRUNCATE TABLE t3;
4848
corrupted SYS_TABLES.MIX_LEN for test/t1
4949
corrupted SYS_TABLES.MIX_LEN for test/t2
5050
corrupted SYS_TABLES.MIX_LEN for test/t3
51-
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --skip-innodb-fast-shutdown
51+
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb_undo_directory=MYSQLTEST_VARDIR/tmp/undo_dir --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --skip-innodb-fast-shutdown
5252
TRUNCATE TABLE t1;
5353
ERROR 42S02: Table 'test.t1' doesn't exist in engine
5454
TRUNCATE TABLE t2;

mysql-test/suite/innodb/r/undo_upgrade.result

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,27 @@ SELECT @@global.innodb_undo_tablespaces;
6262
# Should list 2 undo log tablespaces, not 4
6363
undo001
6464
undo002
65+
#
66+
# MDEV-34200 InnoDB tries to write to read-only
67+
# system tablespace in buf_dblwr_t::init_or_load_pages()
68+
#
69+
SET GLOBAL innodb_fast_shutdown=0;
70+
# restart: --innodb_undo_tablespaces=4
71+
# Should list 4 undo log tablespaces
72+
undo001
73+
undo002
74+
undo003
75+
undo004
76+
set global innodb_fast_shutdown=0;
77+
# restart: --innodb_read_only=1
78+
set global innodb_fast_shutdown=0;
79+
# restart: --innodb-data-file-path=ibdata1:1M:autoextend --innodb_undo_directory=MYSQLTEST_VARDIR/tmp/undo_dir --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/bugdir --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/bugdir --innodb_undo_tablespaces=3
80+
# Should list 3 undo log tablespaces
81+
undo001
82+
undo002
83+
undo003
84+
set global innodb_fast_shutdown=0;
85+
# restart: --innodb-data-file-path=ibdata1:1M:autoextend --innodb_undo_directory=MYSQLTEST_VARDIR/tmp/undo_dir --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/bugdir_1 --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/bugdir_1 --innodb_undo_tablespaces=0
86+
# Shouldn't list 0 undo log tablespaces
87+
set global innodb_fast_shutdown=0;
88+
# restart

mysql-test/suite/innodb/t/row_format_redundant.test

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@ let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
1616

1717
let bugdir= $MYSQLTEST_VARDIR/tmp/row_format_redundant;
1818
--mkdir $bugdir
19+
let undodir= $MYSQLTEST_VARDIR/tmp/undo_dir;
20+
--mkdir $undodir
21+
1922
--let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err
2023

2124
--let $d=--innodb-data-home-dir=$bugdir --innodb-log-group-home-dir=$bugdir
2225
--let $d=$d --innodb-data-file-path=ibdata1:1M:autoextend
23-
--let $d=$d --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
26+
--let $d=$d --innodb_undo_directory=$undodir --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
2427
--let $restart_parameters= $d
2528
# Ensure that any DDL records from previous tests have been purged.
2629
SET GLOBAL innodb_fast_shutdown=0;
@@ -153,6 +156,7 @@ DROP TABLE t2,t3;
153156
--list_files $bugdir
154157
--remove_files_wildcard $bugdir
155158
--rmdir $bugdir
159+
--rmdir $undodir
156160

157161
# Remove the data file, because DROP TABLE skipped it for the "corrupted" table
158162
--let MYSQLD_DATADIR=`select @@datadir`

mysql-test/suite/innodb/t/table_flags.test

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,15 @@ let MYSQLD_DATADIR=`select @@datadir`;
2929

3030
let bugdir= $MYSQLTEST_VARDIR/tmp/table_flags;
3131
--mkdir $bugdir
32+
let undodir= $MYSQLTEST_VARDIR/tmp/undo_dir;
33+
--mkdir $undodir
34+
3235
--let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err
3336

3437
--let $d=--innodb-data-home-dir=$bugdir --innodb-log-group-home-dir=$bugdir
3538
--let $d=$d --innodb-data-file-path=ibdata1:1M:autoextend
3639
--let $d=$d --innodb-undo-tablespaces=0
37-
--let $d=$d --skip-innodb-fast-shutdown
40+
--let $d=$d --skip-innodb-fast-shutdown --innodb_undo_directory=$undodir
3841
--let $restart_noprint=1
3942
--let $restart_parameters=$d --innodb-stats-persistent=0
4043
--source include/restart_mysqld.inc
@@ -233,6 +236,7 @@ DROP TABLE tr,tc,td,tz,tp;
233236
--list_files $bugdir
234237
--remove_files_wildcard $bugdir
235238
--rmdir $bugdir
239+
--rmdir $undodir
236240

237241
call mtr.add_suppression("ERROR HY000: Can't create table `test`.`t1`");
238242
--error ER_CANT_CREATE_TABLE

mysql-test/suite/innodb/t/undo_upgrade.test

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,46 @@ SELECT @@global.innodb_undo_tablespaces;
7676

7777
--echo # Should list 2 undo log tablespaces, not 4
7878
list_files $MYSQLD_DATADIR undo*;
79+
80+
--echo #
81+
--echo # MDEV-34200 InnoDB tries to write to read-only
82+
--echo # system tablespace in buf_dblwr_t::init_or_load_pages()
83+
--echo #
84+
85+
SET GLOBAL innodb_fast_shutdown=0;
86+
let $restart_parameters=--innodb_undo_tablespaces=4;
87+
--source include/restart_mysqld.inc
88+
--echo # Should list 4 undo log tablespaces
89+
list_files $MYSQLD_DATADIR undo*;
90+
91+
set global innodb_fast_shutdown=0;
92+
let $restart_parameters=--innodb_read_only=1;
93+
--source include/restart_mysqld.inc
94+
95+
set global innodb_fast_shutdown=0;
96+
let bugdir= $MYSQLTEST_VARDIR/tmp/bugdir;
97+
mkdir $bugdir;
98+
let undodir= $MYSQLTEST_VARDIR/tmp/undo_dir;
99+
mkdir $undodir;
100+
let $d= --innodb-data-file-path=ibdata1:1M:autoextend;
101+
let $d=$d --innodb_undo_directory=$undodir;
102+
let $restart_parameters= $d --innodb-data-home-dir=$bugdir --innodb-log-group-home-dir=$bugdir --innodb_undo_tablespaces=3;
103+
--source include/restart_mysqld.inc
104+
--echo # Should list 3 undo log tablespaces
105+
list_files $undodir undo*;
106+
107+
let bugdir_1= $MYSQLTEST_VARDIR/tmp/bugdir_1;
108+
mkdir $bugdir_1;
109+
110+
set global innodb_fast_shutdown=0;
111+
let $restart_parameters= $d --innodb-data-home-dir=$bugdir_1 --innodb-log-group-home-dir=$bugdir_1 --innodb_undo_tablespaces=0;
112+
--source include/restart_mysqld.inc
113+
--echo # Shouldn't list 0 undo log tablespaces
114+
list_files $undodir undo*;
115+
116+
set global innodb_fast_shutdown=0;
117+
let $restart_parameters=;
118+
--source include/restart_mysqld.inc
119+
rmdir $bugdir;
120+
rmdir $bugdir_1;
121+
rmdir $undodir;

storage/innobase/buf/buf0dblwr.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ dberr_t buf_dblwr_t::init_or_load_pages(pfs_os_file_t file, const char *path)
284284
init(TRX_SYS_DOUBLEWRITE + read_buf);
285285

286286
const bool upgrade_to_innodb_file_per_table=
287+
!srv_read_only_mode &&
287288
mach_read_from_4(TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED +
288289
TRX_SYS_DOUBLEWRITE + read_buf) !=
289290
TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N;

storage/innobase/srv/srv0start.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,11 @@ inline dberr_t trx_sys_t::reset_page(mtr_t *mtr)
369369
sys_header->page.frame + TRX_SYS_DOUBLEWRITE
370370
+ FSEG_HEADER_SIZE + TRX_SYS_DOUBLEWRITE_REPEAT,
371371
sys_header->page.frame + TRX_SYS_DOUBLEWRITE + FSEG_HEADER_SIZE, 12);
372+
mtr->write<4>(
373+
*sys_header,
374+
TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED +
375+
sys_header->page.frame,
376+
TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N);
372377
}
373378

374379
return DB_SUCCESS;
@@ -822,7 +827,7 @@ static dberr_t srv_all_undo_tablespaces_open(bool create_new_undo,
822827
{
823828
char name[OS_FILE_MAX_PATH];
824829
snprintf(name, sizeof name, "%s/undo%03u", srv_undo_dir, i);
825-
uint32_t space_id= srv_undo_tablespace_open(create_new_undo, name, i);
830+
uint32_t space_id= srv_undo_tablespace_open(false, name, i);
826831
if (!space_id || space_id == ~0U)
827832
break;
828833
if (0 == srv_undo_tablespaces_open++)

0 commit comments

Comments
 (0)