博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MySQL Online DDL(二)(r11笔记第88天)
阅读量:6848 次
发布时间:2019-06-26

本文共 4944 字,大约阅读时间需要 16 分钟。

对于Online DDL,之前简单分析了一些场景,其实有一个很关键的点没提到,那就是online DDL的算法,目前有三个操作选项,default,inplace,copy可选

具体可以参考  https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl.html

> select count(*) from newtest;

+----------+
| count(*) |
+----------+
| 22681426 |
+----------+
1 row in set (45.76 sec)表结构信息如下:

> show create table newtest\G

*************************** 1. row ***************************
       Table: newtest
Create Table: CREATE TABLE `newtest` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `game_type` int(11) NOT NULL DEFAULT '-1' ,
  `login_time` datetime NOT NULL DEFAULT '1970-01-01 00:00:00',
  `login_account` varchar(100) DEFAULT NULL ,
  `cn_master` varchar(100) NOT NULL DEFAULT '' ,
  `client_ip` varchar(100) DEFAULT '' ,
  PRIMARY KEY (`id`),
  KEY `ind_tmp_account1` (`login_account`),
  KEY `ind_login_time_newtest` (`login_time`)
) ENGINE=InnoDB AUTO_INCREMENT=22681850 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

默认的copy选项

比如我们运行下面的SQL,添加一个字段,默认情况下是使用copy的算法,即数据是平行复制一份。

alter table newtest add column newcol varchar(10) default '';这个变更过程会生成两个临时的文件.frm,.ibd

-rw-r----- 1 mysql mysql       8840 Dec  5 18:13 newtest.frm
-rw-r----- 1 mysql mysql 4353687552 Dec  5 18:45 newtest.ibd
...
-rw-r----- 1 mysql mysql       8874 Feb 27 22:25 #sql-6273_2980ab.frm
-rw-r----- 1 mysql mysql   41943040 Feb 27 22:25 #sql-ib280-3638407428.ibd
...在这个变更的过程中,是运行DML操作的,而且没有任何阻塞。

> insert into newtest(game_type,login_time,login_account,cn_master,client_ip) values(1,'2017-02-27 16:22:10','150581500032','572031626','183.128.143.113');

Query OK, 1 row affected (0.05 sec)

因为使用了主键自增,所以我可以用同样的语句再插入一条记录,也是全然没有阻塞。

> insert into newtest(game_type,login_time,login_account,cn_master,client_ip) values(1,'2017-02-27 16:22:10','150581500032','572031626','183.128.143.113');

Query OK, 1 row affected (0.00 sec)这个时候查看show processlist的结果,相比就显得有些简单了。不像之前的版本中会有table metadata lock的字样了。

+---------+-----------------+-----------------------------+----------------+-------------+---------+--------------------------------

|Id      | User            | Host                        | db             | Command     | Time    | State                          
+---------+-----------------+-----------------------------+----------------+-------------+---------+--------------------------------
| 2719915 | root            | localhost                   | test           | Query       |      75 | altering table

对比临时文件和现有配置文件

我们简单看看上面列举出来的配置文件.frm

可以通过strings的方式看到一个基本的结构信息。

# strings newtest.frm

PRIMARY
ind_tmp_account1
ind_login_time_newtest
InnoDB
)                                        
game_type
login_time
login_account
cn_master
client_ip
game_type
login_time
login_account
cn_master
client_ip
而查看临时创建的.frm文件

# strings "#sql-6273_2980ab.frm"

PRIMARY
ind_tmp_account1
ind_login_time_newtest
InnoDB
)                                        
game_type
login_time
login_account
cn_master
client_ip
newcol
game_type
login_time
login_account
cn_master
client_ip
newcol整个添加字段的操作持续时间为10分钟左右。

> alter table newtest add column newcol varchar(10) default '';

Query OK, 0 rows affected (10 min 31.64 sec)
Records: 0  Duplicates: 0  Warnings: 0可以看到修改后的.ibd文件大小相比要大了一些。

-rw-r----- 1 mysql mysql       8874 Feb 27 22:25 newtest.frm

-rw-r----- 1 mysql mysql 4047503360 Feb 27 22:34 newtest.ibd而如果我们换一个角度来看,我们删除一个字段。

--alter table newtest drop column newcol , ALGORITHM=INPLACE;  --这种方式是有问题的,采用如下的方式,我们声明使用inplace算法,而实际情况如何呢。

> alter table newtest drop column newcol , ALGORITHM=INPLACE;

