onlineDDL测试


onlineDDL语法:
 alter table
  ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
  ADD   [COLUMN] col_name  column_definition [FIRST|AFTER col_name]
  CHANGE [COLUMN] old_col_name new_col_name column_definition [FIRST|AFTER col_name]
  MODIFY [COLUMN] col_name column_definition
 [FIRST | AFTER col_name],
ALGORITHM [=] {DEFAULT|INPLACE|COPY}  LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE};

简单的说就是原来的语句上,加个ALGORITHM=xxx LOCK=XXXX
ALGORITHM指定了onlineDDL时候是使用COPY,还是INPLACE,
(1)COPY表示执行DDL的时候会创建临时表。
(2)INPLACE表示不需要创建临时表。(inplace英文单词是原地的意思)
(3)DEFAULT表示根据参数old_alter_table来判断是通过INPLACE还是COPY的算法,old_alter_table参数默认为OFF,表示采用INPLACE的方式

LOCK部分为索引创建或删除时对表添加锁的情况,默认是default,可选择的如下:
(1)NONE,目标表不添加任何锁,可以进行读写操作,不阻塞任何操作。如果手工指定NONE,但是onlineDDL不支持SHARE模式,返回一个错误信息,告诉你用SHARE摸索。

(2)SHARE,对操作表加一个S锁。不阻塞读操作。写操作会阻塞,将会发生等待MDL锁,如果手工指定SHARE,但是onlineDDL不支持SHARE模式,将返回一个错误信息。

(3)EXCLUSIVE,执行索引创建或删除时,对目标表加上一个X锁。读写事务均不能进行。会阻塞所有的线程。这和COPY方式类似,但是不需要像COPY方式那样创建一张临时表。

(4)DEFAULT,该模式首先会判断当前操作是否可以使用NONE模式,若不能,则判断是否可以使用SHARE模式,最后判断是否可以使用EXCLUSIVE模式。也就是说DEFAULT会通过判断事务的最大并发性来判断执行DDL的模式。

1.创建一个测试表

(mysql5.7-101)[email protected] [test]> create table ddl_test (id int(11) not null,name varchar(20) not null default ‘‘,age int(3) null default 0,primary key(id));
Query OK, 0 rows affected (0.02 sec)

(mysql5.7-101)[email protected] [test]> 

###这边先看看onlineDDL语法,就是DDL语句后面价格ALGORITHM=INPLACE, lock=none,是否拷贝表,锁模式,什么都指定默认为defalut
(mysql5.7-101)[email protected] [test]> ALTER TABLE `ddl_test` MODIFY COLUMN `id`  int(11) NOT NULL AUTO_INCREMENT FIRST ,ALGORITHM=INPLACE, lock=none;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
(mysql5.7-101)[email protected] [test]> ALTER TABLE `ddl_test` MODIFY COLUMN `id`  int(11) NOT NULL AUTO_INCREMENT FIRST ,ALGORITHM=cpoy, lock=none;
ERROR 1800 (HY000): Unknown ALGORITHM ‘cpoy‘
(mysql5.7-101)[email protected] [test]> ALTER TABLE `ddl_test` MODIFY COLUMN `id`  int(11) NOT NULL AUTO_INCREMENT FIRST ,ALGORITHM=copy, lock=none;
ERROR 1846 (0A000): LOCK=NONE is not supported. Reason: COPY algorithm requires a lock. Try LOCK=SHARED.
(mysql5.7-101)[email protected] [test]> ALTER TABLE `ddl_test` MODIFY COLUMN `id`  int(11) NOT NULL AUTO_INCREMENT FIRST ,ALGORITHM=copy, lock=shared;
Query OK, 10 rows affected (0.00 sec)
Records: 10  Duplicates: 0  Warnings: 0

创建一个大表

(mysql5.7-101)[email protected] [test]> insert into ddl_test (name,age) select name,age from ddl_test;
Query OK, 20971520 rows affected (1 min 20.73 sec)
Records: 20971520  Duplicates: 0  Warnings: 0

###onlineDDL,前不能有个大事务,不然会等待MDL锁
session 1

(mysql5.7-101)[email protected] [test]> select count(name) from ddl_test;

session 2
(mysql5.7-101)[email protected] [test]> alter table ddl_test add column address varchar(255) not null default ‘‘,ALGORITHM=INPLACE, lock=none;

