当前位置: 首页 > 工具软件 > gh-ost > 使用案例 >

pt-osc/gh-ost原理

聂风史
2023-12-01

pt-osc

1、相关环境参数检查
show、select、set
2、创建新表进行变更

SHOW CREATE TABLE `sbtest`.`t1`
CREATE TABLE `sbtest`.`_t1_new`
ALTER TABLE `sbtest`.`_t1_new` 

3、创建触发器
CREATE TRIGGER `pt_osc_sbtest_t1_del` AFTER DELETE ON `subtest`.`t1` FOR EACH ROW DELETE IGNORE FROM `sbtest`.`_t1_new` WHERE `sbtest`.`_t1_new`.`id` <=> OLD.`id`
DELETE原表的时候,触发器根据其主键ID直接删除行记录

CREATE TRIGGER `pt_osc_sbtest_t1_upd` AFTER UPDATE ON `sbtest`.`t1` FOR EACH ROW BEGIN
DELETE IGNORE FROM `sbtest`.`_t1_new` WHERE !(OLD.`id` <=> NEW.`id`) AND `sbtest`.`_t1_new`.`id` <=> OLD.`id`;
REPLACE INTO `sbtest`.`_t1_new` (`id`) VALUES (NEW.`id`);END
UPDATE原表的时候,触发器根据其主键ID判断新旧ID是否一致,如果一致则删除,然后在REPLACE INTO新纪录到新表,如果数据修改的时候,还没有拷贝到新表,修改后再拷贝,虽然重复覆盖,但是数据也没有出错;如果是数据已经拷贝,原表发生修改,这时触发器同步修改数据,两种情况下都保证了数据的一致性;

CREATE TRIGGER `pt_osc_sbtest_t1_ins` AFTER INSERT ON `sbtest`.`t1` FOR EACH ROW REPLACE INTO `sbtest`.`_t1_new` (`id`) VALUES (NEW.`id`)
INSERT原表的时候,触发器根据其主键ID把新纪录INSERT到新表上;

4、pt-osc同时处理全量和增量数据,即一边拷表一边回放增量DML,按块拷贝数据到新表,拷贝过程对数据行持有S锁
INSERT LOW_PRIORITY IGNORE INTO `sbtest`.`_t1_new` (`id`) SELECT `id` FROM `sbtest`.`t1` LOCK IN SHARE MODE /*pt-online-schema-change 30257 copy table*/
5、ANALYZE TABLE `sbtest`.`_t1_new` /* pt-online-schema-change */
6、RENAME TABLE `sbtest`.`t1` TO `sbtest`.`_t1_old`, `sbtest`.`_t1_new` TO `sbtest`.`t1`
7、删除旧表、新表上的删除、更新、插入 触发器

gh-ost

1、相关环境参数检查
show、select、set

2、模拟slave,获取当前的位点信息,创建binlog streamer监听binlog

3、创建 日志记录表 xx_ghc 和影子表 xx_gho 并且执行alter语句将影子表 变更为目标表结构。如下日志记录了该过程,gh-ost会将核心步骤记录到 _b_ghc 中。

4、insert into xx_gho select * from xx 拷贝数据

5、增量应用binlog迁移数据
Insert:
gh-ost的原则是以binlog优先,所以无论任何顺序下,数据都是和binlog保持一致,如果rowcopy在后,会insert ignore,如果binlog apply在后会replace into掉。

update/delete:
对已经rowcopy过的数据,出现对原表的update/delete操作。这时候会全部通过binlog apply执行,对尚未迁移的数据,出现对原表的update/delete操作。这时候对新表的binlog apply会是空操作,具体数据由rowcopy迁移。

6、原始表和影子表cut-over 切换
 * session1建old表并且对原表、old表加锁
 * 对该表的新读写请求被阻塞
 * session2执行RENAME,被阻塞
 * 对该表的新增的读写请求继续被阻塞
 * session1检查是否有被阻塞的 RENAME
 * session1删除old和释放写锁
 * 会话B RENAME成功
 * 所有被阻塞的读写请求于新表

7、清理工具表ghc/_del
 类似资料: