Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Instant add column for inno db in mariadb 10.3+ (fosdem 2018, second draft)


Published on

My slides for (canceled due to personal issues) talk for FOSDEM 2018 MySQL Devroom. I planned to discuss the history of ALTER TABLE speedup and optimization in MySQL, explain the implementation of instant ADD COLUMN for InnoDB tables in MariaDB 10.3 and compare performance of recent versions of MariaDB 10.2, 10.3, Percona Server 5.7, MyRocks from MariaDB 10.2 and MySQL 8.0.4 while working on multiple step test case incolving ALTER TABLE ... ADD COLUMN.

A lof of links to related manuals, blog posts and resources are presented.

Published in: Software
  • Be the first to comment

  • Be the first to like this

Instant add column for inno db in mariadb 10.3+ (fosdem 2018, second draft)

  1. 1. Instant ADD COLUMN for InnoDB in MariaDB 10.3+ On the way to instant ALTER TABLE for failure-free record format changes Valerii Kravchuk, Principal Support Engineer, MariaDB 1
  2. 2. Who am I? Valerii (aka Valeriy) Kravchuk: ● MySQL Support Engineer in MySQL AB, Sun and Oracle, 2005 - 2012 ● Principal Support Engineer in Percona, 2012 - 2016 ● Principal Support Engineer in MariaDB Corporation since March 2016 ● - my blog about MySQL (a lot about MySQL bugs, but some HowTos as well) ● - my Facebook page, a lot about MySQL (mostly bugs, rants and links to blog posts…) ● - it used to be my personal playground ● @mysqlbugs - #bugoftheday on Twitter ● I like FOSDEM, see slides from my previous talks: ○ ○ ○ 2
  3. 3. What is this session about? ● History of ALTER TABLE improvements in MySQL ● Problems with current “online” table rebuilds ● How instant ADD COLUMN for InnoDB appeared in MariaDB ● Basic usage of instant ADD COLUMN, limitations ● Page changes for instant ADD COLUMN ● Some “benchmarks” (not sure if I have enough time…) ● Next steps on the way to instant ALTER TABLE for failure-free InnoDB record format changes that may happen in MariaDB 10.4+ (or not :) 3
  4. 4. History of ALTER TABLE in MySQL/MariaDB ● The old way (also known as ALGORITHM=COPY starting with MySQL 5.6) ○ CREATE TABLE ...; INSERT … SELECT; RENAME TABLE ...; DROP TABLE ...; ○ Lots of unnecessary undo and redo logging in InnoDB ("bulk insert" would help) ● "Fast index creation" in InnoDB Plugin for MySQL 5.1 (built-in 5.5 InnoDB) ○ Supports ADD INDEX, ADD UNIQUE INDEX, ADD PRIMARY KEY (?) ● ALGORITHM=INPLACE starting with MySQL 5.6 ○ Misleading name; some operations may rebuild the table ■ ADD/DROP COLUMN, ADD PRIMARY KEY, CHANGE ...[NOT] NULL ○ Some operations are instant: rename column, change DEFAULT value, … ■ Should have ALGORITHM=(INSTANT|NOCOPY) to avoid surprises (MDEV-13134) ○ Somewhat wrongly called "online" DDL: ■ Changes to data in table are still prevented for some time in the process. Bug #84004! ■ It still causes slaves lag (Bug #73196) ■ We all know it should be “more online”, see Bug #77097, Bug #68498, Bug #72109, Bug #83557 etc ○ Online (LOCK=NONE) is sometimes refused: ■ ALTER TABLE … ADD (FULLTEXT|SPATIAL) INDEX, ALGORITHM=INPLACE; ■ Any table rebuild operation when FULLTEXT or SPATIAL indexes are present (see Bug #81819) 4
  5. 5. Problems with Online Table Rebuild ● MySQL 5.6+ includes “online” ALTER TABLE ([ADD|DROP] COLUMN etc.), with LOCK=NONE. Why are tools like gh-ost or pt-osc still used? ○ Replication ignores LOCK=NONE: Slaves will only continue after commit → huge lag ○ The online log needs to be buffered (in memory or temporary files) ■ The size depends on the concurrent DML workload; hard to predict! ○ The whole table (including all indexes) will have to be copied ■ MySQL 5.7 included some performance improvements to this, but huge I/O remains ○ Theoretically, do we really have to rebuild? ■ Only when introducing stricter constraints (shorter columns, add NOT NULL) ■ Even that could be done by validating the table and editing metadata ■ Only ADD [UNIQUE|PRIMARY|SPATIAL|FULLTEXT] KEY really require writes 5
  6. 6. History of Instant ADD COLUMN for InnoDB ● Both Alibaba and Tencent have instant ADD in their MySQL 5.6 forks ○ Does not work with old data files; requires a new ROW_FORMAT ● MariaDB wants it to work on old (possibly large) files ○ Vin Chen from Tencent Game DBA Team wrote a prototype that adds an optional record header to identify "afterwards added columns" ○ The ADD … DEFAULT values are stored in one place ○ Data dictionary only reflects the latest table definition, including the latest DEFAULT ● Marko Mäkelä rewrote the prototype for MariaDB 10.3.2 (see MDEV-11369) ○ Store a 'default row' at the start of the table (we want to remove SYS_* tables one day) ○ Support all but ROW_FORMAT=COMPRESSED ○ Crash-safe DDL (a new undo record type); simpler DML rollback; "compression" ○ ensured that online table rebuild (e.g. DROP COLUMN) still works 6
  7. 7. Basic Usage of Instant ADD COLUMN ● By default, ALTER TABLE … ADD COLUMN is instantaneous ○ Limitation: No hidden FTS_DOC_ID column (for FULLTEXT INDEX) must exist ● Use the FORCE keyword for the old-fashioned ADD COLUMN, with the old-fashioned (additional) limitations: ○ ALGORITHM=INPLACE will not work if multiple FULLTEXT indexes exist ○ LOCK=NONE will not work if FULLTEXT or SPATIAL index exist ● To monitor the number of avoided table rebuilds: SELECT variable_value FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; ● See also 7
  8. 8. ● No limitations on data types for added columns or DEFAULT expression complexity: CREATE TABLE t(id INT PRIMARY KEY, u INT UNIQUE) ENGINE=InnoDB; INSERT INTO t(id,u) VALUES(1,1),(2,2),(3,3); ALTER TABLE t ADD COLUMN (d DATETIME DEFAULT current_timestamp(), t TEXT CHARSET utf8 DEFAULT 'The quick brown fox', p POINT NOT NULL DEFAULT ST_GeomFromText('POINT(0 0)')); UPDATE t SET t=NULL WHERE id=3; SELECT * FROM t; ● No backward compatibility until rebuilt with FORCE (ToDo: check this). See MDEV-13562 also. Example of Instant ADD COLUMN 8
  9. 9. Page Changes for Instant ADD COLUMN ● Clustered index root page changes: ○ FIL_PAGE_TYPE_INSTANT indicates that instant operation was used ○ PAGE_INSTANT stores the original (smaller) number of clustered index fields ● Change the leftmost clustered index leaf page: ○ After the infimum, store a "default" record with REC_INFO_MIN_REC_FLAG: ■ Must have the optional "added fields" header ■ The number of fields must match the current table definition ■ Values of "added fields" are the values of "missing fields" ● Clustered index contents from the previous example: ○ (default,id,u,d=2017-11-10 12:14:00,t='The quick brown fox',p=POINT(0 0)), ○ (1,1), (2,2), (3,3,2017-11-10 12:14:00, NULL) ○ We omit trailing fields that are equal to the fields in the "default" record 9
  10. 10. MariaDB 10.4+: ADD… [FIRST|AFTER], DROP... ● Keep the user record format unchanged ○ Physically, keep doing ADD COLUMN last in the clustered index records ○ DROP COLUMN will leave garbage in the records ○ Changing column order physically becomes a no-op ○ ADD COLUMN will be possible even if hidden FTS_DOC_ID exists ● In the "default" record, store a mapping of table columns to index fields, pass it somehow when needed 10
  11. 11. MariaDB 10.4+: Instant CHANGE COLUMN? ● MySQL 5.7/MariaDB 10.2: Extend VARCHAR maximum size ○ Only if the physical format allows; not VARCHAR(255) to VARCHAR(256) ● We need something in the user data records to indicate physical format ○ "Format version number" that points to something in the "default" record? ● Format changes can only be instantaneous if they relax constraints: ○ Example: CHAR(1) to CHAR(2), INT to BIGINT or NOT NULL to NULL ○ Less likely: Changing POINT to GEOMETRY, changing latin1 to utf8 ● Failure is an option, if we perform table scan to validate the data: ○ Example: Changing BIGINT NULL to INT UNSIGNED NOT NULL ● Affected secondary indexes must be rebuilt if the physical format changes ○ Still much faster than rebuilding the entire table; can be done online ● Follow MDEV-11424, “Instant ALTER TABLE of failure-free record format changes”, if interested... 11
  12. 12. Set of Statements to Do Lame “Benchmark” See test_instant_alter.sql for more details: create table t(id int auto_increment primary key, c1 int); insert into t(c1) values (0); -- repeat 19 times insert into t(c1) select rand()*1000 from t; -- 0 select count(*) from t; -- 1 ... alter table t add column c2 char(200) default 'a'; -- 2 ... update t set c2 = 'b'; -- 3 update t set c2 = 'c'; -- 4 update t set c2 = 'd'; -- !!! ... alter table t force; -- 5 update t set c2 = 'e'; -- 6 update t set c2 = 'f'; -- 7 12 It may be interesting to compare times to execute 2 and 5, as well as 3 and 4 to 6 and 7, also for different engines (like MyRocks) and versions (PS 5.7, 10.2, 10.3, and, surely MySQL 8.0.4)
  13. 13. Example of Instant ADD COLUMN for Benchmark create table t(id int auto_increment primary key, c1 int); insert into t(c1) values (0); insert into t(c1) select rand()*1000 from t; … continue that way until it’s big enough MariaDB [test]> insert into t(c1) select rand()*1000 from t; Query OK, 262144 rows affected ( 4.141 sec) Records: 262144 Duplicates: 0 Warnings: 0 MariaDB [test]> alter table t add column c2 char(200) default repeat('a',200); Query OK, 0 rows affected ( 0.039 sec) Records: 0 Duplicates: 0 Warnings: 0 MariaDB [test]> update t set c2 = 'b'; Query OK, 524288 rows affected ( 55.682 sec) Rows matched: 524288 Changed: 524288 Warnings: 0 MariaDB [test]> update t set c2 = 'c'; Query OK, 524288 rows affected ( 31.649 sec) Rows matched: 524288 Changed: 524288 Warnings: 0 13
  14. 14. Time to Run ALTER … ADD COLUMN (2) ● On my QuadCore Fedora 27 box, --no-defaults: 14
  15. 15. Time to Run First UPDATE After ALTER (3) ● On my QuadCore Fedora 27 box, --no-defaults: 15
  16. 16. Time to Run Entire “Benchmark” Script ● On my QuadCore Fedora 27 box, --no-defaults: 16
  17. 17. Thanks and Links ● Thanks to Marko Mäkelä for his work, hints and slides on this topic ● Thanks to LeFred and Belcona team for this event! ● Check MDEV-11369 for the details of original task in MariaDB ● Check original blog post about the feature ● Check MDEV-11424 for further plans in MariaDB 10.4+ and progress on them ● My blog post on current state of online DDL in MySQL 5.7 ● Some test and raw benchmark results are shared here 17
  18. 18. Thank you! Questions and Answers? Please, report bugs at: 18