session 3
(mysql5.7-101)[email protected] [crm]> show processlist;
+----+---------+---------------------+------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+
| Id | User    | Host                | db   | Command | Time | State                           | Info                                                                                                 |
+----+---------+---------------------+------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+
| 40 | root    | localhost           | test | Query   |    6 | optimizing                      | select count(name) from ddl_test                                                                     |
| 41 | root    | localhost           | test | Query   |    3 | Waiting for table metadata lock | alter table ddl_test add column address varchar(255) not null default ‘‘,ALGORITHM=INPLACE, lock=non |
| 42 | root    | localhost           | crm  | Query   |    0 | starting                        | show processlist                                                                                     |
| 44 | odstest | 172.16.123.63:9689  | NULL | Sleep   |  921 |                                 | NULL                                                                                                 |
| 45 | odstest | 172.16.123.63:9707  | test | Sleep   |  876 |                                 | NULL                                                                                                 |
| 46 | odstest | 172.16.123.63:10169 | test | Sleep   |  893 |                                 | NULL                                                                                                 |
| 47 | odstest | 172.16.123.63:8959  | test | Sleep   |   79 |                                 | NULL                                                                                                 |
+----+---------+---------------------+------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+
7 rows in set (0.00 sec)
在等待MDL锁

2.测试onlineDDL

#增加列

session 1

(mysql5.7-101)[email protected] [test]> alter table ddl_test add column address varchar(255) not null default ‘‘,ALGORITHM=INPLACE, lock=none;

session 2

(mysql5.7-101)[email protected] [test]> update ddl_test set name=‘adfadf‘ where id>1 and id <10000000;

session 3
看到木有,并不阻塞update

(mysql5.7-101)[email protected] [crm]> show processlist;
+----+---------+---------------------+------+---------+------+----------------+------------------------------------------------------------------------------------------------------+
| Id | User    | Host                | db   | Command | Time | State          | Info                                                                                                 |
+----+---------+---------------------+------+---------+------+----------------+------------------------------------------------------------------------------------------------------+
| 40 | root    | localhost           | test | Query   |    3 | updating       | update ddl_test set name=‘adfadf‘ where id>1 and id <10000000                                        |
| 41 | root    | localhost           | test | Query   |    5 | altering table | alter table ddl_test add column address varchar(255) not null default ‘‘,ALGORITHM=INPLACE, lock=non |
| 42 | root    | localhost           | crm  | Query   |    0 | starting       | show processlist                                                                                     |
| 44 | odstest | 172.16.123.63:9689  | NULL | Sleep   | 1812 |                | NULL                                                                                                 |
| 45 | odstest | 172.16.123.63:9707  | test | Sleep   | 1767 |                | NULL                                                                                                 |
| 46 | odstest | 172.16.123.63:10169 | test | Sleep   | 1784 |                | NULL                                                                                                 |
| 47 | odstest | 172.16.123.63:8959  | test | Sleep   |  970 |                | NULL                                                                                                 |
+----+---------+---------------------+------+---------+------+----------------+------------------------------------------------------------------------------------------------------+
7 rows in set (0.00 sec)
删除一行数据试试,也不阻塞
(mysql5.7-101)[email protected] [test]> delete from ddl_test where id=20000000;
Query OK, 1 row affected (0.02 sec)

(mysql5.7-101)[email protected] [test]> 

####删除列
session 1
(mysql5.7-101)[email protected] [test]> select count(name) from ddl_test;
+-------------+
| count(name) |
+-------------+
|    41943040 |
+-------------+
1 row in set (6.99 sec)
session 2
(mysql5.7-101)[email protected] [test]> alter table ddl_test drop column address,algorithm=inplace,lock=none;

session 3

(mysql5.7-101)[email protected] [crm]> show processlist;
+----+---------+---------------------+------+---------+------+----------------+----------------------------------------------------------------------+
| Id | User    | Host                | db   | Command | Time | State          | Info                                                                 |
+----+---------+---------------------+------+---------+------+----------------+----------------------------------------------------------------------+
| 40 | root    | localhost           | test | Query   |    3 | optimizing     | select count(name) from ddl_test                                     |
| 41 | root    | localhost           | test | Query   |   10 | altering table | alter table ddl_test drop column address,algorithm=inplace,lock=none |
| 42 | root    | localhost           | crm  | Query   |    0 | starting       | show processlist                                                     |
| 44 | odstest | 172.16.123.63:9689  | NULL | Sleep   | 1079 |                | NULL                                                                 |
| 45 | odstest | 172.16.123.63:9707  | test | Sleep   | 1034 |                | NULL                                                                 |
| 46 | odstest | 172.16.123.63:10169 | test | Sleep   | 1051 |                | NULL                                                                 |
| 47 | odstest | 172.16.123.63:8959  | test | Sleep   |  237 |                | NULL                                                                 |
+----+---------+---------------------+------+---------+------+----------------+----------------------------------------------------------------------+
7 rows in set (0.00 sec)

