mysql的在线表结构修改,因为低效和阻塞读写。一直被诟病。至于ALTER TABLE 的原理,参看我上一篇文章。MySQL在线修改大表结构。看完后,发现的问题是还是会锁的,且对于在线更新的这块也是不能很好的处理,所以只能从理论上来理解,应用到在线库还是有问题的。不能保证数据的最新。

今天看到percona推出的工具包中的online-schema-change 和facebook推出的一样。大概原理是一致的。如何安装使用详看官网文档。http://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html
注意文档上说的很清楚。需要注意的是对于两个参数的使用。--dry-run 和--execute 的区别使用。建立先使用--dry-run和--print查看更改的流程。OK后执行--execute 。
引用官网说明如下:
   --dry-run

Create and alter the new table, but do not create triggers, copy data, or replace the original table.

  --execute

Indicate that you have read the documentation and want to alter the table. You must specify this option to alter the table. If you do not, then the tool will only perform some safety checks and exit. This helps ensure that you have read the documentation and understand how to use this tool. If you have not read the documentation, then do not specify this option.

如下是自己执行--dry-run运行的过程。因为是在测试库中,没有新的记录出现。但是执行流程还是可以看出来。屏蔽了密码和host。

root@rb-11:/home/hzwuzhimin# pt-online-schema-change --user=root --password=*** --host='****'  --lock-wait-time=120   --alter="add column dd int(11) default 0"    D=wzm,t=tmp20121127_user_text_monitor_config,F=/home/hzwuzhimin/mysql/my.cnf,S=/home/hzwuzhimin/mysql/node/mysqld.sock,P=4333  --dry-run --print
Starting a dry run.  `wzm`.`tmp20121127_user_text_monitor_config` will not be altered.  Specify --execute instead of --dry-run to alter the table.
Creating new table...
CREATE TABLE `wzm`.`_tmp20121127_user_text_monitor_config_new` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `xml_content` longtext NOT NULL,
  `group_name` varchar(40) NOT NULL DEFAULT '',
  `user_account` varchar(40) NOT NULL DEFAULT '',
  `create_time` bigint(20) NOT NULL,
  `modify_time` bigint(20) NOT NULL,
  `modify_user_account` varchar(40) NOT NULL DEFAULT '',
  `v` bigint(20) NOT NULL DEFAULT '1',
  `aa` int(11) DEFAULT '0',
  `bb` int(11) DEFAULT '0',
  `cc` int(11) DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=244 DEFAULT CHARSET=gbk
Created new table wzm._tmp20121127_user_text_monitor_config_new OK.
Altering new table...
ALTER TABLE `wzm`.`_tmp20121127_user_text_monitor_config_new` add column dd int(11) default 0
Altered `wzm`.`_tmp20121127_user_text_monitor_config_new` OK.
Not creating triggers because this is a dry run.
CREATE TRIGGER `pt_osc_wzm_tmp20121127_user_text_monitor_config_del` AFTER DELETE ON `wzm`.`tmp20121127_user_text_monitor_config` FOR EACH ROW DELETE IGNORE FROM `wzm`.`_tmp20121127_user_text_monitor_config_new` WHERE `wzm`.`_tmp20121127_user_text_monitor_config_new`.`id` <=> OLD.`id`
CREATE TRIGGER `pt_osc_wzm_tmp20121127_user_text_monitor_config_upd` AFTER UPDATE ON `wzm`.`tmp20121127_user_text_monitor_config` FOR EACH ROW REPLACE INTO `wzm`.`_tmp20121127_user_text_monitor_config_new` (`id`, `xml_content`, `group_name`, `user_account`, `create_time`, `modify_time`, `modify_user_account`, `v`, `aa`, `bb`, `cc`) VALUES (NEW.`id`, NEW.`xml_content`, NEW.`group_name`, NEW.`user_account`, NEW.`create_time`, NEW.`modify_time`, NEW.`modify_user_account`, NEW.`v`, NEW.`aa`, NEW.`bb`, NEW.`cc`)
CREATE TRIGGER `pt_osc_wzm_tmp20121127_user_text_monitor_config_ins` AFTER INSERT ON `wzm`.`tmp20121127_user_text_monitor_config` FOR EACH ROW REPLACE INTO `wzm`.`_tmp20121127_user_text_monitor_config_new` (`id`, `xml_content`, `group_name`, `user_account`, `create_time`, `modify_time`, `modify_user_account`, `v`, `aa`, `bb`, `cc`) VALUES (NEW.`id`, NEW.`xml_content`, NEW.`group_name`, NEW.`user_account`, NEW.`create_time`, NEW.`modify_time`, NEW.`modify_user_account`, NEW.`v`, NEW.`aa`, NEW.`bb`, NEW.`cc`)
Not copying rows because this is a dry run.
 
