• Marko Mäkelä's avatar
    MDEV-17158 TRUNCATE is not atomic after MDEV-13564 · 75f8e86f
    Marko Mäkelä authored
    It turned out that ha_innobase::truncate() would prematurely
    commit the transaction already before the completion of the
    ha_innobase::create(). All of this must be atomic.
    
    innodb.truncate_crash: Use the correct DEBUG_SYNC point, and
    tolerate non-truncation of the table, because the redo log
    for the TRUNCATE transaction commit might be flushed due to
    some InnoDB background activity.
    
    dict_build_tablespace_for_table(): Merge to the function
    dict_build_table_def_step().
    
    dict_build_table_def_step(): If a table is being created during
    an already started data dictionary transaction (such as TRUNCATE),
    persistently write the table_id to the undo log header before
    creating any file. In this way, the recovery of TRUNCATE will be
    able to delete the new file before rolling back the rename of
    the original table.
    
    dict_table_rename_in_cache(): Add the parameter replace_new_file,
    used as part of rolling back a TRUNCATE operation.
    
    fil_rename_tablespace_check(): Add the parameter replace_new.
    If the parameter is set and a file identified by new_path exists,
    remove a possible tablespace and also the file.
    
    create_table_info_t::create_table_def(): Remove some debug assertions
    that no longer hold. During TRUNCATE, the transaction will already
    have been started (and performed a rename operation) before the
    table is created. Also, remove a call to dict_build_tablespace_for_table().
    
    create_table_info_t::create_table(): Add the parameter create_fk=true.
    During TRUNCATE TABLE, do not add FOREIGN KEY constraints to the
    InnoDB data dictionary, because they will also not be removed.
    
    row_table_add_foreign_constraints(): If trx=NULL, do not modify
    the InnoDB data dictionary, but only load the FOREIGN KEY constraints
    from the data dictionary.
    
    ha_innobase::create(): Lock the InnoDB data dictionary cache only
    if no transaction was passed by the caller. Unlock it in any case.
    
    innobase_rename_table(): Add the parameter commit = true.
    If !commit, do not lock or unlock the data dictionary cache.
    
    ha_innobase::truncate(): Lock the data dictionary before invoking
    rename or create, and let ha_innobase::create() unlock it and
    also commit or roll back the transaction.
    
    trx_undo_mark_as_dict(): Renamed from trx_undo_mark_as_dict_operation()
    and declared global instead of static.
    
    row_undo_ins_parse_undo_rec(): If table_id is set, this must
    be rolling back the rename operation in TRUNCATE TABLE, and
    therefore replace_new_file=true.
    75f8e86f
fil0fil.h 50.7 KB