忘记了是DML,删除一行试一下,看会阻塞么,哈哈,并不阻塞(因为表数据很多,执行这个语句,会话二还在执行)
(mysql5.7-101)[email protected] [test]> delete from ddl_test where id=200;
Query OK, 0 rows affected (0.02 sec)

(mysql5.7-101)[email protected] [test]>
###

#####修改列
先试一下看看能不能不拷贝表,
(mysql5.7-101)[email protected] [test]> alter table ddl_test modify column address varchar(200) not null default ‘‘,ALGORITHM=INPLACE, lock=none;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
呵呵了,要拷贝表
(mysql5.7-101)[email protected] [test]> alter table ddl_test modify column address varchar(200) not null default ‘‘,ALGORITHM=copy, lock=none;
那么看看是不是不锁表,也呵呵了,只支持共享锁,那么意味这阻塞DML,不阻塞select
ERROR 1846 (0A000): LOCK=NONE is not supported. Reason: COPY algorithm requires a lock. Try LOCK=SHARED.
(mysql5.7-101)[email protected] [test]> 

session 1

(mysql5.7-101)[email protected] [test]> alter table ddl_test modify column address varchar(200) not null default ‘‘,ALGORITHM=copy, lock=shared;
Query OK, 83886079 rows affected (5 min 21.72 sec)
Records: 83886079  Duplicates: 0  Warnings: 0

session 2

(mysql5.7-101)[email protected] [test]> update ddl_test set name=‘adeefadf‘ where id>1 and id <10000000;
Query OK, 9606885 rows affected (8 min 26.51 sec)
Rows matched: 9606885  Changed: 9606885  Warnings: 0
session 3

(mysql5.7-101)[email protected] [test]> show processlist;
+----+---------+--------------------+------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+
| Id | User    | Host               | db   | Command | Time | State                           | Info                                                                                                 |
+----+---------+--------------------+------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+
| 42 | root    | localhost          | crm  | Sleep   | 4536 |                                 | NULL                                                                                                 |
| 49 | root    | localhost          | test | Query   |    0 | starting                        | show processlist                                                                                     |
| 51 | odstest | 172.16.123.63:7428 | NULL | Sleep   | 2966 |                                 | NULL                                                                                                 |
| 53 | odstest | 172.16.123.63:1677 | test | Sleep   |  620 |                                 | NULL                                                                                                 |
| 54 | odstest | 172.16.123.63:2082 | test | Sleep   |  606 |                                 | NULL                                                                                                 |
| 56 | root    | localhost          | NULL | Sleep   |  262 |                                 | NULL                                                                                                 |
| 57 | root    | localhost          | test | Query   |    5 | copy to tmp table               | alter table ddl_test modify column address varchar(200) not null default ‘‘,ALGORITHM=copy, lock=sha |
| 58 | root    | localhost          | test | Query   |    2 | Waiting for table metadata lock | update ddl_test set name=‘adeefadf‘ where id>1 and id <10000000                                      |
+----+---------+--------------------+------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+
8 rows in set (0.00 sec)

DML在等待MDL锁,那么来看看select会不会阻塞,新起一个会话,
session 4(mysql5.7-101)[email protected] [test]> select count(name) from ddl_test;

