[MDEV-11655] Transactional data dictionary Created: 2016-12-23 Updated: 2024-01-18 |
|
| Status: | Open |
| Project: | MariaDB Server |
| Component/s: | None |
| Fix Version/s: | None |
| Type: | New Feature | Priority: | Major |
| Reporter: | Marko Mäkelä | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 14 |
| Labels: | None | ||
| Attachments: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description |
|
With Proposal for Global Data Dictionary in MariaDBThe .frm files can be preserved for backward compatibility (tables could be copied by copying data and .frm files). We can create a ‘cache’ of the .frm files in a persistent tables table. Reading from a single table should be much faster than reading table definitions from many small files, especially on startup and when executing INFORMATION_SCHEMA queries. To allow the InnoDB internal data dictionary tables to be removed (MDEV-11633), we will have to make .ibd files self-contained and store a metadata record with the following information:
Prerequisites and FeaturesThis proposal is based on the following assumptions:
DefinitionsStatic metadataAny metadata that can be changed by DDL operations only. Dynamic metadata:Any other metadata. Examples of dynamic metadata attributes include AUTO_INCREMENT (MDEV-6076) and UPDATE_TIME. Any dynamic metadata will be persisted within the storage engine; not written back to the data dictionary core. The latest dynamic metadata can only be accessed by invoking the storage engine. Data dictionary table definition
Note 1: tables only stores persistent metadata about tables and sequences. Note 1.1: If we wish SHOW CREATE TABLE to omit implied attributes, we Note 1.2: In accordance with MDEV-16417, tables that are referencing the current table via FOREIGN KEY constraints would be identified in the .frm file and the tables.frm column. (The referencing tables’ REFERENCES clauses would be present in both tables.description and tables.frm.) Note 1.3: Explicitly specified invalid or unsupported attributes will be removed or replaced both in mysql.tables.definition and the .frm file. Note 1.4: For partitioned tables, there will be a single entry in tables. Note 1.5: For additional safety and portability, whenever a change to Note 1.6: On a table definition cache miss in handler::ha_open(), both Note 1.7: It should be possible to import InnoDB tables or partitions Note 1.8: If any table or columns attached to FOREIGN KEY…REFERENCES are renamed, the Bootstrap, Startup and UpgradingIn the MySQL 8.0 Global Data Dictionary, there will likely be a
On startup, the server will read the contents of this table and refuse In MariaDB, we would probably have to hard-code the definition of the tables table, and compare it to tables.frm if it exists. An entry for tables itself could be omitted from the tables table. Bootstrap (--initialize)MariaDB or InnoDB should ideally not apply any ‘create if not exists’ On a special startup option --initialize, MariaDB will create a new We can initialize a new server instance in the following order:
A startup attempt on an older MariaDB would fail because the (possibly Upgrade To Transactional Data Dictionary (from earlier MariaDB version)We must have enough code to support SHOW CREATE TABLE of all old tables. * the redo log is not clean In these cases, the user would have to address the problem in the older
On upgrade, once MDEV-11633 is completed, MariaDB would abandon Upgrade would create and populate the tables tables based on the old data dictionary contents. If upgrade does not destroy the old files, it should be possible to downgrade to an older MariaDB, provided that there were no InnoDB DDL operations and there is a slow shutdown (the undo and redo logs are empty). After invoking upgrade, the only supported outcomes are the following:
Notes on Consistency ChecksDo we need to check if InnoDB data files use the same ROW_FORMAT as is stored in the .frm file or in the mysql.tables entry? Probably not; we should only require that the .ibd file is self-consistent. If we implement tables, how to ensure consistency with .frm files?
Notes on FOREIGN KEYDiscovering the FOREIGN KEY RelationshipsForeign key metadata is required so that the changes can be prohibited or cascaded based on the existence or contents of (grand)*(child|parent) tables. The SQL layer must know the tables for acquiring appropriate MDL. How to find the FOREIGN KEY children? REFERENCES clauses in SHOW CREATE TABLE point to parents only. As noted in MDEV-16417, we can extend the frm information to additionally store the names of referencing tables. Cleaning up the FOREIGN KEY implementationCertain operations must know the FOREIGN KEY child/parent graph. INSERT, UPDATE, DELETE, REPLACE must be prohibited or cascaded based on the parent and child tables. SELECT, ROLLBACK, COMMIT can continue to ignore FOREIGN KEY constraints. MDEV-22361 would implement native, cross-engine FOREIGN KEY processing in the SQL layer. This would make ON…CASCADE and ON…SET NULL] fire TRIGGER, at last. This would also make FOREIGN KEY work on partitioned tables (MDEV-12483). Comparison to the Global Data Dictionary in MySQL 8.0MySQL 8.0 aims to replace .frm files and InnoDB SYS_* tables with a collection of tables that implement the Global Data Dictionary. The MySQL 8.0 approach is rather complex, using multiple fundamentally different representation formats for the same data:
Normalized and serialized storageThe decomposition of the metadata into relational tables has the benefit that it is possible to implement some INFORMATION_SCHEMA views based on the data dictionary tables. Not all of them; there are some ‘computed columns’ that the storage engines will be asked to fill in by invoking handlerton or handler functions. See Faster INFORMATION_SCHEMA. The decomposition has the drawback of overhead. Using the terms popularized by Mark Callaghan, it is causing read amplification, storage amplification, and write amplification. Read amplificationMetadata will normally be loaded from a bunch of small records scattered in multiple tables, instead of loading serialized data, such as a .frm file. Storage amplificationThe data dictionary tables in MySQL 8.0 include a large number of secondary indexes. (In the core InnoDB data dictionary tables, there is only one secondary index on the unique column SYS_TABLES.ID.) Write amplificationFor example, RENAME TABLE on a partitioned table will cause a rewrite of the decomposed metadata records and a rewrite of one or both of the .SDI file and the WL#7053 embedded metadata inside the .ibd files. In MySQL 8.0.0, the WL#7053 interface is not used yet, and there is no optimization when it comes to updates. All decomposed records will be deleted and inserted with different IDs. This also leads to fragmentation in the data dictionary tables when the system is tortured with a constant stream of trivial DDL operations. |
| Comments |
| Comment by Will Bryant [ 2017-06-20 ] | |
|
Storing the entire table definition in serialized format is an interesting idea. It would be good to think ahead to how it would support making DDL changes not only transactional but also deferred (as opposed to rewriting the table completely). For example, both PostgreSQL and Amazon's Aurora fork of MySQL/InnoDB support adding a nullable column at the end of the table without rewriting the entire table, which is a very useful special case because this is the most common DDL change for many large production environments and this saves a huge amount of IO and migration time. Comparing it to the route that MySQL and PostgreSQL went, because they have one row per table column it is possibly easier to implement extensions such as adding a table definition version number to each row (ie. the first version of the table structure that had this column added), which they could then compare to a number stored on each row or each page. How would you approach storing this metadata if a similar feature was added to MariaDB after 10.4? Would you introduce new attributes with _ prefixes? | |
| Comment by Marko Mäkelä [ 2017-10-06 ] | |
|
will.bryant, | |
| Comment by Marko Mäkelä [ 2018-03-27 ] | |
|
The mysql.ddl_log table should not be used for engine-specific recovery, but only for rolling back or forward changes to .frm files or equivalent, if needed. Inside InnoDB, DDL operations can be recovered by writing undo log records, as hinted in
| |
| Comment by Marko Mäkelä [ 2018-09-26 ] | |
|
0001-WIP-Remove-dict_field_t-name-25ad38abe5b3fb6bb2aafff315de256b8f1e7839.patch | |
| Comment by Marko Mäkelä [ 2021-05-06 ] | |
|
In MariaDB Server 10.6, all DDL operations inside InnoDB are expected to be atomic. This was improved in As far as InnoDB is concerned, we do not really need any ddl_log table for recovery. The undo log is sufficient. In For DDL recovery outside the InnoDB storage engine, The .frm files provide a serialized description of the data dictionary. If we did not care about the upgrade process, it could be nicer to have a text-based format, something like a tablename.frm that would contain the CREATE TABLE string in plain text and a list of child table names that contain any FOREIGN KEY constraint that REFERENCES this table. To speed up server startup (say, when a user executes SHOW TABLES and there are millions of tables), the contents of the .frm files can be cached in a table. Something SQLite-style could be sufficient:
For this to work, the .ibd and undo log file format in InnoDB would have to be changed as follows:
| |
| Comment by Aleksey Midenkov [ 2023-08-16 ] | |
|
marko I would not mix InnoDB and SQL tasks. Moving out .frm into transactional table is big enough task on its own. |