官方online ddl

摘要:
就地算法不支持将VARCHAR列的大小从小于256字节增加到等于或大于256字节,因为在这种情况下,所需长度的字节数只能通过复制从1更改为2。创建与目标表T1 frm文件S1.frm同构的临时表。目标表T1的字典锁升级为独占锁

一、5.6版本online DDL

操作In PlaceRebuilds TableConcurrent DMLOnly Modifies Metadata说明
add/create secondary indexyesNoyes*no当表上有FULLTEXT索引除外,需要锁表,阻塞写
drop indexyesnoyesyes-
add fulltext indexyesnonono-
add primary keyyes*yesyesno即使in-place,但需要copy data,不过效率比copy方式高
drop primary keynoyesnono即使in-place,但需要copy data,不过效率比copy方式高
Dropping a primary key and adding anotherYesYesYesNo-
add columnyesyesyes*no自增列阻塞写
drop columnyesyesyesno-
Rename a columnyesnoyes*yes只改变列名不改变类型才支持写
Reorder columnsyesyesyesno-
Set default value for a columnyesnoyesyes-
Change data type of columnnoyesnono-
Dropping the column default valueyesnoyesyes-
Changing the auto-increment valueyesnoyesno*修改时内存值不是数据文件
Making a column NULLyesyesyesno-
Making a column NOT NULLyesyesyesno-
Modifying the definition of an ENUM or SET columnyesnoyesyes-
Adding a foreign key constraintyes*noyesyesINPLACE只有在foreign_key_checks=off
Dropping a foreign key constraintyesnoyesyes-
Changing the ROW_FORMATyesyesyesno
Changing the KEY_BLOCK_SIZEyesyesyesno
Convert character setnoyesnono-
optimize tableyes*yesyesno从5.6.17支持in-place,但当带有fulltext index的表用copy table方式并且阻塞写
alter table...engine=innodbyes*yesyesno从5.6.17支持in-place,当带有fulltext index的表用copy table方式并且阻塞写
Renaming a tableyesnoyesyes-

二、5.7版本online DDL(仅突出与5.6不同的地方,列出如下(未列出的同5.6))

操作In PlaceRebuilds TableConcurrent DMLOnly Modifies Metadata说明
Renaming an indexyesnoyesyes5.7新增
Adding a SPATIAL indexYesNoNoNo5.7新增
Extending VARCHAR column sizeYesNoYesYes5.7新增,只能在[0-255],[256-~]字节区间扩大

1、扩展varchar长度测试

1.1)varchar从大变小

操作In PlaceRebuilds TableConcurrent DMLOnly Modifies Metadata说明
varchar从大变小noyesnono阻塞DML

1.2) varchar从小变大

对于大小为0到255字节的VARCHAR列,需要一个长度字节来编码该值。对于大小为256或更多的字节的VARCHAR列,需要两个长度字节。
因此,in-place算法更改表只支持将VARCHAR列的大小从0字节增加到255字节,或者从256字节增加到更大的值。
in-place算法不支持将VARCHAR列的大小从小于256字节增加到等于或大于256字节的大小,因为在这种情况下,所需长度字节的数量从1变化到2,只能通过copy方式实现。
比如将VARARAR(255字节)更改为VARCHAR(256字节),只能copy算法并且阻塞写

-------------------测试---------------------

说明:采用utf8,如果存中文字符,一个字符需要3个字节,因此255字节对应最大字符数是varchar(85),也就是[0-255]对应varchar(0-85),[256-~]对应varchar(86-~)

表结构:
   create table varchar_test(
      c1 varchar(1) not null default '0'
   );
 
 1)采用online方式,扩大到85字符---支持
     alter table varchar_test change c1 c1 varchar(85) not null default '0',ALGORITHM=INPLACE, LOCK=NONE;
     Query OK, 0 rows affected (0.00 sec)
     Records: 0  Duplicates: 0  Warnings: 0
     
 2)采用online方式,扩大到86字符---不支持
    alter table varchar_test change c1 c1 varchar(86) not null default '0',ALGORITHM=INPLACE, LOCK=NONE;
    ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
    
 3)采用copy方式
    alter table varchar_test change c1 c1 varchar(86) not null default '0',ALGORITHM=copy;
     Query OK, 1 row affected (0.00 sec)
     Records: 1  Duplicates: 0  Warnings: 0
 
 4)采用online方式,从86扩大到259字符---支持
    alter table varchar_test change c1 c1 varchar(259) not null default '0',ALGORITHM=INPLACE, LOCK=NONE;
     Query OK, 0 rows affected (0.00 sec)
     Records: 0  Duplicates: 0  Warnings: 0

三、8.0版本online DDL(仅列出与5.7不同的地方)

OperationInstantIn PlaceRebuilds TablePermits Concurrent DMLOnly Modifies Metadatadesc
add columnyes*yesyesyes*no自增列阻塞写
modify index typeyesyesnoyesyes-

3、实现原理

    目标表T1上MDL(SHARED_NO_WRITE),阻塞所有写操作
    判断是否符合在线加字段的条件,如符合,执行步骤3,否则按照官方方式来新增字段。
    创建跟目标表T1同构的临时表frm文件S1.frm(含新增字段)
    目标表T1的字典锁升级为排它锁,所有关于T1表的所有读写操作被阻塞
    修改T1表InnoDB内部数据字典信息,增加新字段。
    将S1.frm重命名为T1.frm
    释放表T1的字典锁

2、支持instant的ddl

Change index option
Rename table (in ALTER way)
SET/DROP DEFAULT
MODIFY COLUMN
Add/drop virtual columns
Add columns– We call this instant ADD COLUMN


4、使用最新算法instant条件:

1)不能合并写到其他不支持instant算法的alter 语句后面;