session 3 再次查看一下
(mysql5.7-101)[email protected] [test]> show processlist;
+----+---------+--------------------+------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+
| Id | User    | Host               | db   | Command | Time | State                           | Info                                                                                                 |
+----+---------+--------------------+------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+
| 42 | root    | localhost          | test | Query   |   15 | optimizing                      | select count(name) from ddl_test                                                                     |
| 49 | root    | localhost          | test | Query   |    0 | starting                        | show processlist                                                                                     |
| 51 | odstest | 172.16.123.63:7428 | NULL | Sleep   | 3033 |                                 | NULL                                                                                                 |
| 53 | odstest | 172.16.123.63:1677 | test | Sleep   |  687 |                                 | NULL                                                                                                 |
| 54 | odstest | 172.16.123.63:2082 | test | Sleep   |  673 |                                 | NULL                                                                                                 |
| 56 | root    | localhost          | NULL | Sleep   |  329 |                                 | NULL                                                                                                 |
| 57 | root    | localhost          | test | Query   |   72 | copy to tmp table               | alter table ddl_test modify column address varchar(200) not null default ‘‘,ALGORITHM=copy, lock=sha |
| 58 | root    | localhost          | test | Query   |   69 | Waiting for table metadata lock | update ddl_test set name=‘adeefadf‘ where id>1 and id <10000000                                      |
+----+---------+--------------------+------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+
8 rows in set (0.00 sec)
不阻塞select

小结:只要LOCK模式不是NONE的DDL操作,锁最小范围都是共享锁,意味着还是会阻塞DML,其他情况我就不一一测试了,参考官方手册

问题

####

(mysql5.7-101)[email protected] [test]> alter table ddl_test add column address varchar(255) not null default ‘‘,ALGORITHM=INPLACE, lock=none;
ERROR 1799 (HY000): Creating index ‘FTS_DOC_ID_INDEX‘ required more than ‘innodb_online_alter_log_max_size‘ bytes of modification log. Please try again.
(mysql5.7-101)[email protected] [test]> show global variables like ‘innodb_online_alter_log_max_size‘;
+----------------------------------+-----------+
| Variable_name                    | Value     |
+----------------------------------+-----------+
| innodb_online_alter_log_max_size | 134217728 |
+----------------------------------+-----------+
1 row in set (0.02 sec)
支持动态修改
(mysql5.7-101)[email protected] [test]>
(mysql5.7-101)[email protected] [(none)]> set global innodb_online_alter_log_max_size=2147483648;
Query OK, 0 rows affected (0.00 sec)

(mysql5.7-101)[email protected] [(none)]> 

innodb存储引擎实现Online DDL的原理是在执行创建或者删除操作同时,将DML操作日志写入到一个缓存中,待完成索引创建后再将重做应用到表上,以此达到数据的一致性。
这个缓存的大小由参数innodb_online_alter_log_max_size控制,默认大小为128MB,支持动态修改
如果更新的表比较大,并且创建过程中有大量的写操作,如果遇到innodb_online_alter_log_max_size的空间不能存放日志时,会抛出相应的错误,
如果遇到改错误,我们可以调大该参数,以此获得更大的日志缓存空间。还可以设置lock的模式为SHARE,这样在执行过程中会阻塞写操作发生,因此不需要进行DML日志的记录。

参考资料:

http://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html

时间: 2024-07-29 06:22:17

onlineDDL测试的相关文章

iOS app打包 -- 生成ipa测试包 步骤详解

最近有小伙伴问我如何打成ipa包分发给测试人员 , 虽然现在网上的教程很多,但是也很杂, 没有一个比较完整的讲解. 利用工作之余, 就说一下如何生成ipa包?共分为两种方法. 第一种方法: 1) 至于配置发布证书和AdHoc描述文件, 就不再累述, 下载下来双击安装即可.(ps: 生成AdHoc描述文件的时候要注意勾选所有的设备, 只有被描述文件包含的设备才能进行相应的测试. 如果是企业账号的话则不需要添加设备的udid). 2) 接下来开始配置xCode里的工作(包括发布证书和描述文件), 注

Monkey测试

1             概述 Monkey测试是Android自动化测试的一种手段.Monkey测试本身非常简单,就是模拟用户的按键输入,触摸屏输入,手势输入等,看设备多长时间会出异常. 当Monkey程序在模拟器或真实设备运行的时候,程序会产生一定数量或一定时间内的随机模拟用户操作的事件, 如点击,按键,手势等, 以及一些系统级别的事件.通常也称随机测试或者稳定性测试. 2             测试步骤 2.1   测试前提条件 1.将手机恢复出厂设置 2.恢复出厂设置后,进入设置--

软件测试中的数据库测试

