InnoDB Online DDL续

在"InnoDB Online DDL一瞥"中说到了Online DDL的局限性, 主从复制环境中, 若主数据库上对一大表变更ALTER TABLE, 耗时较长, 该过程在从数据库上回放, 一般也要较长时间, 这期间主数据库上对该数据表的DML操作, 将不能及时体现在从数据库上, 这样从数据库的可用性就受到了影响.

原因可归结为, 一个大事物未能及时执行完毕, 引起了复制延时(其实MySQL 5.6, 5.7版本中ALTER TABLE还不具有原子性, 此处只是为了便于说明.). 而对于大事物的优化, 首先尝试分解成多个小事物, 本文主角pt-online-schema-change工具(以下简称pt-osc)正是利用了该思想, 其可有效的控制复制延时的问题.

pt-osc在不阻塞读写的情况下, 进行数据表变更. 其先创建一个符合要求的新数据表, 然后将原数据表中的数据, 以块为单位, 拷贝至新数据表中, 这期间原数据表上的DML操作, 都会通过其先前在原数据表上创建的触发器, 反映到新数据表上. 整个过程中, 该工具会通过多种方法将复制延时和主数据库负载控制在合理范围内.

看下实际中pt-osc使用的例子, 其日志输出也展示了它的工作过程.

[email protected]: ~$pt-online-schema-change --alter "ADD COLUMN org_id BIGINT UNSIGNED NOTNULL DEFAULT 0" --nocheck-replication-filters --recursion-method=processlist h=192.168.19.168,P=3316,u=zz,p=123456,D=test,t=test_zzzz --execute

Found 1 slaves:

db02 ->192.168.19.190:3316

Will check slave lagon:

db02 ->192.168.19.190:3316

Operation, tries,wait:

analyze_table,10, 1

copy_rows, 10,0.25

create_triggers, 10, 1

drop_triggers,10, 1

swap_tables,10, 1

update_foreign_keys, 10, 1

Altering`test`.`test_zzzz`...

Creating new table...

Created new tabletest._test_zzzz_new OK.

Waiting forever fornew table `test`.`_test_zzzz_new` to replicate to db02...

Altering new table...

Altered`test`.`_test_zzzz_new` OK.

2017-09-15T16:12:11Creating triggers...

2017-09-15T16:12:11Created triggers OK.

2017-09-15T16:12:11Copying approximately 4861821 rows...

Copying`test`.`test_zzzz`:   6% 07:42 remain

...

Copying`test`.`test_zzzz`:  89% 00:41 remain

Copying`test`.`test_zzzz`:  97% 00:08 remain

2017-09-15T16:18:42Copied rows OK.

2017-09-15T16:18:42Analyzing new table...

2017-09-15T16:18:42Swapping tables...

2017-09-15T16:18:42Swapped original and new tables OK.

2017-09-15T16:18:42Dropping old table...

2017-09-15T16:18:42Dropped old table `test`.`_test_zzzz_old` OK.

2017-09-15T16:18:42Dropping triggers...

2017-09-15T16:18:42Dropped triggers OK.

Successfully altered`test`.`test_zzzz`.

通过数据表变更过程中产生的general log, 了解下pt-osc背后运行细节, 从而也可印证上面说的主要工作原理.

Step1, 设置各种超时时间, 以防遇到锁等待等情况, 可尽快退出, 不影响其它操作.

57049 Query    SHOW VARIABLES LIKE ‘innodb\_lock_wait_timeout‘

57049 Query    SET SESSION innodb_lock_wait_timeout=1

57049 Query    SHOW VARIABLES LIKE ‘lock\_wait_timeout‘

57049 Query    SET SESSION lock_wait_timeout=60

57049 Query    SHOW VARIABLES LIKE ‘wait\_timeout‘

57049 Query    SET SESSION wait_timeout=10000

Step2, 创建一个符合变更要求的新表.

57049 Query  CREATE TABLE `test`.`_test_zzzz_new` (

`id` bigint(20)unsigned NOT NULL AUTO_INCREMENT,

...

PRIMARY KEY(`id`),

...

) ENGINE=InnoDBAUTO_INCREMENT=5342221 DEFAULT CHARSET=utf8mb4

57049 Query  ALTER TABLE `test`.`_test_zzzz_new` ADD COLUMN org_id BIGINT UNSIGNED NOT NULL DEFAULT 0

Step3, 创建触发器, 以便将原数据表上的DML操作, 体现到新数据表上.

57049 Query  CREATE TRIGGER `pt_osc_test_test_zzzz_del`AFTER DELETE ON `test`.`test_zzzz` FOR EACH ROW DELETE IGNORE FROM`test`.`_test_zzzz_new` WHERE `test`.`_test_zzzz_new`.`id` <=> OLD.`id`

