由于某个临时需求,需要给在线MySQL的某个超过千万的表增加一个字段。此表在设计之时完全按照需求实现,并没有多余的保留字段。

我们知道在MySQL中如果要执行ALTER TABLE操作,MySQL会通过制作原来表的一个临时副本来工作。对于表结构的修改在副本上施行,然后将新表替换原始表,此时会产生锁表,用户可以从原始表读取数据,而用户的更新和写入操作都会被lock,待新表准备好后写入新表。
这对于在线的数据量较大的表来说是绝对无法容忍的,并且由于这种在线操作时间会很长,此时如果show processlist,会发现有若干的MySQL进程处于lock状态,当这种进程太多超过单台服务器允许的MySQL进程数,其它进程可能会被拒绝连接。

有哪些方案可以处理这个问题呢?

方案1、直接ALTER TABLE
这个方案只能说这仅仅是一种方案,在某些非实时在线或数据量较小时有较好的表现。

方案2、模拟数据库修改表结构的操作,在非数据库层实现整个过程。

  1. 实现业务中对于数据的读写分离
  2. 创建一个已经按需求修改好结构的新表
  3. 修改业务逻辑,将读操作指向旧表,将写操作指向新表。如果读旧表没有,再读新表,并将旧的数据写入到新表,当然这一步写入操作我们可以不用,我们可以在后台做一个定时任务将旧数据同步到新表。

这种方案有一个较大的缺点,需要业务逻辑层配合实现数据的迁移,对于业务逻辑有修改,并且如果有多台机器的话,需要一台一台的修改,较费时间,但是对于MySQL的两种主要存储引擎都适用。

方案3、facebook online schema change
facebook的OSC在整体流程上与方案2没有较大的区别,只是它在这里引入了触发器,从而不需要修改业务逻辑,在数据库层就实现了新数据的两个表的同步问题。其大概步骤如下:

  1. 按需求创建新表
  2. 针对原始表创建触发器
  3. 对于原始表的更新操作都会被触发器更新到新表中
  4. 把原始表中的数据复制到新表中
  5. 将新表替换旧表

fb的osc方案从数据库层解决了方案2的问题,但是它仅支持InnoDB存储引擎。

方案4、换一个思路,保留字段。
假设一切可以从头再来,我们也许可以加多一些冗余字段,各个类型都加一些,备用。只是,回不去了!

方案5、再换一个思路,增加扩展表。
我们不在原有的表的基础上修改了,以增加扩展表的方式,将新字段的数据写入到扩展表中,修改业务逻辑,这些字段从新表中读取。
志强同学说这是典型的维表结构设计。
暂时解决了问题,如果这些字段后续使用频率高的话,可能会有对后期维护或业务有一定的影响。

后记
基于现有的需求,只是需要记录新的字段,所以采用了扩展表的方案。

转载【http://www.phppan.com/2012/05/online-schema-change/】

问题描述

由于某个临时需求,需要给在线MySQL的某个超过千万的表增加一个字段。此表在设计之时完全按照需求实现,并没有多余的保留字段。

我们知道在MySQL中如果要执行ALTER TABLE操作,MySQL会通过制作原来表的一个临时副本来工作。对于表结构的修改在副本上施行,然后将新表替换原始表,此时会产生锁表,用户可以从原始表读取数据,而用户的更新和写入操作都会被lock,待新表准备好后写入新表。
这对于在线的数据量较大的表来说是绝对无法容忍的,并且由于这种在线操作时间会很长,此时如果show processlist,会发现有若干的MySQL进程处于lock状态,当这种进程太多超过单台服务器允许的MySQL进程数,其它进程可能会被拒绝连接。

有哪些方案可以处理这个问题呢?

方案1、直接ALTER TABLE
这个方案只能说这仅仅是一种方案,在某些非实时在线或数据量较小时有较好的表现。

方案2、模拟数据库修改表结构的操作,在非数据库层实现整个过程。

  1. 实现业务中对于数据的读写分离
  2. 创建一个已经按需求修改好结构的新表
  3. 修改业务逻辑,将读操作指向旧表,将写操作指向新表。如果读旧表没有,再读新表,并将旧的数据写入到新表,当然这一步写入操作我们可以不用,我们可以在后台做一个定时任务将旧数据同步到新表。

这种方案有一个较大的缺点,需要业务逻辑层配合实现数据的迁移,对于业务逻辑有修改,并且如果有多台机器的话,需要一台一台的修改,较费时间,但是对于MySQL的两种主要存储引擎都适用。

方案3、facebook online schema change
facebook的OSC在整体流程上与方案2没有较大的区别,只是它在这里引入了触发器,从而不需要修改业务逻辑,在数据库层就实现了新数据的两个表的同步问题。其大概步骤如下:

  1. 按需求创建新表
  2. 针对原始表创建触发器
  3. 对于原始表的更新操作都会被触发器更新到新表中
  4. 把原始表中的数据复制到新表中
  5. 将新表替换旧表

fb的osc方案从数据库层解决了方案2的问题,但是它仅支持InnoDB存储引擎。

方案4、换一个思路,保留字段。
假设一切可以从头再来,我们也许可以加多一些冗余字段,各个类型都加一些,备用。只是,回不去了!

方案5、再换一个思路,增加扩展表。
我们不在原有的表的基础上修改了,以增加扩展表的方式,将新字段的数据写入到扩展表中,修改业务逻辑,这些字段从新表中读取。
志强同学说这是典型的维表结构设计。
暂时解决了问题,如果这些字段后续使用频率高的话,可能会有对后期维护或业务有一定的影响。

