本帖最后由 jan_1985 于 2014-1-15 13:28 编辑

Mysql繁忙主从库在线修改表结构与添加索引问题

一直以来,生产情况下都有修改索引和修改字段的需求,但是对锁表引起的访问不便是会严重影响到在线业务的。

以前对于索引修改都是在其中一台从库中执行,然后将查询转到相应的服务器上,这种方式不便于服务器变更的情况,也不能满足表结构的修改的情形。

经过测试openark-kit这个套件下oak-online-alter-table这个工具可以实现在线修改表结构,我已经正式在主库使用了4次,目前来说运行良好。

应用环境: Mysql 5.1

工具版本:   openark-kit-180

工具的局限性:

The table must have at least one UNIQUE KEY (may expand one or more columns)

The altered table must share a UNIQUE KEY with the original one

No 'AFTER' triggers may be defined on the table

Foreign keys currently not supported

Table name must be at most 57 characters long

工具的说明页面 http://code.google.com/p/openarkkit/wiki/OakOnlineAlterTableSteps

安装工具:

wget http://openarkkit.googlecode.com/files/openark-kit-180.tar.gz

yum install MySQL-python -y

tar -zxvf openark-kit-180.tar.gz

cd openark-kit-180

python setup.py install

运行:

oak-online-alter-table -H localhost -u myuser --ask-pass -S /tmp/mysql.sock \

-d dbname --table=dbname.tablename -c 3000

--alter="add column signup_ip int(11) unsigned NOT NULL DEFAULT '' AFTER signup_time;"

工具的实现原理:

oak-online-alter-table 首先新建一个镜像表,将alter应用上去。再将数据从原表同步到镜像表,最后以镜像表替代原表。

一次从原表取出来到镜像表的记录数量 chunk值的设置依据整个表的记录数量和正常读写量不同而设置合适的配置。

当然,做为一个好的DBA,永远都要有两手准备。预案是少不了的。每次修改前我将备份表,并暂停一个备份从库的同步进程,直到执行完没有问题。

工具执行的SQL:

# 建立包含新结构的表

CREATE TABLE dbname.__oak_tablename LIKE dbname.tablename;

ALTER TABLE dbname.__oak_tablename add column signup_ip int(11) unsigned NOT NULL DEFAULT '' AFTER signup_time;

# 建立触发器,使新表与旧表在工具执行期间保持数据同步

CREATE DEFINER=`root`@`%` TRIGGER dbname.tablename_AD_oak AFTER DELETE ON dbname.tablename

FOR EACH ROW

DELETE FROM dbname.__oak_tablename WHERE (id) = (OLD.id);

CREATE DEFINER=`root`@`%` TRIGGER dbname.tablename_AU_oak AFTER UPDATE ON dbname.tablename

FOR EACH ROW

BEGIN

DELETE FROM dbname.__oak_tablename WHERE (id) = (OLD.id);

REPLACE INTO dbname.__oak_tablename (id, signup_time, login_disid, signup_siteman, login_time, signup_mid, signup_gid, signup_webads, signup_disid, login_gid, signupfrom) VALUES (NEW.id, NEW.signup_time, NEW.login_disid, NEW.isolduser, NEW.signup_siteman, NEW.login_time, NEW.signup_mid, NEW.signup_gid, NEW.signup_webads, NEW.signup_disid, NEW.member_id, NEW.login_gid, NEW.signupfrom);

END;

CREATE DEFINER=`root`@`%` TRIGGER dbname.tablename_AI_oak AFTER INSERT ON dbname.tablename

FOR EACH ROW

REPLACE INTO dbname.__oak_tablename (id, signup_time, login_disid, signup_siteman, login_time, signup_mid, signup_gid, signup_webads, signup_disid, login_gid, signupfrom) VALUES (NEW.id, NEW.signup_time, NEW.login_disid, NEW.isolduser, NEW.signup_siteman, NEW.login_time, NEW.signup_mid, NEW.signup_gid, NEW.signup_webads, NEW.signup_disid, NEW.member_id, NEW.login_gid, NEW.signupfrom);

#将数据从旧表插入到新表 chunk模式插入数据.并且随时保持同步。

SET @`unique_key_range_start_0`:=1/*!*/;

SET @`unique_key_range_end_0`:=3000/*!*/;

SET TIMESTAMP=1357542299/*!*/;

INSERT IGNORE INTO dbname.__oak_tablename (id, signup_time, login_disid, signup_siteman, login_time, signup_mid, signup_gid, signup_webads, signup_disid, login_gid, signupfrom)

(SELECT id, signup_time, login_disid, signup_siteman, login_time, signup_mid, signup_gid, signup_webads, signup_disid, login_gid, signupfrom FROM dbname.tablename

WHERE

(((id > @unique_key_range_start_0) OR ((id = @unique_key_range_start_0)))

AND

((id < @unique_key_range_end_0) OR ((id = @unique_key_range_end_0))))

)

/*!*/;

........... 略

#delete 那些在旧表中不存在(执行期间被删除的记录)的数据.

SET @`unique_key_range_start_0`:=1/*!*/;

SET @`unique_key_range_end_0`:=3000/*!*/;

DELETE FROM dbname.__oak_tablename

WHERE

(((id > @unique_key_range_start_0) OR ((id = @unique_key_range_start_0)))

AND

((id < @unique_key_range_end_0) OR ((id = @unique_key_range_end_0))))

