[MDEV-17158] TRUNCATE is not atomic after MDEV-13564 Created: 2018-09-07  Updated: 2018-09-26  Resolved: 2018-09-10

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB, Tests
Affects Version/s: 10.3.10
Fix Version/s: 10.3.10, 10.2.19

Type: Bug Priority: Blocker
Reporter: Marko Mäkelä Assignee: Marko Mäkelä
Resolution: Fixed Votes: 0
Labels: recovery

Issue Links:
Relates
relates to MDEV-13564 TRUNCATE TABLE and undo tablespace tr... Closed
relates to MDEV-14717 RENAME TABLE in InnoDB is not crash-safe Closed

 Description   

I observed this both on 10.2 and 10.3 when testing MDEV-13564. The following test would occasionally fail on a cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_ASAN=1 build:

./mtr --parallel=40 --repeat=100 --mysqld=--debug=d,ib_log innodb.truncate_crash{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,}

The reason for this appears to be that the following call does not always guarantee a write to the redo log:

log_write_up_to(mtr.commit_lsn(), true);

Such a call is present in all callers of fil_name_write_rename_low(), yet sometimes we end up with losing the table, because no undo log was persisted for the incomplete transaction despite this call.



 Comments   
Comment by Elena Stepanova [ 2018-09-07 ]

The test fails for me like this:

innodb.truncate_crash 'innodb'           w4 [ 52 fail ]
        Test ended at 2018-09-07 23:06:13
 
CURRENT_TEST: innodb.truncate_crash
mysqltest: At line 20: query 'SELECT * FROM t1' failed: 1932: Table 'test.t1' doesn't exist in engine

If it's not an indication of the reported problem, then could you please paste the output which does indicate it?

Comment by Marko Mäkelä [ 2018-09-10 ]

I made a wrong diagnosis. log_write_up_to() appears to behave as it should. The actual problem is in MDEV-13564: ha_innobase::truncate() will invoke innobase_rename_table(), which will commit the transaction prematurely. Because of this, the original table would be persistently renamed to a temporary name before the new empty table has been created.

Comment by Marko Mäkelä [ 2018-09-10 ]

It turned out that there were multiple InnoDB transaction commits inside ha_innobase::truncate() before the completion of ha_innobase::create(). Also the crash recovery had to be revised a bit, because the new empty file has to be deleted before the old non-empty table can be renamed back to the old file.

Generated at Thu Feb 08 08:34:21 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.