Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-23842

Atomic RENAME TABLE

    XMLWordPrintable

    Details

      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

            Activity

              People

              Assignee:
              monty Michael Widenius
              Reporter:
              monty Michael Widenius
              Votes:
              1 Vote for this issue
              Watchers:
              9 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Git Integration