1
0
mirror of https://github.com/MariaDB/server.git synced 2025-05-25 13:42:52 +03:00

10 Commits

Author SHA1 Message Date
Marko Mäkelä
d5a2bc6a0f Merge 10.2 into 10.3 2019-04-04 19:41:12 +03:00
Marko Mäkelä
cad56fbaba MDEV-18733 MariaDB slow start after crash recovery
If InnoDB crash recovery was needed, the InnoDB function srv_start()
would invoke extra validation, reading something from every InnoDB
data file. This should be unnecessary now that MDEV-14717 made
RENAME operations crash-safe inside InnoDB (which can be
disabled in MariaDB 10.2 by setting innodb_safe_truncate=OFF).

dict_check_sys_tables(): Skip tables that would be dropped by
row_mysql_drop_garbage_tables(). Perform extra validation only
if innodb_safe_truncate=OFF, innodb_force_recovery=0 and
crash recovery was needed.

dict_load_table_one(): Validate the root page of the table.
In this way, we can deny access to corrupted or mismatching tables
not only after crash recovery, but also after a clean shutdown.
2019-04-03 19:56:03 +03:00
Sergei Golubchik
b64fde8f38 Merge branch '10.2' into 10.3 2019-03-17 13:06:41 +01:00
Marko Mäkelä
d3afdb1e8f Datafile::validate_first_page(): Change some ERROR to Note
On startup, if the InnoDB doublewrite buffer can be used to
recover a corrupted page, raising an ERROR about a recoverable
error seems inappropriate. Issue Note instead, and adjust
tests accordingly.

Also, correctly validate the tablespace ID in the files.
2019-03-14 10:15:50 +02:00
Marko Mäkelä
df51dc28f5 Fix tests for innodb_checksum_algorithm=strict_crc32
In tests that directly write InnoDB data file pages,
compute the innodb_checksum_algorithm=crc32 checksums,
instead of writing the 0xdeadbeef value used by
innodb_checksum_algorithm=none. In this way, these tests
will not cause failures when executing
./mtr --mysqld=--loose-innodb-checksum-algorithm=strict_crc32
2019-02-16 12:06:52 +02:00
Marko Mäkelä
61b32df931 Merge 10.2 into 10.3 2018-10-10 06:45:19 +03:00
Marko Mäkelä
00b6c7d8fc MDEV-16946 innodb.alter_kill failed in buildbot with wrong result
Ensure that no redo log checkpoint occurs in a critical section
of a recovery test.
2018-10-10 06:31:43 +03:00
Marko Mäkelä
2610c26a53 MDEV-16273 innodb.alter_kill fails Unknown storage engine 'InnoDB'
The test is shutting down InnoDB, corrupting a file, and finally
restarting InnoDB. Before the shutdown, the test created the table
and inserted some records. Before MDEV-12288, there would be no access
to the table after server restart, but after MDEV-12288 purge would
reset the transaction identifier after the INSERT, and this would
sometimes happen after the restart.

To make the test deterministic, wait for purge to complete before the
shutdown.
2018-10-10 06:14:14 +03:00
Thirunarayanan Balathandayuthapani
91659983eb Adjust the tests for MariaDB.
New added test case: alter_kill in innodb suite.
2018-05-16 15:03:09 +05:30
Marko Mäkelä
ac2410f6d8 Bug#19330255 WL#7142 - CRASH DURING ALTER TABLE LEADS TO DATA DICTIONARY INCONSISTENCY
The server crashes on a SELECT because of space id mismatch. The
mismatch happens if the server crashes during an ALTER TABLE.

There are actually two cases of inconsistency, and three fixes needed
for the InnoDB problems.

We have dictionary data (tablespace or table name) in 3 places:

(a) The *.frm file is for the old table definition.
(b) The InnoDB data dictionary is for the new table definition.
(c) The file system did not rename the tablespace files yet.

In this fix, we will not care if the *.frm file is in sync with the
InnoDB data dictionary and file system. We will concentrate on the
mismatch between (b) and (c).

Two scenarios have been mentioned in this bug report. The simpler one
first:

