-
Dmitry Lenev authored
Changed the storage engine API and SQL-layer code in order to allow InnoDB to get rid of its internal data-dictionary and to enable support for atomic/crash-safe DDL in future. Changed DROP TABLES user-visible behavior in case of error to make it more atomic. Also changed the way DROP TABLES and DROP DATABASE are written in the binary log to make them more crash-safe once atomic DDL is supported. Particularly: 1) Added support for auxiliary columns and keys which are implicitly added to the table by SE (e.g. InnoDB's DB_ROW_ID, implicit PK) to the SE API. Even though such columns and keys are not visible to users we still want to store information about them in the DD. So new: int handler::add_extra_columns_and_keys(HA_CREATE_INFO *, const List<Create_field> *, KEY *, uint, dd::Table *) method was introduced, which is called during dd::create_table() execution. SE adds hidden columns/keys by adjusting dd::Table object passed as in/out parameter and then adjusted table definition is saved to the DD. 2) Provided access to se_private_* values and methods to update them during DDL. Added "const dd::Table *" argument to handler::open() call so SE should be able to get values of these attributes when table is opened. Similar arguments were to DDL-related methods which operate on tables without opening them. Extended SE API methods related to DDL to allow SEs to adjust these attributes for tables (and its subobjects) and tablespaces. For example, SE method for renaming table now looks like: int handler::rename_table(const char *from, const char *to, const dd::Table *from_table_def, dd::Table *to_table_def); New from_table_def in-argument contains pointer to dd::Table object describing the table prior to rename. to_table_def is in/out-parameter which points to dd::Table object describing the table after rename. The latter object can be adjusted by SE and will be saved in the DD for storage engines which support atomic DDL (i.e. have HTON_SUPPORTS_ATOMIC_DDL flag set). 3) Paved the way for atomic/crash-safe DDL by ensuring that for capable SEs (i.e. with HTON_SUPPORTS_ATOMIC_DDL flag) it is executed as a single atomic transaction. Such transaction includes updates to the DD, changes in SE and writes to binary log and should either commit and have its effect properly reflected in DD, SE and binary log or rollback and doesn't have any effect at all. To achieve this: *) Removed intermediate commits in DDL from SQL-layer if DDL involves only SEs supporting atomic DDL. For cases when DDL involves engines which do not support atomic DDL intermediate commits still happen as it improves their crash safety. *) Introduced new handlerton post_ddl() hook to be called after DDL is committed or rolled back to let SE do necessary post-commit/ rollback work (like removing table files after DROP TABLES is committed). *) Ensured that atomic DDL statements are written as transactional statements to the binary log, so they can be correctly committed/ rolled back. However, WL@9175 is necessary for binlog not to override this choice and to support correct crash recovery for such statements. 4) Introduced Partition_handler::exchange_partition() method to be used for implementation of atomic ALTER TABLE EXCHANGE PARTITION which do not rely on legacy partitioning code. 5) Changed the behavior of DROP TABLES statement to make user-visible behavior more atomic and try to avoid side-effects from failed statements when possible. Multi-table DROP TABLES statement (sans IF EXISTS clause) no longer drops any tables if one them is missing. Also we will try to rollback effects of this statement in case of any error. This means that DROP TABLES which involves only tables in SEs supporting atomic DDL will be either successful or fail without any side-effects. Deletion of tables in SEs which don't support atomic DDL can't be rolled back of course and is visible as a side-effect after DROP TABLES fails due to some error from SE (but not because of missing table). The above also applies to DROP DATABASE statement (except that it cannot fail due to missing table). Binary logging for DROP TABLES and DROP DATABASE statement were also changed to make them more crash safe. When GTIDs are not involved we write separate DROP TABLE statements for each table in SE not supporting atomic DDL which is dropped. Removal of tables in SEs supporting atomic DDL is still represented in binary log as a single multi-table DROP TABLES statement (or as DROP DATABASE statement if we are dropping database). Statements with assigned GTID can't be split in the binary log, so we are still writing single DROP TABLES/DROP DATABASE statement in this case. Note that for SEs which do not support atomic DDL it might happen that table is missing from SE, but is present in the DD. Such tables still can be dropped using DROP TABLE IF EXISTS. Note that even though this patch enables HTON_SUPPORTS_ATOMIC_DDL flag for InnoDB SE, this engine still doesn't really support atomic DDL internally. So this patch adds some workarounds for this until WL@9536 is implemented. It also disables a few tests until WL@9175 and WL@9536 fully enable support for atomic DDL in binary log and InnoDB SE.
Dmitry Lenev authoredChanged the storage engine API and SQL-layer code in order to allow InnoDB to get rid of its internal data-dictionary and to enable support for atomic/crash-safe DDL in future. Changed DROP TABLES user-visible behavior in case of error to make it more atomic. Also changed the way DROP TABLES and DROP DATABASE are written in the binary log to make them more crash-safe once atomic DDL is supported. Particularly: 1) Added support for auxiliary columns and keys which are implicitly added to the table by SE (e.g. InnoDB's DB_ROW_ID, implicit PK) to the SE API. Even though such columns and keys are not visible to users we still want to store information about them in the DD. So new: int handler::add_extra_columns_and_keys(HA_CREATE_INFO *, const List<Create_field> *, KEY *, uint, dd::Table *) method was introduced, which is called during dd::create_table() execution. SE adds hidden columns/keys by adjusting dd::Table object passed as in/out parameter and then adjusted table definition is saved to the DD. 2) Provided access to se_private_* values and methods to update them during DDL. Added "const dd::Table *" argument to handler::open() call so SE should be able to get values of these attributes when table is opened. Similar arguments were to DDL-related methods which operate on tables without opening them. Extended SE API methods related to DDL to allow SEs to adjust these attributes for tables (and its subobjects) and tablespaces. For example, SE method for renaming table now looks like: int handler::rename_table(const char *from, const char *to, const dd::Table *from_table_def, dd::Table *to_table_def); New from_table_def in-argument contains pointer to dd::Table object describing the table prior to rename. to_table_def is in/out-parameter which points to dd::Table object describing the table after rename. The latter object can be adjusted by SE and will be saved in the DD for storage engines which support atomic DDL (i.e. have HTON_SUPPORTS_ATOMIC_DDL flag set). 3) Paved the way for atomic/crash-safe DDL by ensuring that for capable SEs (i.e. with HTON_SUPPORTS_ATOMIC_DDL flag) it is executed as a single atomic transaction. Such transaction includes updates to the DD, changes in SE and writes to binary log and should either commit and have its effect properly reflected in DD, SE and binary log or rollback and doesn't have any effect at all. To achieve this: *) Removed intermediate commits in DDL from SQL-layer if DDL involves only SEs supporting atomic DDL. For cases when DDL involves engines which do not support atomic DDL intermediate commits still happen as it improves their crash safety. *) Introduced new handlerton post_ddl() hook to be called after DDL is committed or rolled back to let SE do necessary post-commit/ rollback work (like removing table files after DROP TABLES is committed). *) Ensured that atomic DDL statements are written as transactional statements to the binary log, so they can be correctly committed/ rolled back. However, WL@9175 is necessary for binlog not to override this choice and to support correct crash recovery for such statements. 4) Introduced Partition_handler::exchange_partition() method to be used for implementation of atomic ALTER TABLE EXCHANGE PARTITION which do not rely on legacy partitioning code. 5) Changed the behavior of DROP TABLES statement to make user-visible behavior more atomic and try to avoid side-effects from failed statements when possible. Multi-table DROP TABLES statement (sans IF EXISTS clause) no longer drops any tables if one them is missing. Also we will try to rollback effects of this statement in case of any error. This means that DROP TABLES which involves only tables in SEs supporting atomic DDL will be either successful or fail without any side-effects. Deletion of tables in SEs which don't support atomic DDL can't be rolled back of course and is visible as a side-effect after DROP TABLES fails due to some error from SE (but not because of missing table). The above also applies to DROP DATABASE statement (except that it cannot fail due to missing table). Binary logging for DROP TABLES and DROP DATABASE statement were also changed to make them more crash safe. When GTIDs are not involved we write separate DROP TABLE statements for each table in SE not supporting atomic DDL which is dropped. Removal of tables in SEs supporting atomic DDL is still represented in binary log as a single multi-table DROP TABLES statement (or as DROP DATABASE statement if we are dropping database). Statements with assigned GTID can't be split in the binary log, so we are still writing single DROP TABLES/DROP DATABASE statement in this case. Note that for SEs which do not support atomic DDL it might happen that table is missing from SE, but is present in the DD. Such tables still can be dropped using DROP TABLE IF EXISTS. Note that even though this patch enables HTON_SUPPORTS_ATOMIC_DDL flag for InnoDB SE, this engine still doesn't really support atomic DDL internally. So this patch adds some workarounds for this until WL@9536 is implemented. It also disables a few tests until WL@9175 and WL@9536 fully enable support for atomic DDL in binary log and InnoDB SE.
Loading