工作流程

  1. 1、检查更改表是否有主键或唯一索引,是否有触发器
  2. 2、检查修改表的表结构,创建一个临时表,在新表上执行ALTER TABLE语句
  3. 3、在源表上创建三个触发器分别对于INSERT UPDATE DELETE操作
  4. 4、从源表拷贝数据到临时表,在拷贝过程中,对源表的更新操作会写入到新建表中
  5. 5、将临时表和源表rename(需要元数据修改锁,需要短时间锁表)
  6. 6、删除源表和触发器,完成表结构的修改。

工具限制

  1. 1、源表必须有主键或唯一索引,如果没有工具将停止工作
  2. 2、如果线上的复制环境过滤器操作过于复杂,工具将无法工作
  3. 3、如果开启复制延迟检查,但主从延迟时,工具将暂停数据拷贝工作
  4. 4、如果开启主服务器负载检查,但主服务器负载较高时,工具将暂停操作
  5. 5、当表使用外键时,如果未使用--alter-foreign-keys-method参数,工具将无法执行
  6. 6、只支持Innodb存储引擎表,且要求服务器上有该表1倍以上的空闲空间。
    7、被修改表上不能有针对after delete | insert |update三个触发器,否则修改表操作失败

ALTER 语句限制

  1. 1、不需要包含alter table关键字,可以包含多个修改操作,使用逗号分开,如"drop clolumn c1, add column c2 int"
  2. 2、不支持rename语句来对表进行重命名操作
  3. 3、不支持对索引进行重命名操作
  4. 4、如果删除外键,需要对外键名加下划线,如删除外键fk_uid, 修改语句为"DROP FOREIGN KEY _fk_uid"
    5、重命名字段,不能使用drop add方式,会导致数据丢失,使用“change col1 col1_new type constraint",保持数据和约束一致。

数据一致性与加锁

  1. 如何保持数据一致性:
  2. 1、对于"数据拷贝"方式产生的数据可能已存在于新表,使用INSERT LOW_PRIORITY IGNORE INTO忽略已有数据
  3. 2、对于"触发器"方式产生的数据可能存储或不存在于新表,使用REPLACE INTO/DELETE IGNORE删除或替换数据
  4. 3、使用RENAME TABLE来同时修改原表和新表的表名
  5.  
  6. 由于pt-osc只对正在拷贝的数据加共享锁,且每次拷贝操作只操作小范围的数据,单次操作会很快完成并释放共享锁,因此造成“不影响对原表访问”的假象。

唯一索引

  1. 使用pt-osc创建唯一索引时,会造成数据丢失,需谨慎操作:
  2. 1、当表中要建立唯一索引的数据列上存在重复数据,则部分重复数据会丢失
  3. 2、如果创建过程中插入新数据,新数据与原数据库存在重复,则原数据丢失
  4.  
  5. 丢失原因:
  6. 由于INSERTUPDATE触发器使用REPLCAE INTO的方式更新新表数据,而新表中包含唯一索引,导致REPLACE INTO操作转换成DELETE+INSERT操作,将已存在于新表中的重复记录删除,再插入当前记录,最终导致数据丢失。

数据拷贝

  1. 在拷贝数据过程中,工具会把数据按照主键或唯一键进行拆分,限制每次拷贝数据的行数以保证拷贝进行不过多消耗服务器资源。为保证源表和目标表数据相同,采用LOCK IN SHARE MODE来获取要拷贝数据段的最新数据并对数据加共享锁组织其他回话修改数据,采用LOW_PRIORITY IGNORE来将数据插入到新表中, 关键字LOW_PRIORIT使得插入操作会等待其他访问该表的操作完成会再执行,关键字INGORE使得表中出现主键或唯一索引键重复时新数据被忽略而不会被插入。
  2.  
  3. 对表`testdb1`.`tb1001`进行修改时的数据拷贝脚本:
  4.  
  5. ## 先获取下一次拷贝数据的边界,强制索引可以有效避免执行计划出现问题
  6. SELECT /*!40001 SQL_NO_CACHE */ `id` FROM `testdb1`.`tb1001` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= '8394306')) ORDER BY `id` LIMIT 22256, 2 /*next chunk boundary*/
  7.  
  8. ## 通过拷贝数据的边界限制,防止单次拷贝过多数据而长时间阻塞其他回话
  9. INSERT LOW_PRIORITY IGNORE INTO `testdb1`.`_tb1001_new` (`id`, `c1`, `c6`) SELECT `id`, `c1`, `c6` FROM `testdb1`.`tb1001` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= '8394306')) AND ((`id` <= '8416562')) LOCK IN SHARE MODE /*pt-online-schema-change 14648 copy nibble*/