alter table sbtest1 add index idx_2(k),add c5 varchar(10) not null default '0' ,ALGORITHM=instant;
ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=COPY/INPLACE.

2) 不支持before和after关键字,只能默认的加到最后一列;

alter table sbtest1 add c2 varchar(10) not null default '0';
Query OK, 0 rows affected (0.09 sec)
Records: 0  Duplicates: 0  Warnings: 0

alter table sbtest1 add c4 varchar(10) not null default '0' after id;
Query OK, 0 rows affected (26.42 sec)
Records: 0  Duplicates: 0  Warnings: 0

alter table sbtest1 add c5 varchar(10) not null default '0' after id,ALGORITHM=instant;
ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=COPY/INPLACE.

3)不支持ROW_FORMAT=COMPRESSED类型的表;

root:sbtest> show table status like 'sbtest1'G
*************************** 1. row ***************************
           Name: sbtest1
         Engine: InnoDB
        Version: 10
     Row_format: Compressed
           Rows: 9906340
 Avg_row_length: 73
    Data_length: 724033536
Max_data_length: 0
   Index_length: 101171200
      Data_free: 3145728
 Auto_increment: 20000020
    Create_time: 2018-10-21 15:48:22
    Update_time: NULL
     Check_time: NULL
      Collation: utf8_general_ci
       Checksum: NULL
 Create_options: max_rows=100000000 row_format=COMPRESSED
        Comment: 
1 row in set (0.00 sec)

root:sbtest> 
root:sbtest> alter table sbtest1 add c5 varchar(10) not null default '0',ALGORITHM=instant;
ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=COPY/INPLACE.
root:sbtest> 

4)表上有FULLTEXT index,不支持instant算法;

5)不支持临时表加字段;

6)如果表上存在大事务,instant也会被阻塞

六、官方online ddl限制

官方online ddl第1张

1、大事务可能引起MDL锁(即使是8.0.12 instant方式也是需要获取MDL锁的)


session 1:
   alter table sbtest1 ALGORITHM=INPLACE,drop column c2 ;   

session2:写入事务未提交
   set autocommit=0;
   begin;
     insert into sbtest1(c) values("session2"); --当执行后,session 1将被阻塞,状态有alter table -->Waiting for table metadata lock

session3:
     insert into sbtest1(c) values("session2");  --被阻塞

结论发现:

    dbadmin:sbtest> show processlist;
+----------+---------+-----------+--------+---------+------+---------------------------------+------------------------------------------------------+
| Id       | User    | Host      | db     | Command | Time | State                           | Info                                                 |
+----------+---------+-----------+--------+---------+------+---------------------------------+------------------------------------------------------+
| 78213439 | dbadmin | localhost | sbtest | Query   |    0 | starting                        | show processlist                                     |
| 78213440 | root    | localhost | sbtest | Query   | 1763 | Waiting for table metadata lock | alter table sbtest1 ALGORITHM=INPLACE,drop column c2 |
| 78213441 | dbadmin | localhost | sbtest | Query   | 1373 | Waiting for table metadata lock | insert into sbtest1(c) values("darren")              |

经过漫长的时间,发现session2 插入语句被回滚了(因为客户端连接超过30分钟断开导致未提交的事务自动回滚),session 1和session 3执行成功。

2、online ddl无法暂停和进度监控

3、online ddl大表可能导致从库延迟严重

免责声明:内容来源于网络,仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇为友盟消息推送开发的PHP SDK(composer版):可以按省发Android push网站大全下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

临时表与表变量深入探究

临时表或表变量我们一般用来充当中间结果集,很多时候都在用,但真正了解他们之间的区别的人还是很少的,网上流传的说法也不甚统一,所以今天我就做一个实验,让我们看看临时表和表变量的区别,以及他们各自的用途。 执行以下语句,对测试环境做准备 DBCC DROPCLEANBUFFERS --从缓冲池中删除所有清除缓冲区 DBCC FREEPROCCACHE...

Lua字符串及模式匹配

字符类基础函数举例介绍: string.len( ‘string’ ) string.lower( ‘string’ ) string.upper( ‘string’ ) string.rep( ‘a’ , 5 ) ==> aaaaa string.sub( ‘string’ , I , j ) string.sub(...

extremeComponents(ec)源码分析

eXtremeComponents(简称ec)是一系列提供高级显示的开源JSP定制标签,当前的包含的组件为eXtremeTable,用于以表形式显示数据。 其本质是jsp的自定义标签,抓住这一点就抓住了ec的本源。 1. Table定义 我们先看一下标签的定义:extremComponents.tld,其中table的标签定义如下: <t...

pyflink从入门到入土

一 安装环境与安装 您需要一台具有以下功能的计算机: Java 8 or 11 Python 3.6, 3.7 or 3.8 使用Python Table API需要安装PyFlink,它已经被发布到 PyPi,您可以通过如下方式安装PyFlink: $ python -m pip install apache-flink 安装PyFlink后,您便...

orcl 如何快速删除表中百万或千万数据

orcl 数据库表中数据达到上千万时,已经变的特别慢了,所以时不时需要清掉一部分数据。 bqh8表中目前有10000000条数据,需要保留19条数据,其余全部清除掉。 以下为个人方法: 1、首先把需要保留的数据备份到temp1临时表中。 create table temp1 as select * from bqh8 where id<20;sele...

GPT转MBR

故事背景: 一个朋友说他的移动硬盘在有的电脑有打的开,在有的上面打不开。我问是不是在win7上打的开,但在单位的windows xp上打不开? 把盘拿来一看,的确是这个问题。应该是在win7上分的GTP分区,windows xp不识别。 目标: 将GPT分区转为MBR 步骤: 先查看当前盘的分区: ➜ ~ sudo fdisk /dev/sdb Wel...