[MDEV-13564] TRUNCATE TABLE and undo tablespace truncation are not compatible with Mariabackup Created: 2017-08-17 Updated: 2023-12-22 Resolved: 2018-09-07 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Backup, Storage Engine - InnoDB |
| Affects Version/s: | 10.2.2 |
| Fix Version/s: | 10.3.10, 10.4.0, 10.2.19 |
| Type: | Bug | Priority: | Major |
| Reporter: | Marko Mäkelä | Assignee: | Marko Mäkelä |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | backup, ddl, performance, recovery | ||
| Attachments: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description |
|
MariaDB 10.2.2 imported MySQL 5.7.9, which introduced separate log files, for server startup to determine if any tables or undo tablespace need "truncate fixup". There is no logic in Mariabackup to deal with this. A cleaner solution would be to remove the separate log files and to make the InnoDB redo log self-contained with respect to the truncate operations. This would likely require writing a new redo log record type MLOG_FILE_CREATE that would cause the file to be initialized from the scratch, followed by some page-level redo log records that would initialize the page contents.
|
| Comments |
| Comment by Marko Mäkelä [ 2018-04-23 ] | |||||||||||||||||||||||||||||||||||||||||
|
monty mentioned that a customer would like to have non-locking TRUNCATE TABLE: Old transactions that are reading from the table would continue to see the table contents. The TRUNCATE action would basically rename the old table to an internal #sql name so that This could be refined further by implementing a multi-versioned data dictionary cache (which is work mostly outside InnoDB). In that case, old transactions would continue to see the table contents as it was before the TRUNCATE, even when the first access to the table is after the TRUNCATE was executed. (Write transactions would always refer to the newest table definition.) | |||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-08-02 ] | |||||||||||||||||||||||||||||||||||||||||
|
I believe that we need a twofold fix:
In this way, the TruncateLogger and some related code can be removed. But we will have to keep TruncateLogParser in order to be able to crash-upgrade from MariaDB Server 10.2 or 10.3 prior to this fix. In MariaDB Server 10.2, TRUNCATE will no longer be crash-safeMariaDB Server 10.2 is affected by If the server is killed in the middle of the BEGIN; RENAME; CREATE; COMMIT; transaction, after recovery we could end up with the table not being truncated, and with the data file having been renamed to #sql-ib….ibd. Some manual recovery would then be needed (such as, renaming the .frm file to match the .ibd file name, then RENAME TABLE `#mysql50##sql-ib…` TO original_table_name; If the server is killed before the original table (#sql-ib….ibd) is dropped, then the table would remain orphaned after recovery. It could be dropped by copying the .frm file and then issuing DROP TABLE `#mysql50##sql-ib…`;. MariaDB Server 10.3 is not affected by these issues, because there RENAME operations will be correctly rolled back, and #sql tables will be dropped on startup ( | |||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-08-02 ] | |||||||||||||||||||||||||||||||||||||||||
|
truncate.patch | |||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-08-16 ] | |||||||||||||||||||||||||||||||||||||||||
|
Mariabackup starting with 10.2.18 and 10.3.10 will refuse operation if any MLOG_TRUNCATE record was written (by the incompatible implementation of TRUNCATE TABLE). Unfortunately we cannot easily detect if the incompatible form of undo log tablespace truncation was attempted. I plan to implement both undo log tablespace truncation and TRUNCATE TABLE in a backup-safe way in the first affected series (MariaDB Server 10.2). | |||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-08-28 ] | |||||||||||||||||||||||||||||||||||||||||
|
There was an issue with mysql.gtid_slave_pos. With the old truncate, it was not a problem to have open table handles lingering around:
Also, mroonga must pass the table options, because ha_innobase::truncate() will be calling ha_innobase::create():
| |||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-08-28 ] | |||||||||||||||||||||||||||||||||||||||||
|
I have pushed this to bb-10.2-marko for testing. There are 2 open issues:
These issues could be resolved by implementing changes that will break crash-downgrade to earlier versions in the 10.2 or 10.3 series:
| |||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-08-31 ] | |||||||||||||||||||||||||||||||||||||||||
|
For the record, this would also fix the following hang, which I observed in innodb_zip.wl6501_scale_1:
The above I/O thread is waiting for an adaptive hash index latch, which is being held by TRUNCATE (which appears to have initiated the flush and eviction):
| |||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-09-05 ] | |||||||||||||||||||||||||||||||||||||||||
|
bb-10.4-marko removes code for supporting crash-upgrade of TRUNCATE TABLE or undo tablespace truncation from pre- | |||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-09-06 ] | |||||||||||||||||||||||||||||||||||||||||
|
To make the new TRUNCATE crash-safe in 10.2, I backported With this, a crash-downgrade of a RENAME (or TRUNCATE or table-rebuilding ALTER TABLE or OPTIMIZE TABLE) operation to an earlier 10.2 version would trigger a debug assertion failure during rollback, in trx_roll_pop_top_rec_of_trx():
In a non-debug build, cause the undo log record to be misinterpreted as an update. The table name would be misinterpreted as DB_TRX_ID,DB_ROLL_PTR and the PRIMARY KEY of the table. In the highly unlikely event that a record is found, the execution would be aborted in row_undo_mod(), on the switch (node->rec_type). Normally, the non-debug build would crash inside ha_innobase::open():
I am not sure if this really counts as a regression. 10.2 without | |||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-09-06 ] | |||||||||||||||||||||||||||||||||||||||||
|
We can prevent a crash-downgrade to earlier MariaDB 10.2 versions by changing the InnoDB redo log format identifier to the 10.3 identifier, and by introducing a subformat identifier so that 10.2 can continue to refuse crash-downgrade from 10.3 or later. After a clean shutdown, a downgrade to MariaDB 10.2.13 or later would still be possible. Older MariaDB 10.2 are missing | |||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-09-07 ] | |||||||||||||||||||||||||||||||||||||||||
|
Even though I prepared a fix for 10.2, I decided not to push it yet, because I fear that | |||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-09-13 ] | |||||||||||||||||||||||||||||||||||||||||
|
We decided not to push this to 10.2.18, because it backports a large amount of code to 10.2, which could be risky right before a 10.2 release. So, the backport could be merged to 10.2.19 at the earliest. Note that the crash-downgrade prevention for 10.2 will prevent Percona Xtrabackup from working with MariaDB Server 10.2 with the backport included. (Xtrabackup already does not work with MariaDB Server 10.3 or later.) | |||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-10-10 ] | |||||||||||||||||||||||||||||||||||||||||
|
bb-10.2-marko Edit: the option was renamed to innodb_safe_truncate. | |||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-10-11 ] | |||||||||||||||||||||||||||||||||||||||||
|
Buildbot seems to be OK with the change. I conducted a manual test of crash-downgrading to mariadb-10.2.18:
Once the server is killed by the test, switch to the 10.2.18 executable (using the file command in GDB) and restart (run in GDB). With the first test (which uses the backup-safe mechanism), the InnoDB in MariaDB Server 10.2.18 would refuse to start up, after emitting the following message to the error log:
With the second test, which uses MySQL 5.7’s backup-unsafe but crash-safe TRUNCATE TABLE, the MariaDB 10.2.18 server would parse and apply the old-format redo log and the ib_*_*_trunc.log just fine. That test is restarting the server several times. I ran the test twice; first, switching to 10.2.18 on the first restart, and second, switching to 10.2.18 on the second restart and on subsequent restarts, switching between 10.2.18 and this 10.2.19 revision. | |||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-10-17 ] | |||||||||||||||||||||||||||||||||||||||||
|
The default value for the 10.2-specific parameter will be innodb_safe_truncate=ON. |