拷贝数据Chunk设置

  1. pt-osc的帮助文档中,关于chunk的参数有如下:
  2. --chunk-index=s Prefer this index for chunking tables
  3. --chunk-index-columns=i Use only this many left-most columns of a --chunk-index
  4. --chunk-size=z Number of rows to select for each chunk copied (default 1000)
  5. --chunk-size-limit=f Do not copy chunks this much larger than the desired chunk size (default 4.0)
  6. --chunk-time=f Adjust the chunk size dynamically so each data-copy query takes this long to execute (default 0.5)
  7.  
  8. chunk-sizechunk-time两者都未指定时,chunk-size默认值为1000chunk-time默认值为0.5S,第一次按照chunk-size来进行数据复制,然后根据第一次复制的时间动态调整chumk-size的大小,以适应服务器的性能变化,如上一次复制1000行消耗0.1S,则下次动态调整chumk-size5000
  9. 如果明确指定chumk-size的值或将chunk-time指定为0,则每次都按照chunk-size复制数据。

触发器

  1. pt-osc工具在源表上创建三个AFTER触发器分别对于INSERT/UPDATE/DELETE操作:
  2. 1DELETE触发器使用DELETE IGNORE来保证源表和新表的数据都被删除
  3. 2INSERT触发器使用REPLACE INTO来保证源表和新表的数据相同
  4. 3UPDATE触发器使用DELETE IGNORE删除新表上主键变化前的数据,再使用REPLACE INTO插入或更新新表数据。
  5.  
  6. 由于MySQL限制相同类型的触发器只能有一个,因此需要在运行前检查源表上是否有触发器,为保证删除和更新效率和方便和将源表数据进行分片处理,因此要求表上有主键或唯一索引,由于唯一索引不要求索引列必须为NULL,因此触发器中DELETE IGNORE操作使用<=>来判断
  7. UPDATE触发器中DELETE语句为:
  8. DELETE IGNORE FROM `db001`.`_tb003_new`
  9. WHERE !(OLD.`id` <=> NEW.`id`)
  10. AND `db001`.`_tb003_new`.`id` <=> OLD.`id`
  11. DELETE触发器中DELETE语句为:
  12. DELETE IGNORE FROM `db001`.`_tb003_new`
  13. WHERE `db001`.`_tb003_new`.`id` <=> OLD.`id`

主机性能影响

  1. 为避免过度影响主机性能,pt-osc工具通过以下几个方面来限制:
  2. 1、通过参数chunk-sizechunk-time控制每次拷贝数据大小
  3. 2、通过参数max-load来检查主机当前压力,每次chunk拷贝完成后,都会运行SHOW GLOBAL STATUS LIKE 'Threads_running' 命令检查当前正在运行的Threads数量,默认Threads_running=25,如果未指定最大值,则会取当前值的120%作为最大值,如果超过阀值则会暂停数据拷贝

从库复制延迟

  1. 对于复制延迟比较敏感的业务,可以通过下面参数来控制复制延迟:
  2. --max-log
  3. 默认为1s,每个chunks拷贝完成后,会查看check-slave-lag参数所指定的从库的延迟信息,如果超过max-log的阀值,则暂停复制数据,直到复制延迟小于max-log的阀值。检查复制延迟信息依赖于SHOW SLAVE STATUS语句中返回的Seconds_Behind_Master列的值。
  4.  
  5. --check-interval
  6. 当出现复制延迟暂停复制数据后,按照check-interval指定的时间进行周期检查复制延迟,直到延迟时间低于max-log阀值,然后恢复数据拷贝
  7.  
  8. --check-slave-lag
  9. 需要检查复制延迟的从库IP
  10. 如果指定check-slave-lag参数,且从库无法正常连接或从库IO线程和SQL线程停止,会认为主从存在延迟,导致复制数据操作一直暂停。
  11. 如果未指定check-slave-lag参数,默认还是会检查从库的延迟,但复制延迟不会导致数据复制暂停。

修改主键

通常情况下,我们会采用自增列来作为主键,优点是主键列长度小且业务无关,假设当前表使用业务主键,需要将业务主键修改为自增主键,并将业务主键修改为唯一索引,如果手工操作,则需要进行如下操作:
1. 删除现有主键
2. 添加新的自增主键
3. 增加唯一索引