57049 Query  CREATE TRIGGER `pt_osc_test_test_zzzz_upd`AFTER UPDATE ON `test`.`test_zzzz` FOR EACH ROW BEGIN DELETE IGNORE FROM `test`.`_test_zzzz_new`WHERE !(OLD.`id` <=> NEW.`id`) AND `test`.`_test_zzzz_new`.`id` <=>OLD.`id`;REPLACE INTO `test`.`_test_zzzz_new` (`id`, ...) VALUES (NEW.`id`,...);END

57049 Query  CREATE TRIGGER `pt_osc_test_test_zzzz_ins`AFTER INSERT ON `test`.`test_zzzz` FOR EACH ROW REPLACE INTO`test`.`_test_zzzz_new` (`id`, ...) VALUES (NEW.`id`, ...)

Step4, 分块拷贝数据, 这期间其会监控延时和负载情况.

57049 Query  INSERT LOW_PRIORITY IGNORE INTO`test`.`_test_zzzz_new` (`id`, ...) SELECT `id`, ... FROM `test`.`test_zzzz`FORCE INDEX(`PRIMARY`) WHERE ((`id` >= ‘147592‘)) AND ((`id` <=‘148591‘)) LOCK IN SHARE MODE /*pt-online-schema-change 4924 copy nibble*/

Step5, 收尾工作.

57049 Query  ANALYZE TABLE `test`.`_test_zzzz_new` /*pt-online-schema-change */

57049 Query  RENAME TABLE `test`.`test_zzzz` TO`test`.`_test_zzzz_old`, `test`.`_test_zzzz_new` TO `test`.`test_zzzz`

57049 Query  DROP TABLE IF EXISTS `test`.`_test_zzzz_old`

57049 Query  DROP TRIGGER IF EXISTS`test`.`pt_osc_test_test_zzzz_del`

57049 Query  DROP TRIGGER IF EXISTS `test`.`pt_osc_test_test_zzzz_upd`

57049 Query  DROP TRIGGER IF EXISTS`test`.`pt_osc_test_test_zzzz_ins`

在主从复制环境下, pt-osc借助选项--recursion-method=processlist获取从数据库的信息. 若某台服务器使用命令行, mysqlbinlog --host=192.168.19.168 --port=3316 --user=zz --password=123456 --read-from-remote-server --raw --stop-never --to-last-log --stop-never-slave-server-id=4444 --result-file=/backup/binlog/ bin.000044, 实时备份binlog, 那processlist方式就失效了, 此时要用dsn方式. 先创建一个数据表, 然后写入从库的IP信息, 如下所示:

([email protected])[test]> SHOW CREATE TABLE dsns\G

***************************1. row ***************************

Table: dsns

Create Table: CREATETABLE `dsns` (

`id` int(11)NOT NULL AUTO_INCREMENT,

`parent_id`int(11) DEFAULT NULL,

`dsn`varchar(255) NOT NULL,

PRIMARY KEY(`id`)

) ENGINE=InnoDBAUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4

1 row in set (0.00sec)

([email protected])[test]> SELECT * FROM dsns;

+----+-----------+---------------+

| id | parent_id | dsn          |

+----+-----------+---------------+

|  1 |     NULL | 192.168.19.190 |

+----+-----------+---------------+

1 row in set (0.05sec)

最后, pt-osc命令行如下所示:

pt-online-schema-change --alter "ADD COLUMN org_id BIGINT UNSIGNED NOT NULL DEFAULT 0" --nocheck-replication-filters --recursion-method=dsn=D=test,t=dsns h=192.168.19.168,P=3316,u=zz,p=123456,D=test,t=test_zzzz --execute

pt-osc的局限性

1. 数据表要有主键, 或唯一索引, 其实这也是任一InnoDB数据表的设计规范.

2. 有外键约束情况下, 使用pt-osc会比较复杂, 实际业务中一般是在应用程序中实现逻辑上的外键约束的.

3. MySQL 5.6版本中, 若要变更的数据表上已有触发器, pt-osc将不能使用, 该情况在5.7版本得了到改善.

pt-osc和OnlineDDL相比, 执行速度会慢, 要求磁盘空间会大, 但其保证了从库的可用性. 一般建议, 数据表数据量较小时, 可用Online DDL; 若数据量较大(大于500万或1000万), 这时要想到Online DDL会造成延时, 可考虑pt-osc.

时间: 2024-10-24 08:23:51

InnoDB Online DDL续的相关文章

MySQL InnoDB Online DDL学习

