[MDEV-23844] Atomic DROP TABLE (single table) Created: 2020-09-29  Updated: 2022-11-01  Resolved: 2021-05-20

Status: Closed
Project: MariaDB Server
Component/s: Data Definition - Create Table
Fix Version/s: 10.6.1

Type: Task Priority: Critical
Reporter: Michael Widenius Assignee: Michael Widenius
Resolution: Fixed Votes: 1
Labels: None

Issue Links:
Blocks
blocks MDEV-24589 DROP TABLE is not crash-safe Closed
PartOf
is part of MDEV-17567 Atomic DDL Closed

 Description   

Atomic DROP TABLE

The purpose of this task is to ensure that DROP TABLE is atomic.
As DROP TABLE cannot be rolled back, it will work a bit different
than atomic RENAME TABLE.

If the server crashes during drop table, at restart the last drop that
was 'incompletely done' will be completed and then we will log what was
actually dropped to the binary log.

We don't have to log temporary tables as on restart a log entry is written
that causes the slave to automatically drop all temporary tables from
this master.

Note that only single table DROP TABLE is atomic. If one drops multiple tables in the same statement and there is a crash, those tables that was dropped will continue to be dropped while any other tables will be left intact. This will be fixed in a future task where we will make multi-table drop table atomic.

This task also includes atomic DROP VIEW

How drop table works in 10.5:

- Parser ensures that one can't have the same table name twice in
  the table list
- All temporary tables are 'opened' with
  thd->open_temporary_tables(all_tables),
- mysql_rm_table() is called
   - Abort if the user tries to drop a log table
   - Delete statistics for all tables
   - Call lock_table_names for all tables
   - Call mysql_rm_table_no_locks()
     - Loop over all tables
       - Drop the table, if possible. This is a 'force drop' so even
         tables that have only part of table files (after a possible crashed
         server) will be able to drop their files.
     - Write to the binary log what was actually dropped

Special cases to consider:

  • Dropping temporary tables and normal tables in same query
  • Dropping tables that are discovered
  • If we get a crash during drop table, we should finalize the drop of last table
    that was partially dropped but not drop any more tables. In particular,
    if no table was dropped before the server crashed, then no table should
    be dropped during recovery.

How atomic drop table should work:

Normal operation

- Log to ddl log:
  - Query
   - Log names of all not temporary objects
   - Log type of query: 'drop view' and 'drop_sequence' arguments to
     mysql_rm_table_no_locks
   - xid of query in binary log
 
- Loop over all tables/views
   - Log table or view to be dropped to ddl log
   - Drop table
   - Mark in the ddl log that drop was done and now it is time to drop triggers
   - Drop triggers for the table
   - Mark in the ddl log that the drop was done completely
- Update xid of query to ddl_log
- Log query to binary log together with xid.
- Mark ddl log entry done

Recovery of active atomic drop entry

In following code, all temporary tables can be ignored as these has
already been deleted by the server.

- Check if query is in the binary log.
  - If yes
     - The drop succeed. Markddl  log entry done end exit
 
- Start with first table not marked as completely dropped
- Check if the object is a table (not a view), that it exist and is complete (.frm exist and handler open works)
  - If not, redo the drop of the table and mark it in ddl log
- Log all successfully dropped tables to binary log.
- Mark log entry done.


Generated at Thu Feb 08 09:25:29 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.