而如果使用pt-osc工具,会创建一个新表来承载新的结构和数据,如果新表中只有新自增主键,那么在处理触发器捕获到的变更数据时,无法按照旧表的主键来进行处理因此造成对新表的全表扫描,导致严重的性能问题。因此应该在操作时,同时变更主键并创建唯一索引,则alter命令为:

  1. --alter "drop primary key,add column id int auto_increment primary key first,add unique key uk_c1(c1)"

命令模板

  1. ## --recursion-method="processlist" 表示使用SHOW PROCESSLIST来获取从库信息
  2. ## --check-salve-lag='192.168.1.102' 表示要检查复制延迟的从库信息
  3. ## --check-interval=10s 表示每10秒检查一次复制从库延迟情况,默认标量为秒
  4. ## --max-lag=60s 表示最大从库延迟,当超过该值后,暂停数据拷贝
  5. ## --nocheck-replication-filters 表示不检查从库复制过滤条件
  6. ## --database=db001 t=tb003 表示需要变更的库和表
  7. ## --alter="drop column c4" 表示需要执行的变更操作
  8. ## --critical-load="Threads_running=512" 表示超过该阈值后放弃拷贝数据
  9. ## --max-load="Threads_running=256" 表示超过该阈值后暂停拷贝数据
  10. ## --progress=time,30 表示每30秒输出拷贝数据进度
  11. ## --execute表示执行
  12. ## --dry-run表示只进行模拟测试
  13.  
  14. pt-online-schema-change \
  15. --host="192.168.1.101" \
  16. --port=3306 \
  17. --user="root" \
  18. --password="root_psw" \
  19. --charset="utf8" \
  20. --recursion-method="processlist" \
  21. --nocheck-replication-filters \
  22. --check-slave-lag="192.168.1.102" \
  23. --check-interval=10s \
  24. --critical-load="Threads_running=512" \
  25. --max-load="Threads_running=256" \
  26. --max-lag=60s \
  27. D="db001",t="tb003" \
  28. --alter="add column c5 int" \
  29. --progress=time,30 \
  30. --execute

上面命令输出结果:

  1. Found 1 slaves:
  2. zabbixserver -> 192.168.1.1023306
  3. Will check slave lag on:
  4. zabbixserver -> 192.168.1.1023306
  5. Operation, tries, wait:
  6. analyze_table, 10, 1
  7. copy_rows, 10, 0.25
  8. create_triggers, 10, 1
  9. drop_triggers, 10, 1
  10. swap_tables, 10, 1
  11. update_foreign_keys, 10, 1
  12. Altering `db001`.`tb003`...
  13. Creating new table...
  14. Created new table db001._tb003_new OK.
  15. Altering new table...
  16. Altered `db001`.`_tb003_new` OK.
  17. 2019-07-10T16:45:46 Creating triggers...
  18. 2019-07-10T16:45:46 Created triggers OK.
  19. 2019-07-10T16:45:46 Copying approximately 24257443 rows...
  20. Copying `db001`.`tb003`: 6% 06:44 remain
  21. Copying `db001`.`tb003`: 14% 05:40 remain
  22. Copying `db001`.`tb003`: 23% 05:00 remain
  23. Copying `db001`.`tb003`: 30% 04:31 remain
  24. Copying `db001`.`tb003`: 38% 04:01 remain
  25. Copying `db001`.`tb003`: 46% 03:31 remain
  26. Copying `db001`.`tb003`: 53% 03:00 remain
  27. Copying `db001`.`tb003`: 60% 02:33 remain
  28. Copying `db001`.`tb003`: 68% 02:03 remain
  29. Copying `db001`.`tb003`: 76% 01:31 remain
  30. Copying `db001`.`tb003`: 84% 01:01 remain
  31. Copying `db001`.`tb003`: 91% 00:34 remain
  32. Copying `db001`.`tb003`: 99% 00:03 remain
  33. 2019-07-10T16:52:21 Copied rows OK.
  34. 2019-07-10T16:52:21 Analyzing new table...
  35. 2019-07-10T16:52:21 Swapping tables...
  36. 2019-07-10T16:52:22 Swapped original and new tables OK.
  37. 2019-07-10T16:52:22 Dropping old table...
  38. 2019-07-10T16:52:22 Dropped old table `db001`.`_tb003_old` OK.
  39. 2019-07-10T16:52:22 Dropping triggers...
  40. 2019-07-10T16:52:23 Dropped triggers OK.
  41. Successfully altered `db001`.`tb003`.

