zoukankan      html  css  js  c++  java
  • 数据库遇到的问题——mysql在线修改表结构大数据表的风险与解决办法归纳

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

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

    由于mysql在线ddl(加字段、加索引等修改表结构之类的操作)过程如下:

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

    在这个过程中会锁表。造成当前操作的表无法写入数据,影响用户使用。由于需要复制原表的数据到中间表,所以表的数据量越大,等待的时候越长,卡死在那里(用户被拒绝执行update和insert操作,表现就是延迟了一直在等待)。

    其实就是对表加了个排它锁,这个时候其他用户只能读表的数据,不能写。

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

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

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

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

     

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

    表的数据量上亿。要把表的存储引擎从myisam改为innodb(我觉得存储结构都不同了,转换需要时间更长),但是他是停掉mysql服务器操作的

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

    3、使用专门的辅助工具。一些公司开发了自己的内部工具来辅助进行。比如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

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

  • 相关阅读:
    Apache CXF实战之四 构建RESTful Web Service
    使用CXF开发RESTFul服务
    Java多线程中的异常处理
    Checked异常和Runtime异常体系
    hql 语法与详细解释<转>
    hibernate实现有两种配置,xml配置与注释配置。<转>
    Hibernate配置详细解释
    重构(Refactoring)技巧读书笔记(General Refactoring Tips)
    Hibernate(1)——数据访问层的架构模式<转>
    关于layer.photos即照片显示的问题。
  • 原文地址:https://www.cnblogs.com/zheng123/p/11363928.html
Copyright © 2011-2022 走看看