pt-online-schema-change 添加字段过程解析

pt-online-schema-change 添加字段过程解析

大家好,又见面了,我是全栈君。

对于大表的 DDL操作,我们一般使用 pt-online-schema-change  来进行。


具体的操作步骤如下:

1、创建一张新表_xxx_new ,对其做DDL操作

2、创建3个触发器(delete\update\insert),在复制数据开始之后,将对源数据表继续进行数据修改的操作记录下来,以便在数据复制结束后执行这些操作,保证数据不会丢失

3、复制数据,从源数据表复制数据到新表(分成多个chunk,小事务提交)

4、修改外键相关的子表,根据修改后的数据,修改外键关联的子表

5、将源数据表重命名为old表,将新表更改为源表名

6、删除原表

7、删除触发器


下面看一个例子,来亲自验证下这个过程。

如下是一条DDL测试语句:

ALTER TABLE tb_2 ADD COLUMN content text ;


对应的pt-osc写法如下:

pt-online-schema-change –user=root –password=123456 -h localhost –alter “ADD COLUMN content text” D=db1,t=tb_2–no-check-replication-filters –alter-foreign-keys-method=auto –recursion-method=none –print –charset=utf8 –execute


下面是我在使用pt-osc执行上述DDL时候,generallog里面记录的内容(部分不太重要的地方有删减..)

Connectroot@localhost on db1

            set autocommit=1

            SELECT @@SQL_MODE

            /*!40101 SET NAMES “utf8″*/

            SHOW VARIABLES LIKE ‘innodb\_lock_wait_timeout’

            SET SESSION innodb_lock_wait_timeout=1

            SHOW VARIABLES LIKE ‘lock\_wait_timeout’

            SET SESSION lock_wait_timeout=60

            SHOW VARIABLES LIKE ‘wait\_timeout’

            SET SESSION wait_timeout=10000

            SET @@SQL_QUOTE_SHOW_CREATE = 1/*!40101, @@SQL_MODE=’NO_AUTO_VALUE_ON_ZERO,NO_ENGINE_SUBSTITUTION’*/

            SELECT @@server_id /*!50038 , @@hostname*/

Connectroot@localhost on db1

            set autocommit=1

            SELECT @@SQL_MODE

            /*!40101 SET NAMES “utf8″*/

            SHOW VARIABLES LIKE ‘innodb\_lock_wait_timeout’

            SET SESSION innodb_lock_wait_timeout=1

            SHOW VARIABLES LIKE ‘lock\_wait_timeout’

            SET SESSION lock_wait_timeout=60

            SHOW VARIABLES LIKE ‘wait\_timeout’

            SET SESSION wait_timeout=10000

            SET @@SQL_QUOTE_SHOW_CREATE = 1/*!40101, @@SQL_MODE=’NO_AUTO_VALUE_ON_ZERO,NO_ENGINE_SUBSTITUTION’*/

            SELECT @@server_id /*!50038 , @@hostname*/

            SHOW VARIABLES LIKE ‘wsrep_on’

            SHOW VARIABLES LIKE ‘version%’

            SHOW ENGINES

            SHOW VARIABLES LIKE ‘innodb_version’

            SHOW GLOBAL STATUS LIKE ‘Threads_running’

            SHOW GLOBAL STATUS LIKE ‘Threads_running’

            SELECT CONCAT(@@hostname, @@port)

            SHOW VARIABLES

            SHOW TABLES FROM `db1` LIKE ‘tb_2’


### 查看原表是否已存在触发器

            SHOW TRIGGERS FROM `db1` LIKE ‘tb_2’


            /*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := ”, @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */

            USE `db1`

            SHOW CREATE TABLE `db1`.`tb_2`

            /*!40101 SET @@SQL_MODE := @OLD_SQL_MODE, @@SQL_QUOTE_SHOW_CREATE := @OLD_QUOTE */

            EXPLAIN SELECT * FROM `db1`.`tb_2` WHERE 1=1

            SELECT table_schema, table_name FROM information_schema.key_column_usage WHERE referenced_table_schema=’db1′ AND referenced_table_name=’tb_2′

            SHOW VARIABLES LIKE ‘wsrep_on’

            /*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := ”, @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */

            USE `db1`

            SHOW CREATE TABLE `db1`.`tb_2`

            /*!40101 SET @@SQL_MODE := @OLD_SQL_MODE, @@SQL_QUOTE_SHOW_CREATE := @OLD_QUOTE */