MySQL Percona Toolkit--pt-osc学习的更多相关文章

  1. Percona Toolkit之pt-table-checksum学习

    pt-table-checksum用来检测主从数据库上的数据一致性,其原理是通过在主库上运行一系列的MySQL函数计算每个表的散列值,并利用主从关系将相同的操作在从服务器上重放(基于statement ...

  2. Percona Toolkit mysql辅助利器

    1 PT介绍 Percona Toolkit简称pt工具—PT-Tools,是Percona公司开发用于管理MySQL的工具,功能包括检查主从复制的数据一致性.检查重复索引.定位IO占用高的表文件.在 ...

  3. RDS for MySQL 如何使用 Percona Toolkit

    Percona Toolkit 包含多种用于 MySQL 数据库管理的工具. 下面介绍常用的 pt-online-schema-change  和  pt-archiver 搭配 RDS MySQL ...

  4. Percona Toolkit工具连接MySQL 8报错的解决方案

    使用Percona Toolkit的工具连接MySQL 8.x数据库时,会遇到类似"failed: Plugin caching_sha2_password could not be loa ...

  5. Percona Toolkit工具使用

    Percona Toolkit简称pt工具-PT-Tools,是Percona公司开发用于管理MySQL的工具,功能包括检查主从复制的数据一致性.检查重复索引.定位IO占用高的表文件.在线DDL等 下 ...

  6. 使用MySQL Migration Toolkit快速将Oracle数据导入MySQL[转]

    使用MySQL Migration Toolkit快速将Oracle数据导入MySQL上来先说点废话本人最近在学习一些数据库方面的知识,之前接触过Oracle和MySQL,最近又很流行MongoDB非 ...

  7. Centos 安装Percona Toolkit工具集

    1.下载 下载地址:   https://www.percona.com/downloads/percona-toolkit/LATEST/ [root@bogon ~]# wget https:// ...

  8. Percona Toolkit工具集介绍

    部署mysql工具是一个非常重要的部分,所以工具的可靠性和很好的设计非常重要.percona toolkit是一个有30多个mysql工具的工具箱.兼容mysql,percona server,mar ...

  9. Want to archive tables? Use Percona Toolkit’s pt-archiver--转载

    原文地址:https://www.percona.com/blog/2013/08/12/want-to-archive-tables-use-pt-archiver/ Percona Toolkit ...

  10. MySQL Percona Toolkit--pt-osc重点参数

    修改命令参数alter .不需要包含alter table关键字,可以包含多个修改操作,使用逗号分开,如"drop clolumn c1, add column c2 int" . ...

随机推荐

  1. Could not create connection to database server. Attempted reconnect 3 times. Giving up.

    报出这个错误,可能原因: 1.检查MySQL数据库服务是否正常(包含检查服务名和密码),如果不正常,修复至正常为止: 2.maven工程中导入的mysql的jar版本和你的MySQL版本不相符,必须相 ...

  2. CobaltStrike3.14破解

    原文发布在:https://bithack.io/forum/310 8月6日已更新 之前发的是5月2号破解的,并且官方作者的exit暗桩没有去掉.看到很多人用此版本遇到问题,抽空修复了下bug.此版 ...

  3. wms证书异常问题

    目前我司已定位到两个原因,详细如下, 1.  快速生成的证书存在问题,导致APACHE和NGINX显示的时间都是4号凌晨 2.  贵司在配置完成162和163两台应用的APACHE证书,以及其中10. ...

  4. C# 语音技术

    1.使用DotNetSpeech.dll. /// <summary> /// 朗读/// </summary>/// <param name="text&qu ...

  5. Docker-Compose简介及常用命令

    1.Docker-Compose简介 Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排.Docker-Compose将所管理的容器分为三层,分别是 ...

  6. start & stop kafka cluster shell script

    kafka_start_cluster.sh #!/bin/bash brokers="kafka-server-1 kafka-server-2 kafka-server-3" ...

  7. Mac下进入MySQL命令行

    /usr/local/MySQL/bin/mysql -u root -p 其中,root为数据库用户名

  8. myeclipse An internal error occurred during: "Initialize metrics".

    重新安装的myeclipse,在打开的时候弹出:    An internal error occurred during: "Initialize metrics". com/g ...

  9. (IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)

    参考博客: https://www.cnblogs.com/xiao987334176/p/9056511.html 内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yi ...

  10. Python学习之路:函数传递可变参数与不可变参数

    函数传参的方法: 太基础了,8说了 直接上重点 一.可变参数的传递 可变参数有:列表.集合.字典 直接上代码: a = [1, 2] def fun(a): print('传入函数时a的值为:', a ...