后记
基于现有的需求,只是需要记录新的字段,所以采用了扩展表的方案。

在线修改MySQL大表的表结构的更多相关文章

  1. 修改MySQL数据库中表和表中字段的编码方式的方法

    今天向MySQL数据库中的一张表添加含有中文的数据,可是老是出异常,检查程序并没有发现错误,无奈呀,后来重新检查这张表发现表的编码方式为latin1并且原想可以插入中文的字段的编码方式也是latin1 ...

  2. mysql大数据分表记录app用户的坐标数据

    最近提到一个需求.需要记录app用户在使用app中的移动轨迹,即坐标值.每分钟上传一次XY坐标,有点类似跑步软件的描线轨迹. 不考虑app如何获取,反正api只要接受到坐标数据 就记录下来保存到数据库 ...

  3. mysql大数据分表后查询

    当数据量猛增的时候,大家都会选择库表散列等等方式去优化数据读写速度,举例说明: 1亿条数据,分100张表 1.首先创建100张表 $i=0;while($i<=99){echo "$n ...

  4. linu下修改mysql数据库面

    修改密码:1.例如你的 root用户现在没有密码,你希望的密码修改为123456,那么命令是:mysqladmin -u root password 1234562.如果你的root现在有密码了(12 ...

  5. 修改mysql允许主机访问的权限

    开启mysql的远程访问权限 默认mysql的用户是没有远程访问的权限的,因此当程序跟数据库不在同一台服务器上时,我们需要开启mysql的远程访问权限. 主流的有两种方法,改表法和授权法. 相对而言, ...

  6. mysql在线修改表结构大数据表的风险与解决办法归纳

    整理这篇文章的缘由: 互联网应用会频繁加功能,修改需求.那么表结构也会经常修改,加字段,加索引.在线直接在生产环境的表中修改表结构,对用户使用网站是有影响. 以前我一直为这个问题头痛.当然那个时候不需 ...

  7. 数据库遇到的问题——mysql在线修改表结构大数据表的风险与解决办法归纳

    互联网应用会频繁加功能,修改需求.那么表结构也会经常修改,加字段,加索引.在线直接在生产环境的表中修改表结构,对用户使用网站是有影响. 以前我一直为这个问题头痛.当然那个时候不需要我来考虑,虽然我们没 ...

  8. MySQL使用pt-online-change-schema工具在线修改1.6亿级数据表结构

    摘  要:本文阐述了MySQL DDL 的问题现状.pt-online-schema-change的工作原理,并实际利用pt-online-schema-change工具在线修改生产环境下1.6亿级数 ...

  9. pt-online-schema-change工具使用教程(在线修改大表结构)

    percona-toolkit中pt-online-schema-change工具安装和使用 pt-online-schema-change介绍 使用场景:在线修改大表结构 在线数据库的维护中,总会涉 ...

随机推荐

  1. CF781A Andryusha and Colored Balloons

    题意: Andryusha goes through a park each day. The squares and paths between them look boring to Andryu ...

  2. spark性能调优--jvm调优(转)

    一.问题切入 调用spark 程序的时候,在获取数据库连接的时候总是报  内存溢出 错误 (在ideal上运行的时候设置jvm参数 -Xms512m -Xmx1024m -XX:PermSize=51 ...

  3. grep的几个参数

    -a 在二进制问就爱你中,以文本方式进行搜索 -c 计算找到搜索字符串的次数 -i 忽略大小写 -n 输出行号 -v 反向选择,即没有显示搜索字符串内容的那一行 grep -n '\.$'  file ...

  4. mysql出错排查

    1,例如:Can't connect to local MySQL server through socket '/tmp/mysql-5.5.37.sock' (2) Mysql链接出错,请配置/A ...

  5. 如何使用capedit分割数据包文件

    wireshark是一个网络数据包的分析工具,主要用来捕获网卡上的数据包并显示数据包的详细内容.在处理一些大的数据包文件时,如果直接用wireshark图形工具打开一些大文件的数据包会出现响应慢甚至没 ...

  6. PHP一句话后门过狗姿势万千之理论篇

    写在前面: 过狗相关的资料网上也是有很多,所以在我接下来的文章中,可能观点或者举例可能会与网上部分雷同,或者表述不够全面. 但是我只能说,我所传达给大家的信息,是我目前所掌握或者了解的,不能保证所有人 ...

  7. 聊天室(C++客户端+Pyhton服务器)3.群功能添加

    创建群 数据库 group_table(user, name) grpuser_table(grpname,user) 按下添加群按钮 // 创建群组void CUserDialog::OnBnCli ...

  8. android打包需要的图标

    ldpi:mdpi:hdpi:xhdpi:xxhdpi=3:4:6:8:12 大小: 32x32.png 48 72 96 144

  9. python基础一 day3 列表

    字符串是有序的,列表也是有序的,有索引值,可以切片 可以用切片来截取列表中的任何部分返回得到一个新列表. 列表方法: 1:增加 结果: 例子:    结果: int类型不可迭代      结果: 删: ...

  10. 28. TRIGGERS ,29. USER_PRIVILEGES,30. VIEWS

    28. TRIGGERS TRIGGERS表提供有关触发器的信息.要查看有关表的触发器的信息,您必须具有该表的TRIGGER权限. TRIGGERS表有以下列: TRIGGER_CATALOG :触发 ...