INSERT LOW_PRIORITY IGNORE INTO `wzm`.`_tmp20121127_user_text_monitor_config_new` (`id`, `xml_content`, `group_name`, `user_account`, `create_time`, `modify_time`, `modify_user_account`, `v`, `aa`, `bb`, `cc`) SELECT `id`, `xml_content`, `group_name`, `user_account`, `create_time`, `modify_time`, `modify_user_account`, `v`, `aa`, `bb`, `cc` FROM `wzm`.`tmp20121127_user_text_monitor_config` LOCK IN SHARE MODE /*pt-online-schema-change 7498 copy table*/
Not swapping tables because this is a dry run.
Not dropping old table because this is a dry run.
Not dropping triggers because this is a dry run.
DROP TRIGGER IF EXISTS `wzm`.`pt_osc_wzm_tmp20121127_user_text_monitor_config_del`;
DROP TRIGGER IF EXISTS `wzm`.`pt_osc_wzm_tmp20121127_user_text_monitor_config_upd`;
DROP TRIGGER IF EXISTS `wzm`.`pt_osc_wzm_tmp20121127_user_text_monitor_config_ins`;
Dropping new table...
DROP TABLE IF EXISTS `wzm`.`_tmp20121127_user_text_monitor_config_new`;
Dropped new table OK.
Dry run complete.  `wzm`.`tmp20121127_user_text_monitor_config` was not altered.
 
执行--execute后的过程如下
root@rb-11:/home/hzwuzhimin# pt-online-schema-change --user=root --password=*** --host='*****'  --lock-wait-time=120   --alter="add column dd int(11) default 0"    D=wzm,t=tmp20121127_user_text_monitor_config,F=/home/hzwuzhimin/mysql/my.cnf,S=/home/hzwuzhimin/mysql/node/mysqld.sock,P=4333 --execute --print
Altering `wzm`.`tmp20121127_user_text_monitor_config`...
Creating new table...
CREATE TABLE `wzm`.`_tmp20121127_user_text_monitor_config_new` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `xml_content` longtext NOT NULL,
  `group_name` varchar(40) NOT NULL DEFAULT '',
  `user_account` varchar(40) NOT NULL DEFAULT '',
  `create_time` bigint(20) NOT NULL,
  `modify_time` bigint(20) NOT NULL,
  `modify_user_account` varchar(40) NOT NULL DEFAULT '',
  `v` bigint(20) NOT NULL DEFAULT '1',
  `aa` int(11) DEFAULT '0',
  `bb` int(11) DEFAULT '0',
  `cc` int(11) DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=244 DEFAULT CHARSET=gbk
