[MDEV-14717] RENAME TABLE in InnoDB is not crash-safe Created: 2017-12-20 Updated: 2021-04-28 Resolved: 2017-12-20 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - InnoDB |
| Affects Version/s: | 5.5, 10.0, 10.1, 10.2, 10.3 |
| Fix Version/s: | 10.3.3, 10.2.19 |
| Type: | Bug | Priority: | Major |
| Reporter: | Marko Mäkelä | Assignee: | Marko Mäkelä |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | crash, ddl | ||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description |
|
The RENAME TABLE operation, which is also internally part of ALTER TABLE when ALGORITHM=COPY is in effect, is not crash-safe within InnoDB. Starting with MySQL 5.7.5, where I implemented WL#7142 to speed up InnoDB crash recovery and to avoid silently losing redo log entries for InnoDB data files, InnoDB startup may be refused because of a missing file, because no MLOG_FILE_RENAME2 record will be written during RENAME TABLE:
Before MariaDB 10.2.2 or MySQL 5.7.5, the server should always start up, but it could fail to find the table:
Both problems can be reproduced with the following instrumentation:
and the following test:
Remove the first invocation of restart_mysqld.inc to reproduce the failure to startup. How to fix this?
How to work around the bug? While the server is offline, manually rename the .ibd files back so that they match the data dictionary (and in this case, the .frm files). If we introduced a new undo log record type in a GA version of MariaDB, this could prevent a downgrade to an earlier GA version and violate our compatibility rules. If we started writing MLOG_FILE_RENAME2 redo log records in MariaDB 10.2, then users should not see InnoDB startup failures related to this, but instead they would encounter missing tables. If there was any incomplete transaction that operated on the table, the rollback of that recovered transaction would skip and thus corrupt the table. The status quo would seem better: a startup after manually renaming the .ibd file back should succeed. |
| Comments |
| Comment by Marko Mäkelä [ 2017-12-20 ] | ||||||||||||||||||||||||||||
|
After I implemented MLOG_FILE_RENAME2 redo logging of all .ibd file rename operations, I ran into a different problem on ha_innobase::open():
I then proceeded to revert what looks like a work-around: removing the parameters adjust_space, table_id from fil_space_for_table_exists_in_mem(). It did not make any difference. The cause of this assertion failure is that at startup, before rolling back any transactions, the table was loaded into the data dictionary with the new name. That is, InnoDB essentially performed READ UNCOMMITTED of SYS_TABLES here:
Later, after the incomplete data dictionary transaction was rolled back, on ha_innobase::open() for executing the SELECT, the table would be loaded with the correct name. But, a table with the same ID already existed in the cache, and the assertion fails. | ||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2017-12-20 ] | ||||||||||||||||||||||||||||
|
Fixed in bb-10.2-ext and merged to 10.3. | ||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-09-07 ] | ||||||||||||||||||||||||||||
|
While testing Edit: There is nothing wrong with trx_undo_report_rename(). The redo log flush is initiated in each caller of fil_name_write_rename_low(). There is also nothing wrong with the redo log flushing:
The problem that I observed in I filed | ||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-10-11 ] | ||||||||||||||||||||||||||||
|
In MariaDB 10.2, this fix will remain disabled by default, in order to preserve compatibility with third-party tools.
in the server configuration or add
to the mysqld invocation. This option will only be available in the MariaDB Server 10.2 series. The reason for this is that the crash-safe rename will require an undo log format change, and we can only change the undo log format by making sure that older versions of MariaDB 10.2 will refuse to start after a crash. This redo log format identifier change could cause some third-party tools to fail. | ||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2019-09-26 ] | ||||||||||||||||||||||||||||
|
While renaming tables inside InnoDB should be safe in the event the server process crashes, renaming the files might not be safe when file system recovery is involved. MDEV-20677 was filed to cover those scenarios. |