Query OK, 0 rows affected (9 min 54.18 sec)
Records: 0  Duplicates: 0  Warnings: 0我们可以看到DML操作畅通无阻。

> insert into newtest(game_type,login_time,login_account,cn_master,client_ip) values(1,'2017-02-27 16:22:10','150581500032','572031626','183.128.143.113');

Query OK, 1 row affected (0.15 sec)这个过程可以看到效果和启用copy算法是一样的,为什么呢。因为添加字段,删除字段是一个数据重组的过程,所以相比而言,这个操作的代价也是昂贵的。

添加/删除索引

然后我们添加索引,启用inplace算法。

alter table newtest add index (client_ip) ,algorithm=inplace;这个过程就特别了,依旧会创建.frm的临时文件,但是数据文件不会复制,而是现改。

-rw-r----- 1 mysql mysql       8840 Feb 27 22:49 newtest.frm
-rw-r----- 1 mysql mysql 4018143232 Feb 27 23:06 newtest.ibd
...
-rw-r----- 1 mysql mysql       8840 Feb 27 23:06 #sql-6273_2980ab.frm这个过程中,DML依旧是畅通的。

> insert into newtest(game_type,login_time,login_account,cn_master,client_ip) values(1,'2017-02-27 16:22:10','150581500032','572031626','183.128.143.113');

Query OK, 1 row affected (0.04 sec)整个添加的过程相比而言,持续时间要短很多,大概是3分钟左右。

> alter table newtest add index (client_ip) ,algorithm=inplace;

Query OK, 0 rows affected (3 min 42.84 sec)
Records: 0  Duplicates: 0  Warnings: 0
而如果此时删除索引,这个过程就如同非一般的感觉,不到一秒即可完成。

> alter table newtest drop index  client_ip ,algorithm=inplace;

Query OK, 0 rows affected (0.13 sec)
Records: 0  Duplicates: 0  Warnings: 0整个过程中.frm和.ibd文件没有任何大小变化。

-rw-r----- 1 mysql mysql       8840 Feb 27 23:13 newtest.frm

-rw-r----- 1 mysql mysql 4785700864 Feb 27 23:13 newtest.ibd而如果我们为了对比同样的inpalce和copy操作场景下的代价,可以使用copy显示创建一个索引,即可得到一个基本的对比情况。

alter table newtest add index (client_ip) ,algorithm=copy;整个过程因为.ibd文件较大,持续时间也会放大很多,这个环境中执行时间是29分,差别已然非常明显。

> alter table newtest add index (client_ip) ,algorithm=copy;

Query OK, 22681430 rows affected (29 min 13.80 sec)
Records: 22681430  Duplicates: 0  Warnings: 0

小结

Online DDL还是存在着一些限定情况,很多场景还没有完全测试到,需要结合具体的场景和需求来考量。

转载地址:http://bhlul.baihongyu.com/

你可能感兴趣的文章
《金蝶ERP-K/3模拟实战——财务/供应链/生产制造(第2版)》——1.3 安装金蝶ERP-K/3(V11.X)...
查看>>
Linux 开发者考虑为内核崩溃引入条形码
查看>>
Nike 发布其开源项目,意欲何为?
查看>>
《Adobe Illustrator CS5中文版经典教程》—第0课0.1节简 介
查看>>
《Cisco IOS XR技术精要》一导读
查看>>
《PaaS程序设计》一3.3 走向公开标准
查看>>
《淘宝网开店 进货 运营 管理 客服 实战200招》——2.8 网上商品定价方法
查看>>
Maven项目中获取classpath和资源文件的路径
查看>>
《电路分析导论(原书第12版)》一1.4.2 软件包
查看>>
2014 年中国开源优秀项目获奖
查看>>
直播|排除万难,阿里巴巴大规模持续集成的技术演进之路
查看>>
阿里大幅增持Lazada 东南亚6亿用户进入天猫版图
查看>>
《jQuery EasyUI开发指南》——10.3 系统上线
查看>>
《树莓派渗透测试实战》——2.3 渗透测试需要做的准备
查看>>
《架构真经:互联网技术架构的设计》大道至简
查看>>
FreeMarker的基础语法
查看>>
《C++ AMP:用Visual C++加速大规模并行计算》——3.9 数学库函数
查看>>
《 Python树莓派编程》—— 3.5总结
查看>>
《Visual Studio程序员箴言》----2.4 IntelliSense
查看>>
如何在局域网中将Ubuntu文件夹共享给Windows
查看>>