Details
-
Task
-
Status: Closed (View Workflow)
-
Critical
-
Resolution: Fixed
-
None
Description
Atomic rename table
The purpose of this task is to ensure that RENAME TABLE is atomic.
Either all renames and logging to binary log will succeed or all
renames will roll back, even if the server would crash at any point in
rename process.
This task also includes atomic RENAME VIEW.
How rename works in 10.5:
mysql_rename_tables() checks if tables are log tables and if yes and
|
not renamed correctly aborts with an error
|
- rename_tables() is are called
|
- Loop over all tables in table list, two at a time
|
If 'from' table is temporary table call do_rename_temporary()
|
else call do_rename()
|
- First handler rename is called, then .frm is renamed
|
|
- If failure, rename changes tables back to their original names
|
Notes
- If a table is discovered during rename, the .frm file will be created.
We can use this fact to discover if a rename was completely done or not.
Special cases to consider:
- renaming temporary tables and normal tables in same query
- Swapping tables:
RENAME TABLE t1 TO tmp, t2 TO t1, tmp TO t2;
RENAME TABLE t1 TO tmp, t2 TO t1, tmp TO t2, t3 TO t4; - renaming table over old table (should fail):
RENAME TABLE t1 TO t2, t3 TO existing_table;
RENAME TABLE t1 TO t2, t3 TO t2; - Renaming not existing table:
RENAME TABLE t1 TO t2, not_existing_table TO t3; - Re-renaming a table:
RENAME TABLE t1 TO t2, t2 TO t3;
The code also needs to take care of that a rename can fail in the engine for various reasons
and we have to be able to back out from any stage in the rename. Some of the reasons for
failures are:
- Internal foreign key constraints in the engine, not noticed until rename
- One of the tables table is on a read-only storage or protected by the engine
- Some files for an engine is missing (like in MyISAM where there should be an .MYI and MYD file but one of the files has are missing or corrupted
- Engine doesn't support rename
How atomic rename should work:
Normal operation
- Loop over all tables and remember if they are temporary or not.
|
- Loop over all tables and check that there are no renames of not existing
|
tables over over existing tables and give errors early (this is a change
|
from how things works now, where we try to do all renames and rename back
|
things on failure).
|
This code also have to take into account all renames that would happen
|
before. The above examples should cover those cases.
|
- Log to ddl log:
|
- Query
|
- Information of which tables where temporary
|
- Short uuid
|
- Position of binary log (if open)
|
|
- Loop over all tables
|
- Add rename to be done in ddl log
|
- Rename table
|
- Mark in the ddl log that the rename was done.
|
- Update triggers and table rows in status tables
|
- Update xid of query to ddl_log
|
- Log query to binary log together with xid.
|
- Mark ddl log entry done
|
Recovery of active atomic rename entry
In following code, all temporary tables can be ignored as these has
already been deleted by the server.
- If last table is marked as 'completed', loop over all entries in
|
the binary log, starting from recorded binary log position and check if
|
there is an entry with the ddl log uuid.
|
- If yes
|
- The renames succeed. Mark log entry done end exit
|
|
- Start from table list at last table that was marked renamed
|
- If not last table and next table exist and is not complete
|
(.frm doesn't exist or handler open doesn't work)
|
- The crash happened in the middle of the rename or just after
|
Do a 'handler force rename' back from 'to' to 'from'.
|
Rename 'to'.frm to 'from.frm' if to.frm exists.
|
- In reverse order from current table to start of table list
|
- Mark in log that we are at start of current table.
|
- Rename table 'to' to 'from'
|
- Mark log entry done
|
New handler calls needed
- We need a new handler call 'force rename'. For engines that can't do atomic
ddl internally, this should do the rename of all 'from.*' files to 'to.*'
files relevant for the engine.
Attachments
Issue Links
- is blocked by
-
MDEV-24184 InnoDB RENAME TABLE recovery failure if names are reused
- Closed
- is part of
-
MDEV-17567 Atomic DDL
- Closed
- relates to
-
MDEV-14717 RENAME TABLE in InnoDB is not crash-safe
- Closed
- mentioned in
-
Page Loading...