mysql在线修改表结构大数据表的风险与解决办法概括

整理这篇文章的原因:php

互联网应用会频繁加功能,修改需求。那么表结构也会常常修改,加字段,加索引。在线直接在生产环境的表中修改表结构,对用户使用网站是有影响。html

之前我一直为这个问题头痛。固然那个时候不须要我来考虑,虽然咱们没专门的dba,他们数据量比咱们更大,那这种问题也会存在。因此我很想看看业界是怎么作的,我想寻找有没有更高级的方案,呵呵,让我以为每次开发一个新功能,我在线加字段都比较纠结。后来只知道,不清楚在何时,无心中看到一个资料介绍online-schema-change这个工具,因而顺便搜出了很多东西。后来逐渐发现腾讯,淘宝他们都会存在这种问题,我发现解决思路都差很少。具体看完我这篇概括的文章mysql

 

 

 

因为mysql在线ddl(加字段、加索引等修改表结构之类的操做)过程以下:linux

 A.对表加锁(表此时只读)
B.复制原表物理结构
C.修改表的物理结构
D.把原表数据导入中间表中,数据同步完后,锁定中间表,并删除原表
E.rename中间表为原表
F.刷新数据字典,并释放锁web

 

 

在这个过程当中会锁表。形成当前操做的表没法写入数据,影响用户使用。因为须要复制原表的数据到中间表,因此表的数据量越大,等待的时候越长,卡死在那里(用户被拒绝执行update和insert操做,表现就是延迟了一直在等待)。sql

其实就是对表加了个排它锁,这个时候其余用户只能读表的数据,不能写。想具体体验一下是什么效果,我之前测验对mysql的表加锁,操做的时候是如何的:http://www.cnblogs.com/wangtao_20/p/3463435.htmlshell

 

平时进行修改表的结构,更改字段,新增字段,更改字段名称通常都是经过ALTER TABLE  TABLENAE 语法进行修改的。对于测试库,在线小表或者并发访问不是很大的状况是OK。可是若是是在线大表。那就很麻烦。因为表数据量大,复制表须要比较长的时间,在这个时间段里面,表是被加了锁的(写锁),加写锁时其余用户只能select表不能update、insert表。表数据量越大,耗时越长。数据库

 

因此,对于数据量大的表,数量很大。在线修改表结构一直是一个头痛的问题,由于互联网应用的一大特色不能影响用户正常使用,不然用户会慢慢流失掉。安全

 

 

有些公司碰到的表数据很小,几万到几十万行数据一张表,可能还不会遇到应用卡死的问题。因此咱们网站在跑,开发个新功能,须要加个新字段,常常是直接操做不会影响什么(况且只是延迟写入操做而已,呵呵)服务器

看这几篇文章就知道了:

一、http://wiki.hexnova.com/pages/viewpage.action?pageId=2031684 mysql在线修改表字段形成的锁表

二、http://hidba.org/?p=795

三、好比就有人专门在加字段以前进行测验mysql是否复制表,以减低应用卡死的风险:http://www.cnblogs.com/zuoxingyu/archive/2013/03/28/2986715.html

拷贝表结构,而后插入少许的数据。去修改表结构。看影响的行。若是为0,则表示不会拷贝中间表的方式

 

 

 

目前业界实践出了一些成熟的解决办法

一、不少公司之前的作法是:停掉mysql服务器来修改表结构。而后进行滚动式更新。好比不少台mysql服务器。先修改主服务器的表结构,把这台服务器停掉来更新(通常多台主服务器,让其余主服务器提供服务)。等到更新完,就滚动到从服务器(在此以前是其余从服务器提供服务的)。其实想一想发现有个弊病:修改表结构要等到很长时间才能生效。mysql服务器越多,就须要的时间越长。那我能够理解:假设须要几天,那只有等到更新完毕。才能把代码丢上去,由于表结构没有更新完毕,新的程序操做新的字段会出错的。

 

从冯大辉那篇文章那里据说,Facebook数千台MySQL服务器在过去增长个索引须要几个月的滚动升级(后来他们本身开发了后面提到的工具,只须要几天)

 

可以停掉mysql服务器来修改字段,这就好办,时间长也无所谓,呵呵,至少用户不会使用你网站的时候卡死吧。可是互联网应用每每不能影响用户使用,因此不少公司尽可能是在凌晨的时候进行操做(这个时候访问用户少,对用户影响就小)

好比像这个例子:http://www.mysqlops.com/2011/03/30/myisam-innodb.html