#### 创建新表,并对其做ALTER操作

            CREATE TABLE `db1`.`_tb_2_new` (

  `id` bigint(20) NOT NULL,

  `url` varchar(2048) NOT NULL DEFAULT ”,

  `appid` smallint(6) NOT NULL,

  `rand_code` int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘随机码’,

  `create_time` bigint(20) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

            ALTER TABLE `db1`.`_tb_2_new` ADD COLUMN content text


            /*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := ”, @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */

            USE `db1`

            SHOW CREATE TABLE `db1`.`_tb_2_new`

            /*!40101 SET @@SQL_MODE := @OLD_SQL_MODE, @@SQL_QUOTE_SHOW_CREATE := @OLD_QUOTE */


##### 创建3个触发器(delete、update、insert) (在原表上update,新临时表上是replace into整行数据,所以达到有则更新,无则插入。同时配合后面的 insert ignore,保证这条数据不会因为重复而失败)

            CREATE TRIGGER `pt_osc_db1_tb_2_del` AFTER DELETE ON `db1`.`tb_2` FOR EACH ROW DELETE IGNORE FROM `db1`.`_tb_2_new` WHERE `db1`.`_tb_2_new`.`id` <=> OLD.`id`

CREATE TRIGGER `pt_osc_db1_tb_2_upd` AFTER UPDATE ON `db1`.`tb_2` FOR EACH ROW REPLACE INTO `db1`.`_tb_2_new` (`id`, `url`, `appid`, `rand_code`, `create_time`) VALUES (NEW.`id`, NEW.`url`, NEW.`appid`, NEW.`rand_code`, NEW.`create_time`)

CREATE TRIGGER `pt_osc_db1_tb_2_ins` AFTER INSERT ON `db1`.`tb_2` FOR EACH ROW REPLACE INTO `db1`.`_tb_2_new` (`id`, `url`, `appid`, `rand_code`, `create_time`) VALUES (NEW.`id`, NEW.`url`, NEW.`appid`, NEW.`rand_code`, NEW.`create_time`)

            EXPLAIN SELECT * FROM `db1`.`tb_2` WHERE 1=1

            SELECT /*!40001 SQL_NO_CACHE */ `id` FROM `db1`.`tb_2` FORCE INDEX(`PRIMARY`) ORDER BY `id` LIMIT 1 /*first lower boundary*/

            SELECT /*!40001 SQL_NO_CACHE */ `id` FROM `db1`.`tb_2` FORCE INDEX (`PRIMARY`) WHERE `id` IS NOT NULL ORDER BY `id` LIMIT 1 /*key_len*/

            EXPLAIN SELECT /*!40001 SQL_NO_CACHE */ * FROM `db1`.`tb_2` FORCE INDEX (`PRIMARY`) WHERE `id` >= ‘20000000’ /*key_len*/


### 分块查询数据,减小后续操作的持锁范围

            EXPLAIN SELECT /*!40001 SQL_NO_CACHE */ `id` FROM `db1`.`tb_2` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= ‘20000000’)) ORDER BY `id` LIMIT 999, 2 /*next chunk boundary*/

            SELECT /*!40001 SQL_NO_CACHE */ `id` FROM `db1`.`tb_2` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= ‘20000000’)) ORDER BY `id` LIMIT 999, 2 /*next chunk boundary*/

            EXPLAIN SELECT `id`, `url`, `appid`, `rand_code`, `create_time` FROM `db1`.`tb_2` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= ‘20000000’)) AND ((`id` <= ‘20000999’)) LOCK IN SHARE MODE /*explain pt-online-schema-change 12296 copy nibble*/


### 开始灌数据操作

            INSERT LOW_PRIORITY IGNORE INTO `db1`.`_tb_2_new` (`id`, `url`, `appid`, `rand_code`, `create_time`) SELECT `id`, `url`, `appid`, `rand_code`, `create_time` FROM `db1`.`tb_2` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= ‘20000000’)) AND ((`id` <= ‘20000999’)) LOCK IN SHARE MODE /*pt-online-schema-change 12296 copy nibble*/  

            SHOW WARNINGS

            SHOW GLOBAL STATUS LIKE ‘Threads_running’


 。。。 对于操作期间有数据INSERT、UPDATE写入的话,这里还会出现REPLACE INTO 类型的SQL语句 。。。

