在线修改MySQL大表的表结构
由于某个临时需求,需要给在线MySQL的某个超过千万的表增加一个字段。此表在设计之时完全按照需求实现,并没有多余的保留字段。
我们知道在MySQL中如果要执行ALTER TABLE操作,MySQL会通过制作原来表的一个临时副本来工作。对于表结构的修改在副本上施行,然后将新表替换原始表,此时会产生锁表,用户可以从原始表读取数据,而用户的更新和写入操作都会被lock,待新表准备好后写入新表。
这对于在线的数据量较大的表来说是绝对无法容忍的,并且由于这种在线操作时间会很长,此时如果show processlist,会发现有若干的MySQL进程处于lock状态,当这种进程太多超过单台服务器允许的MySQL进程数,其它进程可能会被拒绝连接。
有哪些方案可以处理这个问题呢?
方案1、直接ALTER TABLE
这个方案只能说这仅仅是一种方案,在某些非实时在线或数据量较小时有较好的表现。
方案2、模拟数据库修改表结构的操作,在非数据库层实现整个过程。
- 实现业务中对于数据的读写分离
- 创建一个已经按需求修改好结构的新表
- 修改业务逻辑,将读操作指向旧表,将写操作指向新表。如果读旧表没有,再读新表,并将旧的数据写入到新表,当然这一步写入操作我们可以不用,我们可以在后台做一个定时任务将旧数据同步到新表。
这种方案有一个较大的缺点,需要业务逻辑层配合实现数据的迁移,对于业务逻辑有修改,并且如果有多台机器的话,需要一台一台的修改,较费时间,但是对于MySQL的两种主要存储引擎都适用。
方案3、facebook online schema change
facebook的OSC在整体流程上与方案2没有较大的区别,只是它在这里引入了触发器,从而不需要修改业务逻辑,在数据库层就实现了新数据的两个表的同步问题。其大概步骤如下:
- 按需求创建新表
- 针对原始表创建触发器
- 对于原始表的更新操作都会被触发器更新到新表中
- 把原始表中的数据复制到新表中
- 将新表替换旧表
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、模拟数据库修改表结构的操作,在非数据库层实现整个过程。
- 实现业务中对于数据的读写分离
- 创建一个已经按需求修改好结构的新表
- 修改业务逻辑,将读操作指向旧表,将写操作指向新表。如果读旧表没有,再读新表,并将旧的数据写入到新表,当然这一步写入操作我们可以不用,我们可以在后台做一个定时任务将旧数据同步到新表。
这种方案有一个较大的缺点,需要业务逻辑层配合实现数据的迁移,对于业务逻辑有修改,并且如果有多台机器的话,需要一台一台的修改,较费时间,但是对于MySQL的两种主要存储引擎都适用。
方案3、facebook online schema change
facebook的OSC在整体流程上与方案2没有较大的区别,只是它在这里引入了触发器,从而不需要修改业务逻辑,在数据库层就实现了新数据的两个表的同步问题。其大概步骤如下:
- 按需求创建新表
- 针对原始表创建触发器
- 对于原始表的更新操作都会被触发器更新到新表中
- 把原始表中的数据复制到新表中
- 将新表替换旧表
fb的osc方案从数据库层解决了方案2的问题,但是它仅支持InnoDB存储引擎。
方案4、换一个思路,保留字段。
假设一切可以从头再来,我们也许可以加多一些冗余字段,各个类型都加一些,备用。只是,回不去了!
方案5、再换一个思路,增加扩展表。
我们不在原有的表的基础上修改了,以增加扩展表的方式,将新字段的数据写入到扩展表中,修改业务逻辑,这些字段从新表中读取。
志强同学说这是典型的维表结构设计。
暂时解决了问题,如果这些字段后续使用频率高的话,可能会有对后期维护或业务有一定的影响。
后记
基于现有的需求,只是需要记录新的字段,所以采用了扩展表的方案。
在线修改MySQL大表的表结构的更多相关文章
- 修改MySQL数据库中表和表中字段的编码方式的方法
今天向MySQL数据库中的一张表添加含有中文的数据,可是老是出异常,检查程序并没有发现错误,无奈呀,后来重新检查这张表发现表的编码方式为latin1并且原想可以插入中文的字段的编码方式也是latin1 ...
- mysql大数据分表记录app用户的坐标数据
最近提到一个需求.需要记录app用户在使用app中的移动轨迹,即坐标值.每分钟上传一次XY坐标,有点类似跑步软件的描线轨迹. 不考虑app如何获取,反正api只要接受到坐标数据 就记录下来保存到数据库 ...
- mysql大数据分表后查询
当数据量猛增的时候,大家都会选择库表散列等等方式去优化数据读写速度,举例说明: 1亿条数据,分100张表 1.首先创建100张表 $i=0;while($i<=99){echo "$n ...
- linu下修改mysql数据库面
修改密码:1.例如你的 root用户现在没有密码,你希望的密码修改为123456,那么命令是:mysqladmin -u root password 1234562.如果你的root现在有密码了(12 ...
- 修改mysql允许主机访问的权限
开启mysql的远程访问权限 默认mysql的用户是没有远程访问的权限的,因此当程序跟数据库不在同一台服务器上时,我们需要开启mysql的远程访问权限. 主流的有两种方法,改表法和授权法. 相对而言, ...
- mysql在线修改表结构大数据表的风险与解决办法归纳
整理这篇文章的缘由: 互联网应用会频繁加功能,修改需求.那么表结构也会经常修改,加字段,加索引.在线直接在生产环境的表中修改表结构,对用户使用网站是有影响. 以前我一直为这个问题头痛.当然那个时候不需 ...
- 数据库遇到的问题——mysql在线修改表结构大数据表的风险与解决办法归纳
互联网应用会频繁加功能,修改需求.那么表结构也会经常修改,加字段,加索引.在线直接在生产环境的表中修改表结构,对用户使用网站是有影响. 以前我一直为这个问题头痛.当然那个时候不需要我来考虑,虽然我们没 ...
- MySQL使用pt-online-change-schema工具在线修改1.6亿级数据表结构
摘 要:本文阐述了MySQL DDL 的问题现状.pt-online-schema-change的工作原理,并实际利用pt-online-schema-change工具在线修改生产环境下1.6亿级数 ...
- pt-online-schema-change工具使用教程(在线修改大表结构)
percona-toolkit中pt-online-schema-change工具安装和使用 pt-online-schema-change介绍 使用场景:在线修改大表结构 在线数据库的维护中,总会涉 ...
随机推荐
- el-select,选择一行,取值行的对象.
<el-select v-model="set_invoice_form.InvoiceType" placeholder="请选择" :disabl ...
- xcode6的项目中虚拟键盘无法弹出
这是因为Xcode6中的模拟器键盘设置跟之前的版本不一样了.之前版本是模拟器的键盘和电脑的键盘都可以使用,但是Xcode6的模拟器键盘只能使用一种,即要么是模拟器键盘,要么是电脑键盘.快捷键切换键盘类 ...
- linux环境iptables配置
Linux iptables常用规则 设置一个自己用的表, 允许ping 允许ssh 允许 web 允许mysql 允许 ftp 允许dns查询 其他的拒绝.脚本如下 # Firewall confi ...
- android开发中设置字体
转自:http://segmentfault.com/q/1010000000494116 http://ryanhoo.github.io/blog/2014/05/05/android-bette ...
- 原创:mysql下载 实战 最强最全的无脑白痴版 给小白的爱
- C++友元函数和运算符重载
非成员友元函数.成员友元函数和友元类 1.友元的作用: (1)友元提供了不同类的成员函数之间.类的成员函数与一般函数之间进行了数据共享的机制: 2.友元的优点和缺点 优点:提高程序的运行效率: 缺点: ...
- 第1节 flume:4、离线项目处理的整个架构图;5、flume的基本介绍;
第1节 flume:4.离线项目处理的整个架构图 辅助系统工具:flume,azkaban,sqoop. 在一个完整的离线大数据处理系统中,除了hdfs+mapreduce+hive组成分析系统的核心 ...
- The following signatures couldn't be verified because the public key is not available: NO_PUBKEY XXXX
reference apt-key adv --recv-keys --keyserver keyserver.ubuntu.com XXXXXX apt-get update
- Swift中的init方法
摘要:Swift有着超级严格的初始化方法,不仅强化了designated初始化方法的地位,所有不加修饰的init方法都需要在方法中确保非Optional的实例变量被赋值初始化,而在子类中,也强制调用s ...
- 数组对象分类个数js
<script type="text/javascript"> $(function(){ var aaa = [ {"task1":"z ...