1. The changes to SYS_TABLES were committed, and MLOG_FILE_RENAME2
records were written in a single mini-transaction commit.
The files were not yet renamed in the file system.
2a. The server is killed, without making a log checkpoint.
3a. The server refuses to start up, because replaying MLOG_FILE_RENAME2
fails.

I failed to repeat this myself. I repeated step 3a with a saved
dataset. The problem seems to be that MLOG_FILE_RENAME2 replay is
incorrectly being skipped when there is no page-redo log or
MLOG_FILE_NAME record for the old name of the tablespace.

FIX#1: Recover the id-to-name mapping also from MLOG_FILE_RENAME2
records when scanning the redo log. It is not necessary to write
MLOG_FILE_NAME records in addition to MLOG_FILE_RENAME2 records for
renaming tablespace files.

The scenario in the original Description involves a log checkpoint:
1. The changes to SYS_TABLES were committed, and MLOG_FILE_RENAME2
records were written in a single mini-transaction commit.
2. A log checkpoint and a server kill was injected.
3. Crash recovery will see no records (other than the MLOG_CHECKPOINT).
4. dict_check_tablespaces_and_store_max_id() will emit a message about
a non-found table #sql-ib22*.
5. A mismatch is triggering the assertion failure.

In my test, at step 4 the SYS_TABLES root page (0:8) contains these 3
records right before the page supremum:
* delete-marked (committed) name=#sql-ib21* record, with space=10.
* name=#sql-ib22*, space=9.
* name=t1, space=10.
space=10 is the rebuilt table (#sql-ib21*.ibd in the file system).
space=9 is the old table (t1.ibd in the file system).

The function dict_check_tablespaces_and_store_max_id() will enter
t1.ibd with space_id=10 into the fil_system cache without noticing
that t1.ibd contains space_id=9, because it invokes
fil_open_single_table_tablespace() with validate=false.

In MySQL 5.6, the space_id from all *.ibd files are being read when
the redo log checkpoint LSN disagrees with the FIL_PAGE_FILE_FLUSH_LSN
in the system tablespace. This field is only updated during a clean
shutdown, after performing the final log checkpoint.

FIX#2: dict_check_tablespaces_and_store_max_id() should pass
validate=true to fil_open_single_table_tablespace() when a non-clean
shutdown is detected, forcing the first page of each *.ibd file to be
read. (We do not want to slow down startup after a normal shutdown.)

With FIX#2, the SELECT would fail to find the table. This would
introduce a regression, because before WL#7142, a copy of the table
was accessible after recovery.

FIX#3: Maintain a list of MLOG_FILE_RENAME2 records that have been
written to the redo log, but not performed yet in the file system.
When performing a checkpoint, re-emit these records to the redo
log. In this way, a mismatch between (b) and (c) should be impossible.

fil_name_process(): Refactored from fil_name_parse(). Adds an item to
the id-to-filename mapping.

fil_name_parse(): Parses and applies a MLOG_FILE_NAME,
MLOG_FILE_DELETE or MLOG_FILE_RENAME2 record. This implements FIX#1.

fil_name_write_rename(): A wrapper function for writing
MLOG_FILE_RENAME2 records.

fil_op_replay_rename(): Apply MLOG_FILE_RENAME2 records. Replaces
fil_op_log_parse_or_replay(), whose logic was moved to fil_name_parse().

fil_tablespace_exists_in_mem(): Return fil_space_t* instead of bool.

dict_check_tablespaces_and_store_max_id(): Add the parameter
"validate" to implement FIX#2.

log_sys->append_on_checkpoint: Extra log records to append in case of
a checkpoint. Needed for FIX#3.

log_append_on_checkpoint(): New function, to update
log_sys->append_on_checkpoint.

mtr_write_log(): New function, to append mtr_buf_t to the redo log.

fil_names_clear(): Append the data from log_sys->append_on_checkpoint
if needed.

ha_innobase::commit_inplace_alter_table(): Add any MLOG_FILE_RENAME2
records to log_sys->append_on_checkpoint(), and remove them once the
files have been renamed in the file system.

mtr_buf_copy_t: A helper functor for copying a mini-transaction log.

rb#6282 approved by Jimmy Yang
2018-05-16 15:03:09 +05:30