mysql online ddl2
大家知道,互联网业务是典型的OLTP(online transaction process)应用,这种应用访问数据库的特点是大量的短事务高并发运行。因此任何限制高并发的动作都是不可接受的,甚至会给网站带来灾难。对于数据库而言,高并发通常与事务ACID是一对矛盾体,为了保证事务的ACID特性,必需用一定的手段来控制并发,比如基于锁的并发控制,亦或是基于MVCC的并发控制。基于MVCC的并发控制只是一定程度上解决了读不阻塞的问题,但对于DML或DDL依然通过锁机制来保证事务的隔离性。
所有数据库操作中DDL的锁粒度是最大的,通过包括元数据锁和表对象锁。常见的DDL包括alter,create,drop等,对于create,drop而言,通常执行过程很快,因此影响比较少,而对于alter操作,尤其是对大表的alter,这个过程可能持续时间很长,由于变更过程中,表对象的DML操作会阻塞,因此一个alter操作很有可能导致前台的网站应用出现大量的数据库访问超时情况。那么怎么解呢?第一种是alter操作不上锁,从而不影响写操作,若不行退而求其次,将alter操作的时间想办法缩短,减少不可访问表的时间。
对于mysql数据库而言,解决alter的问题也有一个过程,直到5.6才推出了online ddl功能。5.5版本通过FIC(fast index creation),提高了alter操作中加索引和删索引的速度,5.6的online ddl则优化更多,增加了更多的“在线”操作。在介绍FIC和online ddl的原理之前,我们先来看看有哪些常见的alter操作,参见表1
alter动作 |
说明 |
Add index,drop index |
增加、删除、修改二级索引 |
Add column,drop column |
增加、删除、修改列 |
Add primary key,drop primary key |
增加、删除、修改主键索引 |
Set character set utf8/gbk |
修改字符集、修改存储引擎 |
Optimize table |
重组表 |
表1
那么针对以上几种常见的场景,我们看到FIC和online ddl到底做了什么,它们实现的原理是怎样的,下文的分析都是基于innodb表。
对于一般的alter操作而言,它的原理基本是这样的,假设需要对A表做表结构变更,首先创建一个目的表结构的临时表B;其次是锁表,将数据从A表拷贝到B表;最后是将B表rename成A表,释放锁。
FIC针对加索引和删索引做了优化,因为这种情景下,innodb的表存储结构没有变,只是多了或少了索引,因此没有必要进行全表拷贝,直接增加或删除索引即可,这样就减少了拷贝表的时间,同时也减少了锁表时间。对于需要该表存储结构的alter操作,FIC则无能无力。由于mysql迟迟不出现Online ddl的版本,FIC的场景不通用,并且依然会阻塞写,业务不可接受。没有办法,很多时候做表结构变更需要在业务低峰期(凌晨),通过主备库切换的方式去做,真是苦了DBA的童鞋们。
还好,在mysql5.6出现之前,percona公司提供了“在线”表结构变更的工具pt-online-schema-change,这个工具给dba童鞋们带来了福音。工具的核心原理是通过insert… select…语句进行一次全量拷贝,通过触发器记录表结构变更过程中产生的增量,从而达到表结构变更的目的。假设对A表进行变更,主要步骤如下:
- 创建目的表结构的空表,A_gst;
- 在A表上创建触发器,包括增、删、改触发器;
- 通过insert…select…limit N 语句分片拷贝数据到目的表
- Copy完成后,将A_gst表rename到A表
通过这个方式后,执行alter操作时,不再阻塞读和写,而且支持的alter语句也更广泛,比如表1列出来的几种情况都可以支持,除了Optimize table以外。
Mysql online ddl的原理实质与pt-online-schema-change工具原理相同,只不过将这一过程封装在mysql内部了。虽然如此,这种方式也有一定的弊端和限制,比如需要有主键,拷贝表速度不如源生锁表拷贝表快等。
最后,举一个例子说明alter操作在5.5和5.6对于DML的影响。从表2可以看到,5.5和5.6中,查询和更新都会阻塞alter操作;若有alter操作,5.5版本中,alter不会阻塞读,但会阻塞写;5.6版本中,alter不会阻塞读和写。
时间点 |
会话A(5.6) |
会话A(5.5) |
会话B |
会话C |
1 |
set autocommit=0; update t set c2='9999' where c1=4; |
set autocommit=0; update t set c2='9999' where c1=4; |
||
2 |
alter table t drop column c3; |
|||
3 |
Show processlist; B:Waiting for table metadata lock |
|||
4 |
A:提交事务 commit |
|||
5 |
Show processlist; B:copy to tmp table |
|||
6 |
B:继续执行 |
|||
7 |
Select count(*) from t; 正常执行 |
Select count(*) from t; 正常执行 |
||
8 |
update t set c2='9999' where c1=4; 正常执行 |
update t set c2='9999' where c1=4;阻塞 |
||
8 |
Show processlist; A(5.5): Waiting for table metadata lock B: copy to tmp table |
|||
9 |
B执行完毕 |
|||
10 |
A执行完毕 |
表2
mysql online ddl2的更多相关文章
- Hadoop 中利用 mapreduce 读写 mysql 数据
Hadoop 中利用 mapreduce 读写 mysql 数据 有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...
- mysql每秒最多能插入多少条数据 ? 死磕性能压测
前段时间搞优化,最后瓶颈发现都在数据库单点上. 问DBA,给我的写入答案是在1W(机械硬盘)左右. 联想起前几天infoQ上一篇文章说他们最好的硬件写入速度在2W后也无法提高(SSD硬盘) 但这东西感 ...
- LINUX篇,设置MYSQL远程访问实用版
每次设置root和远程访问都容易出现问题, 总结了个通用方法, 关键在于实用 step1: # mysql -u root mysql mysql> Grant all privileges o ...
- nodejs进阶(6)—连接MySQL数据库
1. 建库连库 连接MySQL数据库需要安装支持 npm install mysql 我们需要提前安装按mysql sever端 建一个数据库mydb1 mysql> CREATE DATABA ...
- MySQL高级知识- MySQL的架构介绍
[TOC] 1.MySQL 简介 概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一种关联数据库管理系统,将数据保存在不同的表中,而 ...
- 闰秒导致MySQL服务器的CPU sys过高
今天,有个哥们碰到一个问题,他有一个从库,只要是启动MySQL,CPU使用率就非常高,其中sys占比也比较高,具体可见下图. 注意:他的生产环境是物理机,单个CPU,4个Core. 于是,他抓取了CP ...
- 我的MYSQL学习心得(一) 简单语法
我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...
- Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制
将通用的序列号生成器库 从SQL Server迁移到Mysql 遇到的一个问题,就是TimeStamp/RowVersion并发控制类型在非Microsoft SQL Server数据库中的实现.SQ ...
- Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境
首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...
随机推荐
- TestNG官方文档中文版(2)-annotation(转)
1. 介绍 TestNG是一个设计用来简化广泛的测试需求的测试框架,从单元测试(隔离测试一个类)到集成测试(测试由有多个类多个包甚至多个外部框架组成的整个系统,例如运用服务器). 编写一个测试的 ...
- CSS书写规范、顺序
写了这么久的CSS,但大部分前端er都没有按照良好的CSS书写规范来写CSS代码,这样会影响代码的阅读体验,总结一个CSS书写规范.CSS书写顺序供大家参考,这些是参考了国外一些文章以及我的个人经验总 ...
- IOS-day02_OC中类的声明
在上一个笔记中类的使用中,在编译链接的时候会有警告,原因就是我们没有对类进行声明 类的声明如下:使用关键字@interface #import <Foundation/Foundation.h& ...
- 如何在 Windows Azure 的虚拟机 ubuntu 上面安装和配置 openVPN(二)
第二步:登录到虚拟机 一旦创建好虚拟机后,默认azure会打开TCP 22端口,即SSH的端口.所以,我们可以通过远程连接,访问和管理该虚拟机. 首先,下载一个PuTTY软件.该软件很简单,就一个可执 ...
- C语言——递归练习
1.炮弹一样的球状物体,能够堆积成一个金字塔,在顶端有一个炮弹,它坐落在一个4个炮弹组成的层面上,而这4个炮弹又坐落在一个9个炮弹组成的层面上,以此类推.写一个递归函数CannonBall,这个函数把 ...
- delphi 单例模式实现
unit Unit2; interface uses System.SysUtils; type { TSingle } TSingle = class(TObject) private FStr: ...
- homework-10
不多不说这是一次神奇的作业,作业一拖再拖,到最后发现.... 首先,在一开始的最大字数和问题实现图形界面主要是由我的小伙伴邹同学完成的,所以当我第一次看到说要显示详细运行过程的时候感到很迷茫. 第一感 ...
- 问题-Delphi2007编译时提示内存错误“sxs.dll. No Debug Info.ACCESS 0xXXXXX"
相关资料:http://bbs.csdn.net/topics/340132341 问题现象:在调试程序时,未进工程文件中的TApplication.Run;证明不是代码问题. 问题原因:可能是因为* ...
- UVaLive 7267 Mysterious Antiques in Sackler Museum (if-else,枚举)
题意:给定四个矩形,要求从中选出三个,能不能拼成一个矩形. 析:说到这个题,我还坑了队友一次,读题读错了,我直接看的样例,以为是四个能不能组成,然后我们三个就拼命想有什么简便方法,后来没办法了,直接暴 ...
- UI进阶 CocoaPods的安装使用步骤
一. CocoaPods简介 CocoaPods是一个用来帮助我们管理第三方依赖库的工具.在开发iOS应用时,会经常使用第三方类库,比如SDWebImage.AFNetworking等等,手动的下载与 ...