表的数据量上亿。要把表的存储引擎从myisam改成innodb(我以为存储结构都不一样了,转换须要时间更长),可是他是停掉mysql服务器操做的

阿里巴巴的冯大辉分享中也提到,业务应用大,需求就会频繁变化。因此就常常涉及到修改数据库字段,在线的调整字段是要考虑不少的问题的。做者认为,目前没有特别的方法来解决这个问题(技术是适应需求变化,支撑运营的)。他说豆瓣对此也很头痛,只能把服务器短暂的停一下。

 

二、测验法。加字段,加索引,先在测试环境模拟测试一下须要多长时间。省得服务器生产环境正式加的时候,应用卡死了,好有个预期准备。

我记得之前在a公司,表数据量也上千万,压根就没这种测验吧,大白天,就直接加字段和索引,反正我也不知道前台影响如何,当时我也没这个经验,况且我也不是技术负责人,呵呵,技术负责人都没不清楚这个,我那就更加没了,那个技术经理是作企业级开发的,跟web开发环境和思惟方式是不一样的,他不清楚会存在这些影响吧,再说,当时在加的时候无法凑巧用户投诉说,网站没法下单了啊,没这么巧的状况。其实从我如今理解角度来看,我绝对会更加严格点。

 

前面也提到了,国外有人研究修改表结构会不会复制一张临时表,就看"rows affected “的值。若是为0,则表示不会拷贝中间表的方式,这样子就很快的。我没试过

 

三、使用专门的辅助工具。一些公司开发了本身的内部工具来辅助进行。好比facebook。

另外腾讯的技术也介绍了他们本身定制的tmysql进行在线加字段的实现原理:

http://www.zhdba.com/mysqlops/2013/09/14/mysql-innodb-online-ddl/

 

facebook本身开发的工具,官网:

http://bazaar.launchpad.net/~mysqlatfacebook/mysqlatfacebook/tools/files/head:/osc

 

 

----------------------------------------------------------------------

我记得好像最早是facebook进行了方案创新(呵呵,当你的遇到的是复杂问题,没有人解决过就只能先创造新的技术方案了),当时冯大辉专门写了一篇,其余文章介绍他们的创新。其余工具都是跟这个思路差很少的。不过我下载了facebook官网的,是用php实现的。没具体看。由于下载的包里面都是php文件。

 

 

总的来讲,这些工具大体的理大同小异:表结构的修改在建立的一张新表中执行(这样不须要锁定原表了,也就不会影响mysql提供服务),更为关键的是解决了一个问题,当这个间隔时间内,用户在使用mysql,对表数据进行了更新怎么办?

 

工具的解决办法思路是,在原表中建立几个触发器针对uptate、delete 、insert操做都记录下来,这样子把对原表的操做记录下来,方便更新到新创建的临时表中中去。

 

 

听过豆瓣网的架构变迁分享会中提到,他们之前在这方面也吃过苦头的,一张很大的表(好比上千万),在线加个索引,因为数据量大,整个应用就卡死了。

其实有时候卡几个小时可能都很正常。死锁了嘛。另外对临时表要进行复制数据,创建这个临时表也须要时间嘛。

 

他们如今用的办法是:先拷贝一张如出一辙的表,数量也是差很少,先在这张表上面测试,看看须要多长时间。若是几分钟,是在能够接受的时间范围内,就能够。若是几个小时就不行了。这样子提前预先知道。

另外,也使用了online-schema-change这个工具。

 

关于online-schema-change

是percona推出的一个针对mysql在线ddl的工具

percona是一个mysql分支维护公司,专门提供mysql技术服务的。个人理解,相似于linux的分支redhat公司

官网下载地址为:http://www.percona.com/redir/downloads/percona-toolkit/2.2.1/percona-toolkit-2.2.1.tar.gz

 

腾讯,淘宝,百度这些公司多少都有本身开发的工具来解决这个头痛的问题。

 

 

另外,mysql5.5企业版是支持在线ddl了,不过企业版要收费嘛

 

MySQL 5.6改进了安全功能,例如对关键配置文件和用户密码的加密方式,可是对InnoDB的提高才是大新闻。使用该存储引擎的最后一个主要障碍即是缺乏全文索引,可是如今这个问题已经不复存在了。

该版本还为InnoDB引入了在线DDL,DBA必定会很是喜欢这个功能。增长、重命名和删除列等经常使用的操做能够和并发查询同时执行。尽管可能涉及到一些数据的复制或重组,可是大多数在线DDL操做都可以就地执行。

相关文章
相关标签/搜索