AND (id) NOT IN

(SELECT id FROM dbname.tablename

WHERE

(((id > @unique_key_range_start_0) OR ((id = @unique_key_range_start_0)))

AND

((id < @unique_key_range_end_0) OR ((id = @unique_key_range_end_0))))

);

SET @`unique_key_range_start_0`:=3000/*!*/;

SET @`unique_key_range_end_0`:=6000/*!*/;

DELETE FROM dbname.__oak_tablename

WHERE

(((id > @unique_key_range_start_0))

AND

((id < @unique_key_range_end_0) OR ((id = @unique_key_range_end_0))))

AND (id) NOT IN

(SELECT id FROM dbname.tablename

WHERE

(((id > @unique_key_range_start_0))

AND

((id < @unique_key_range_end_0) OR ((id = @unique_key_range_end_0))))

);

........... 略

#替换旧表

RENAME TABLE

dbname.tablename TO dbname.__arc_tablename,

dbname.__oak_tablename TO dbname.tablename;

DROP TABLE IF EXISTS dbname.__arc_tablename;

mysql 主从 索引_Mysql繁忙主从库在线修改表结构与添加索引问题相关推荐

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

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

  2. osc mysql_MySQL在线修改表结构pt-osc

    MySQL在线修改表结构pt-osc 重所周知 MySQL的DDL操作操作是相比比较昂贵的.因为MySQL在修改表期间会阻塞任何读写操作. 基本上业务处于瘫痪.如果数据量较大可能需要好几个小时才能完成 ...

  3. mysql修改字段结构_MySQL修改表结构及其添加删除修改字段功能

    MySQL修改表结构添加删除修改字段 创建数据库CREATE DATABASE database_name 创建表CREATE TABLE `user` ( `id` int(11) unsigned ...

  4. mysql frm 恢复_mysql 从 frm 文件恢复 table 表结构的3种方法

    mysql 正常运行的时候,查看 table 的结构并不是困难的事. 但是有时 mysql 发生故障,这种方法便不再可行. 当遇到故障,通常使用新的 mysql 实例来恢复当前的数据. 建表是非常重要 ...

  5. pt-online-schema-change 在线修改表结构

    1. 参数 参数 默认值 说明 --host=xxx --user=xxx --password=xxx 连接实例信息,缩写-h xxx -u xxx -p xxx,密码可以使用参数--ask-pas ...

  6. gh ost mysql_mysql 在线修改表结构工具 gh-ost

    -allow-master-master 显式的允许在主主集群中运行-allow-on-master 允许直接运行在主机上,如果没有集群使用这个选项,推荐用在从机上-alter string(必须参数 ...

  7. percona-toolkit之pt-online-schema-change(在线更改表结构)

    传统方法修改表结构 类似alter table xx modify,在修改表结构时需要锁表,如果表很大,则操作时间会较长.目前,绝大多数业务要求24*7无间断服务,而此过程中,如果造成较长时间数据库无 ...

  8. mysql 修改表结构方案_MySQL中修改表结构时需要注意的一些地方

    MySql 在修改表结构的时候可能会中断产品的正常运行影响用户体验,甚至更坏的结果,丢失数据.不是所有的数据库管理员.程序员.系统管理员都非常了解Mysql能避免这种情况.DBA会经常碰到这种生产中断 ...

  9. mysql 复制表结构(包括索引等)、表内容

    =============================================== 2019/7/16_第1次修改                       ccb_warlock == ...

最新文章

  1. 清华本硕男,月入5W征婚引群嘲“普通却自信”,本人终于回应了!
  2. 浅谈java内存分配和回收策略
  3. JVM 参数及各部分含义(转)
  4. Gil Zilberfeld问答:敏捷产品的规划与管理
  5. DPM2012保护sharepoint场
  6. 前端学习(1428):ajax封装三
  7. Google 与 GitHub 结盟,为保护软件供应链而战!
  8. select学习小demo--实现网页换肤
  9. SQL 从入门到精通
  10. idea中 google-java-format 插件的使用
  11. 关于响应式布局,你必须要知道的
  12. gitlab 注册runner
  13. 计算机模拟计算 电脑配置,Material Studio材料模拟计算的工作站配置方案
  14. c语言中(char)的用法,c语言中char的用法是什么意思.docx
  15. 电路原理笔记整理_【盛世清北】2021清华大学827电路原理考研笔记-清华考研辅导班...
  16. 产品读书《B端产品经理必修课:从业务逻辑到产品构建全攻略》
  17. unity3D学习10 AR/MR技术
  18. rono在oracle的作用_Oracle中存储过程的作用和用法
  19. 零距离接触阿里云时序时空数据库TSDB
  20. android中edittext属性

热门文章

  1. 洛奇英雄转无法读取游戏服务器状态,洛奇英雄传无法连接服务器认证失败处理方法讲解...
  2. C语言文件的随机读写
  3. openstack中彻底删除计算节点的操作记录
  4. js 利用数组队列模拟多线程操作
  5. 深度了解视频直播CDN技术
  6. IOS自己主动布局中的浮动布局(6)----MyFloatLayout横空出世
  7. MySQL server has gone away报错原因分析
  8. mysql主从数据库不同步的2种解决方法(转)
  9. Difference between Win-builds vs MinGW-builds
  10. PHP和ajax请求_「jQuery+PHP」ajax请求以及接口PHP响应教程