#### 重命名新、老表名(这个操作期间是锁表的,时间很短暂)

            RENAME TABLE `db1`.`tb_2` TO `db1`.`_tb_2_old`, `db1`.`_tb_2_new` TO `db1`.`tb_2`

#### 删除原表

            DROP TABLE IF EXISTS `db1`.`_tb_2_old`

#### 删除触发器

            DROP TRIGGER IF EXISTS `db1`.`pt_osc_db1_tb_2_del`

            DROP TRIGGER IF EXISTS `db1`.`pt_osc_db1_tb_2_upd`

            DROP TRIGGER IF EXISTS `db1`.`pt_osc_db1_tb_2_ins`

            SHOW TABLES FROM `db1` LIKE ‘\_tb_2\_new’

Quit

Quit










本文转自 lirulei90 51CTO博客,原文链接:http://blog.51cto.com/lee90/1974950,如需转载请自行联系原作者
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107867.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • webpack es6转es5原理_webpack和vue cli区别

    webpack es6转es5原理_webpack和vue cli区别首先下载babel-loadernpminstall–save-devbabel-loader@7babel-corebabel-preset-es2015要在最外部输入指令不然会报错然后在webpack.config.js中写相关代码{test:/\.js$/,exclude:/(node_modules|bower_components)/,use:{

    2022年9月25日
    0
  • k8s基础知识_lable

    k8s基础知识_lable文章目录第三章 资源管理(续)15 命令式对象管理16 命令式对象配置17 声明式对象配置18 资源管理小结第四章 实战入门19 Namespace4.1.1 **查看**4.1.2 **创建**4.1.3 **删除**4.1.4 **使用配置文件(.yaml)进行管理**20 Pod4.2.1 创建并运行4.2.2 查看pod信息4.2.3 访问Pod4.2.4 删除指定Pod4.2.5 配置操作21 Lable4.3.1 命令方式4.3.2 配置方式22 Deployment4.4.1 命令操作4.4.

    2022年8月11日
    2
  • gdb 内存断点watch 的使用

    gdb 内存断点watch 的使用1.watch变量的类型a.整形变量:inti;watchi;b.指针类型:char*p;watchp,watch*p;它们是有区别的.watchp是查看*(&p),是p变量本身。watch(*p)是p所指的内存的内容c.watch一个数组或内存区间ch

    2022年10月24日
    0
  • SQL语句distinct的多个字段去重问题

    SQL语句distinct的多个字段去重问题经典例子selectdistinctname,idfromtable或者selectname,idfromtablegroupbyname像这样是错误的写法,distinct不起作用的曲线救国写法:selectname,idfromtablewhereidin(selectmin(id)fromtablegrou……

    2022年10月22日
    0
  • 精选推荐最新10个优秀源码下载网站超值收藏

    精选推荐最新10个优秀源码下载网站超值收藏以下十个网站是经本人精心收集,亲身体验过,才推荐给大家的。1.源码之家http://www.mycodes.net;;国内流量最大的源码下载站,下载点较多,速度一般,比较稳定,死链少2.果核网https://www.guohew.cn新兴的源码下载站,下载速度快.,源码更新速度较快、源码较全,还有模板、素材下载及一些不错的技术文章,是个值得收藏的站点!3.源码网http://www.yuanmawang.com新崛起的专业网站源码下载门户站,更新速度快较稳定,死链少,下载速度快….

    2022年7月20日
    36
  • Carson带你学Android:这是一份详细的 Retrofit使用教程(含实例讲解)[通俗易懂]

    前言在Andrroid开发中,网络请求十分常用而在Android网络请求库中,Retrofit是当下最热的一个网络请求库今天,我将献上一份非常详细Retrofitv2.0的使用教程,希望你们会喜欢。如果对Retrofitv2.0的源码感兴趣,可看文章:Android:手把手带你深入剖析Retrofit2.0源码目录![目录](http://upload-

    2022年4月13日
    64

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号