数据库中数据的基本结构 定义一:数据元素集合(也可称数据对象)中各元素的关系. 定义二:相互之间存在特定关系的数据元素集合. 一个表(数据库),我们就称它为一个数据结构,它由很多记录(数据元素)组成,每个元素又包括很多 字段(数据项)组成数据库测试分类系统测试.集成测试.单元测试.功能测试.性能测试.安全测试系统测试.数据库在初期设计中需要进行分析测试. 对于各种数据元素进行完美融合,并理清相互之间的关系便是数据库结构的基本定义. 在数据库中,不同数据之间会存在既定的特殊关系,其属于各种数据元素

一些基本LINUX命令以及测试环境的搭建

LINUX操作系统平时用的不多,资深测试与开发同学们用的比较多,像我这样的一个人,只喜欢WINDOWS操作系统.但LINUX操作系统也用过一段时间, 知道一些基本命令,如果不记得的话,就百度一下,拿来就用,也不会太难.下面记录一下自己知道的一些常用命令,方便自己查询,以供大家参考. 首先 LINUX系统的特点是:稳定,安全,开源,可裁剪性.(可裁剪性还真没有理解透) 其次:LINUX 有四个版本,分别是:DEBIAN,UBUNTU,RED HAT,CENTOS. 我只用过CENTOS版本,不过公

微信+WeTest:小程序云端测试系统上线

日前,微信新增小程序测试系统,可便于开发者检测小程序缺陷,评估小程序产品质量.在小程序发布之前,开发者可将小程序代码提交到测试系统,在不同型号的手机真机上运行,执行完毕后自动生成测试报告.小程序云端测试平台,由WeTest提供基础支持,下载"微信开发者工具"即可使用. 小程序测试报告示例:  一. 云真机测试 Beta 为了方便广大开发者检测小程序程序缺陷.评估小程序产品质量,微信提供了免费的云真机测试环境以及一整套测试方案.在小程序交付到真实用户手中使用之前,你可以将小程序分发到云真

微信公众号API测试——接口调用频率限制

接口频率限制[1] 公众号调用接口并不是无限制的.为了防止公众号的程序错误而引发微信服务器负载异常,默认情况下,每个公众号调用接口都不能超过一定限制,当超过一定限制时,调用对应接口会收到如下错误返回码: {"errcode":45009,"errmsg":"api freq out of limit"} 各接口调用频率限制如下: 接口 每日限额 获取access_token 2000 自定义菜单创建 1000 自定义菜单查询 10000 自定义菜

手把手教你如何搭建自己的渗透测试环境

介绍 白帽子是指个体发起的黑客攻击,找到系统潜在的可能被恶意黑客利用的的漏洞或脆弱点.在目标不知情或者没得到授权的情况下发起黑客攻击是非法的.所以通常是建立一个自己的实验室,练习黑客技术. 在这个实验室里,你能看到如何创建一个自己的黑客环境,练习各种各样的黑客攻击技术.我们将会探讨不同类型的虚拟系统,构建一个虚拟网络,在虚拟环境中运行试用版的操作系统,搭建一个有漏洞的web应用程序,安装Kali LInux,执行渗透测试. 所需条件: VMware Workstation Windows XP系

游戏测试经历的流程及发版本注意的问题(或许有遗漏)

一.测试流程: 1.测试人员需要参与需求会议,了解需求,如有必要,提出疑问点,产品修改正 2.需求确定后,编辑测试用例或者测试功能点 3.开发提交完毕后,执行测试用例(要求开发出电脑版,节约前期打包,安装包的时间) 4.发现bug,提交bug到禅道,并通知相关人员 5.开发组修正bug,禅道指派给测试人员,表明已修复 6.对已修正的bug,进行回归测试 7.修正完毕的bug在禅道上置为关闭 8.待电脑版功能验证完毕后,进行手机包测试 9.整体测试完毕,可以发布包 补充: 1.中途有修改需求,也需

1.2软件生命周期&amp;测试流程

软件的生命周期 可行性分析-需求分析-软件设计-软件编码-软件测试-软件维护 1.可行性分析 主要确定软件开发的目的和可行性(PM) 2.需求分析 对软件的功能进行详细的分析(PM),输出需求规格说明书(原型图) 3.软件设计(DEV) 把需求分析得到的结果转换为软件结构和数据结构,形成系统架构 概要设计:搭建架构.模块功能.接口连接和数据传输 详细设计:模块深入分析,对各模块组合进行分析,伪代码   包含数据库设计说明 4.软件编码(DEV) 可运行的程序代码 5.软件测试 5.1.单元测试(