Created new table wzm._tmp20121127_user_text_monitor_config_new OK.
Altering new table...
ALTER TABLE `wzm`.`_tmp20121127_user_text_monitor_config_new` add column dd int(11) default 0
Altered `wzm`.`_tmp20121127_user_text_monitor_config_new` OK.
Creating triggers...
CREATE TRIGGER `pt_osc_wzm_tmp20121127_user_text_monitor_config_del` AFTER DELETE ON `wzm`.`tmp20121127_user_text_monitor_config` FOR EACH ROW DELETE IGNORE FROM `wzm`.`_tmp20121127_user_text_monitor_config_new` WHERE `wzm`.`_tmp20121127_user_text_monitor_config_new`.`id` <=> OLD.`id`
CREATE TRIGGER `pt_osc_wzm_tmp20121127_user_text_monitor_config_upd` AFTER UPDATE ON `wzm`.`tmp20121127_user_text_monitor_config` FOR EACH ROW REPLACE INTO `wzm`.`_tmp20121127_user_text_monitor_config_new` (`id`, `xml_content`, `group_name`, `user_account`, `create_time`, `modify_time`, `modify_user_account`, `v`, `aa`, `bb`, `cc`) VALUES (NEW.`id`, NEW.`xml_content`, NEW.`group_name`, NEW.`user_account`, NEW.`create_time`, NEW.`modify_time`, NEW.`modify_user_account`, NEW.`v`, NEW.`aa`, NEW.`bb`, NEW.`cc`)
CREATE TRIGGER `pt_osc_wzm_tmp20121127_user_text_monitor_config_ins` AFTER INSERT ON `wzm`.`tmp20121127_user_text_monitor_config` FOR EACH ROW REPLACE INTO `wzm`.`_tmp20121127_user_text_monitor_config_new` (`id`, `xml_content`, `group_name`, `user_account`, `create_time`, `modify_time`, `modify_user_account`, `v`, `aa`, `bb`, `cc`) VALUES (NEW.`id`, NEW.`xml_content`, NEW.`group_name`, NEW.`user_account`, NEW.`create_time`, NEW.`modify_time`, NEW.`modify_user_account`, NEW.`v`, NEW.`aa`, NEW.`bb`, NEW.`cc`)
Created triggers OK.
Copying approximately 123 rows...
INSERT LOW_PRIORITY IGNORE INTO `wzm`.`_tmp20121127_user_text_monitor_config_new` (`id`, `xml_content`, `group_name`, `user_account`, `create_time`, `modify_time`, `modify_user_account`, `v`, `aa`, `bb`, `cc`) SELECT `id`, `xml_content`, `group_name`, `user_account`, `create_time`, `modify_time`, `modify_user_account`, `v`, `aa`, `bb`, `cc` FROM `wzm`.`tmp20121127_user_text_monitor_config` LOCK IN SHARE MODE /*pt-online-schema-change 8270 copy table*/
Copied rows OK.
Swapping tables...
RENAME TABLE `wzm`.`tmp20121127_user_text_monitor_config` TO `wzm`.`_tmp20121127_user_text_monitor_config_old`, `wzm`.`_tmp20121127_user_text_monitor_config_new` TO `wzm`.`tmp20121127_user_text_monitor_config`
Swapped original and new tables OK.
Dropping old table...
DROP TABLE IF EXISTS `wzm`.`_tmp20121127_user_text_monitor_config_old`
Dropped old table `wzm`.`_tmp20121127_user_text_monitor_config_old` OK.
Dropping triggers...
DROP TRIGGER IF EXISTS `wzm`.`pt_osc_wzm_tmp20121127_user_text_monitor_config_del`;
DROP TRIGGER IF EXISTS `wzm`.`pt_osc_wzm_tmp20121127_user_text_monitor_config_upd`;
DROP TRIGGER IF EXISTS `wzm`.`pt_osc_wzm_tmp20121127_user_text_monitor_config_ins`;
Dropped triggers OK.
Successfully altered `wzm`.`tmp20121127_user_text_monitor_config`.
 
总结:
实际上通过print出来的日志。我们就能很清楚的看到整个在线更新的流程。
1:创建跟需要修改的表结构一样的表结构。命名为旧表名_new;
2:   根据alter 条件修改新表结构为需要后的表结果;
3:创建触发器,对于修改表和新表的关联,对于INSERT,UPDATE,DELETE的操作。保证两表记录同步。(因为在线更新是不阻塞用户对修改表读写);
4:根据触发条件插入记录到新表中,直到复制完成;
5:重命名表,先将修改的表TAB 重名名成TAB_OLD,  TAB_NEW 重名成TAB ;
6:  然后删除TAB_OLD表。成功后,删除触发器。执行完成。
 

