mysql 8 新特性一 ALGORITHM=INSTANT 实现的快速DDL

mysql 8 新特性一 ALGORITHM=INSTANT 实现的快速DDL,第1张

参考 https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-12.html

在线DDL之 快速增加列(秒级别的),并不会造成业务抖动。该功能自 MySQL 8.0.12 版本引入,是由腾讯游戏DBA团队贡献,我国程序员还是挺厉害的嘛。注意一下,此功能只适用于 InnoDB 表。实际上MySQL 5.7就已支持 Online DDL,虽说大部分 DDL 不影响对表DML *** 作,但是依然会消耗非常多的时间,且占用额外的磁盘空间,并会造成主从延迟,或者影响表的查询速度。有了这个ALGORITHM=INSTANT 就可应对瞬息万变的需求了。。

ALGORITHM=INSTANT 目前对6种ddl有效:

实际试验下,使用 mysql5.7的INPLACE 算法 时间: 52s。

使用 Instant Add Column ,时间:0.39 s。 果然是秒级别添加

当然我们不需要显式指定algorithm=instantmysql会优先使用INSTANT算法来进行ddl的;若显式指定algorithm=instant 同时目标ddl不支持就会报错。如下,DROP COLUMN 时指定则报错

添加或删除virtual 列

添加或删除列默认值

修改 ENUM 定义

修改索引类型

重命名表,好像和5.7的INPLACE算法也没啥时间上的区别。INPLACE的rename table已经足够快了

还有一些特殊情况不能使用ALGORITHM=INSTANT的:

Instant Add Column只能将新字段添加到表的尾巴上,不能添加到中间!

不支持压缩表,即该表行格式不能是 COMPRESSED。

不支持包含全文索引的表;不支持临时表;不支持那些在数据字典表空间中创建的表。这些就不一一验证了。平时 *** 作时要注意下!

MySQL8.0 开始支持原⼦ DDL(atomic DDL),数据字典的更新,存储引擎 *** 作,写⼆进制日志结合成了一个事务。在没有原⼦DDL之前,DROP TABLE test1,test2;如遇到server crash,可能会有test1被drop了,test2没有被drop掉。下面来看下在MySQL8.0之前和MySQL8.0 数据字典的区别

在MySQL8.0 之前,Data Dictionary除了存在与.FRM, .TRG, .OPT ⽂件外,还存在于系统表中(MyISAM ⾮事务引擎表中),在MySQL8.0 ,Data Dictionary 全部存在于Data Dictionary Storage Engine(即 InnoDB表中),这使crash recovery 维持原⼦性成为了可能

存储引擎⽀持

目前,只有InnoDB存储引擎⽀持原子DDL,为了实现原子DDL,Innodb要写DDL logs 到 mysql.innodb_ddl_log 表,这是⼀个隐藏在mysql.ibd 数据字典表空间⾥的数据字典表。要看mysql.innodb_ddl_log 中的内容,需要

SET GLOBAL LOG_ERROR_VERBOSITY=3(MySQL 8.0 默认为2,error log 记录Errors and

warnings,不不记录notes)

SET GLOBAL innodb_print_ddl_logs=1

CREATE TABLE t1 (c1 INT) ENGINE = InnoDB

查看error log

[Note] [MY-011066] InnoDB: DDL log insert : [DDL record: DELETE SPACE, id=30,

thread_id=25, space_id=9, old_file_path=./test/t1.ibd]

[Note] [MY-011066] InnoDB: DDL log delete : by id 30

[Note] [MY-011066] InnoDB: DDL log insert : [DDL record: REMOVE CACHE, id=31,

thread_id=25, table_id=1066, new_file_path=test/t1]

[Note] [MY-011066] InnoDB: DDL log delete : by id 31

[Note] [MY-011066] InnoDB: DDL log insert : [DDL record: FREE, id=32, thread_

id=25, space_id=9, index_id=143, page_no=4]

[Note] [MY-011066] InnoDB: DDL log delete : by id 32

[Note] [MY-011066] InnoDB: DDL log post ddl : begin for thread id : 25

[Note] [MY-011066] InnoDB: DDL log post ddl : end for thread id : 25

原子DDL *** 作步骤

准备:创建所需的对象并将DDL⽇志写入 mysql.innodb_ddl_log表中。DDL日志定义了如何前滚和回滚DDL *** 作。

执行:执⾏DDL *** 作。例如,为CREATE TABLE *** 作执⾏创建。

提交:更新数据字典并提交数据字典事务。

Post-DDL:重播并从mysql.innodb_ddl_log表格中删除DDL⽇志。为确保回滚可以安全执⾏⽽不引⼊不⼀致性,在此最后阶段执⾏⽂件 *** 作(如重命名或删除数据文件)。这一阶段还从 mysql.innodb_dynamic_metadata的数据字典表删除的动态元数据为了DROP TABLE,TRUNCATE和其它重建表的DDL *** 作。

⽆论事务是提交还是回滚,DDL日志都会mysql.innodb_ddl_log在Post-DDL阶段重播并从表中删除 。mysql.innodb_ddl_log如果服务器在DDL *** 作期间暂停,DDL⽇志应该只保留在表中。在这种情况下,DDL⽇志会在恢复后重播并删除。

在恢复情况下,当服务器重新启动时,可能会提交或回退DDL事务。如果在重做⽇志和⼆进制日志中存在DDL *** 作的提交阶段期间执⾏的数据字典事务,则该 *** 作被认为是成功的并且被前滚。否则,在InnoDB重放数据字典重做日志时回滚不完整的数据字典事务 ,并且回滚DDL事务。

原⼦DDL ⽀持类型

• DROP TABLES , all tables dropped or none

• DROP SCHEMA, all entities in the schema are dropped, or none

• Note that atomic DDL statements will be rolled back or committed even in case of crash, e.g. RENAME TABLES

• CREATE TABLE would be successfully committed or rolled back (no orphan ibd left)

• TRUNCATE TABLE (including InnoDB tables with FTS AUX tables) would be successfully committed or rolled back

• RENAME TABLES, all or none

• ALTER TABLE successful or not done

示例

请点击输入图片描述

请点击输入图片描述

结论

在MySQL8.0之前,alter table *** 作在server crash的情况下,会遗留.frm,.ibd文件。MySQL8.0 能实现原⼦DDL(包括 DROP TABLE, DROP SCHEMA, CREATE TABLE, TRUNCATE TABLE, ALTER TABLE),alter table *** 作,在server crash的情况下,不会遗留.frm,.ibd临时文件。让我们⼀起期待MySQL8.0 GA的到来吧!

SQL:结构化查询语言,包括数据定义语言(DDL)如:CREATE、DROP、ALTER等;数据 *** 作语言(DML)如:INSERT、UPDATE、DELETE之类;数据查询语言(DQL)如:SELECT语句;数据控制语言(DCL)如:GRANT、REVOKE、COMMIT、ROLLBACK等。

T-SQL:Transact-SQL,为SQL的语言的增强版,加入了程序语言中的if,while 等流程控制语法,同时可以使用函数功能


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/7489651.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-06
下一篇 2023-04-06

发表评论

登录后才能评论

评论列表(0条)

保存