正文 MySQL Online DDL这个新特性是在MySQL5.6.7开始支持的,更早期版本的MySQL进行DDL对于DBA来说是非常痛苦的.现在主流版本都集中在5.6与5.7,为了更好的理解Online DDL的工作原理与机制,本文就对Online DDL的实现方式进行总结. 本文使用的MySQL版本为官方社区版 5.7.24. (root@localhost) [test] > select version(); +------------+ | version() | +--------

Online ddl 工具之pt-online-schema-change

MySQL ddl 的问题现状 在运维mysql数据库时,我们总会对数据表进行ddl 变更,修改添加字段或者索引,对于mysql 而已,ddl 显然是一个令所有MySQL dba 诟病的一个功能,因为在MySQL中在对表进行ddl时,会锁表,当表比较小比如小于1w上时,对前端影响较小,当时遇到千万级别的表 就会影响前端应用对表的写操作. 目前InnoDB引擎是通过以下步骤来进行DDL的: 1 按照原始表(original_table)的表结构和DDL语句,新建一个不可见的临时表(tmp_tabl

online ddl 工具之pt-online-schema-change封装

online ddl 工具之pt-online-schema-change封装 一.原理 目前InnoDB引擎是通过以下步骤来进行DDL的: 1 按照原始表(original_table)的表结构和DDL语句,新建一个不可见的临时表(tmp_table) 2 在原表上加write lock,阻塞所有更新操作(insert.delete.update等) 3 执行insert into tmp_table select * from original_table 4 rename original

mysql online ddl

目前InnoDB引擎是通过以下步骤来进行DDL的: 1 按照原始表(original_table)的表结构和DDL语句,新建一个不可见的临时表(tmp_table) 2 在原表上加write lock,阻塞所有更新操作(insert.delete.update等) 3 执行insert into tmp_table select * from original_table 4 rename original_table和tmp_table,最后drop original_table 5 释放 w

MySQL8.0新特性——支持原子DDL语句

MySQL 8.0开始支持原子数据定义语言(DDL)语句.此功能称为原子DDL.原子DDL语句将与DDL操作关联的数据字典更新,存储引擎操作和二进制日志写入组合到单个原子事务中.即使服务器在操作期间暂停,也会提交事务,并将适用的更改保留到数据字典,存储引擎和二进制日志,或者回滚事务. 通过在MySQL 8.0中引入MySQL数据字典,可以实现Atomic DDL.在早期的MySQL版本中,元数据存储在元数据文件,非事务性表和存储引擎特定的字典中,这需要中间提交.MySQL数据字典提供的集中式事务

[转载]github在线更改mysql表结构工具gh-ost

GitHub正式宣布以开源的方式发布gh-ost:GitHub的MySQL无触发器在线更改表定义工具! gh-ost是GitHub最近几个月开发出来的,目的是解决一个经常碰到的问题:不断变化的产品需求会不断要求更改MySQL表结构.gh-ost通过一种影响小.可控制.可审计.操作简单的方案来改变线上表结构. 在介绍gh-ost之前,我们先了解一下各种现有方案,以及为什么要自己开发一个新工具. 已有的在线修改表定义方案 目前,在线修改表定义的任务主要是通过这三种途径完成的: 在从库上修改表定义,修

MySQL使用pt-online-change-schema工具在线修改1.6亿级数据表结构

摘  要:本文阐述了MySQL DDL 的问题现状.pt-online-schema-change的工作原理,并实际利用pt-online-schema-change工具在线修改生产环境下1.6亿级数据表结构. 在一个软件生命周期中,我们都知道,前期的表结构设计是非常重要的,因为当表数据量一上来后再进行表结构修改危险性比较大,而且要操作的时间也比较长. 在笔者参与的项目中,就曾遇到这样一个问题,首先上去查看了一下该表的信息,已有约2亿的数据量,而且每分钟还要并发写入4万条记录,而由于这个表有一个

在线修改表结构mysql5.5版本和pt-online-schema-change

一.测试环境 系统:Centos 6.2 数据库:mysql Ver 14.14 Distrib 5.5.18, for Linux (x86_64) using readline 5.1 percona工具:percona-toolkit-2.2.12 测试数据库大小:tx_ljxz_71--16G.t_log_item--3G 二.在线修改表结构的过程 mysql在线修改表结构 1 按照原始表(original_table)的表结构和DDL语句,新建一个不可见的临时表(tmp_table)

迄今最安全的MySQL?细数5.7那些惊艳与鸡肋的新特性(上)【转载】

转自: DBAplus社群 http://www.toutiao.com/m5762164771/ 迄今最安全的MySQL?细数5.7那些惊艳与鸡肋的新特性(上) - 今日头条(TouTiao.com)http://toutiao.com/a6300616158581604609/?tt_from=mobile_qq&utm_campaign=client_share&app=news_article&utm_source=mobile_qq&iid=4592472790&