Percona 工具包 pt-online-schema-change 简介的更多相关文章

  1. schema change + ogg 变更手册

    Check OGG  until no data queuing in replication process:testRO:a)login  test5 –l oggmgrb)oggc)#ggsci ...

  2. Online Schema Change for MySQL

    It is great to be able to build small utilities on top of an excellent RDBMS. Thank you MySQL. This ...

  3. AppBoxFuture(四). 随需而变-Online Schema Change

      需求变更是信息化过程中的家常便饭,而在变更过程中如何尽可能小的影响在线业务是比较头疼的事情.举个车联网监控的例子:原终端设备上传车辆的经纬度数据,新的终端设备支持同时上传速度数据,而旧的车辆状态表 ...

  4. 安装percona工具包

    1.安装percona源 sudo yum install http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona- ...

  5. 数据库schema的简介

    [参考]自百度百科 数据库中的Schema,为数据库对象的集合,一个用户一般对应一个schema. 官方定义如下: A schema is a collection of database objec ...

  6. Oracle数据库Schema的简介

    百度文库中 Schema 的解释: 数据库中的Schema,为数据库对象的集合,一个用户一般对应一个schema. 官方定义如下: A schema is a collection of databa ...

  7. Online, Asynchronous Schema Change in F1

    F1: A Distributed SQL Database That Scales   http://disksing.com/understanding-f1-schema-change   ma ...

  8. Online Schema Upgrade in MySQL Galera Cluster using TOI Method

    http://severalnines.com/blog/online-schema-upgrade-mysql-galera-cluster-using-toi-method     As a fo ...

  9. Mysql 主从一致校验工具------Maatkit工具包

    Maatkit工具包 http://www.maatkit.org/ 简介 maatkit是一个开源的工具包,为mysql日常管理提供了帮助.目前,已被Percona公司收购并维护.其中: mk-ta ...

随机推荐

  1. ASP.NET常见内置对象(一)

    在web开发中,数据库都是通过HTTP协议来传输的.但HTTP是一个无状态协议,不会保留数据的状态和信息. 为了解决问题.各种开发语言都提供了状态管理功能. 状态管理是在同一页或不同页的多个请求发生时 ...

  2. Android中自动跳转到系统设置界面

    // 转到手机设置界面,用户设置GPS Intent intent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActi ...

  3. 项目分析(GS,NET,NGP关系)

    看了两天,这三者之间的关系好像是这样的,因为GS和net在同一台机器上,所以用共享内存通信,毕竟共享内存通信是最快的进程间通信的方式,而NGP是属于客户端的,Net是属于服务器的,他与Net进程是基于 ...

  4. Android实例-使用电话拨号器在移动设备上

    Android实例-使用电话拨号器在移动设备上 源文地址: http://docwiki.embarcadero.com/RADStudio/XE5/en/Mobile_Tutorial:_Using ...

  5. <pre>标签让<textarea>标签的内容原样输出

    当通过<textarea>插数据进数据的库,取出来后都变成一行变成,用这个<pre>标签能原样输入插入时的格式. 当时要对<pre>加一些CSS样式才行啦. 以下为 ...

  6. ubuntu设置开机启动脚本

    rc.local脚本 rc.local脚本是一个ubuntu开机后会自动执行的脚本,我们可以在该脚本内添加命令行指令.该脚本位于/etc/路径下,需要root权限才能修改. 该脚本具体格式如下: #! ...

  7. php获取本地IP

    function get_local_ip() { $preg = "/\A((([0-9]?[0-9])|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]))\.){3 ...

  8. 用jQuery的attr()设置option默认选中无效的解决 attr设置属性失效

    表单下拉选项使用selected设置,发现第一次默认选中成功,在页面不刷新的情况下,再次下拉,selected属性设置了,默认选中不生效 在手机端有些浏览器用jQuery的attr()方法设置sele ...

  9. 单独使用celery

    单独使用celery 参考 http://docs.celeryproject.org/en/latest/getting-started/index.html https://www.jianshu ...

  10. 【pip】【conda】

    1.指定python包安裝版本==  指定python包安裝源-i: pip2 -i https://pypi.tuna.tsinghua.edu.cn/simple 2.配置文件换源 vi ~/.p ...