本文讨论如何挽救崩溃了pt-online-schema-change通过利用pt-archiver和执行查询以确保准确的数据迁移。我将向您展示如何继续数据复制过程,以及如何安全地结束pt-online-schema-change通过手工操作等重命名表和下降触发命令。正常的流程从崩溃中恢复过来pt-online-schema-change是滴水原始表上的触发器和新表创建的脚本。你就会重启pt-online-schema-change。在这种情况下,这是不可能的。
最近一个客户需要添加主键列一个非常繁忙的表(大约2亿行)。桌子上只有一个独特的键(称为一列our_id下文)。客户担心奴隶滞后,要确保有很少或没有滞后。这个,你不能在网上添加主键作为DDL在MySQL和Percona Server 5.6,意味着使用明显的答案雷竞技下载官网pt-online-schema-change。
由于其环境的敏感性,他们只能买得起一个短窗口最初的元数据锁,,需要手动做下交换pt-online-schema-change通常自动。这就是no-drop-triggers和no-swap-tables进来。触发器理论上会无限期地保持新老表同步一次pt-online-schema-change就完成了。我们制定以下命令:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
pt
- - - - - -
在线
- - - - - -
模式
- - - - - -
改变
——执行
——alter-foreign-keys-method =汽车
——max-load线程运行= 30
——临界载荷Threads_running = 55
——check-slave-lag mysql-slave1、mysql-slave2 mysql-slave3
——max = 10−落后
——chunk-time = 0.5
——set-vars = lock_timeout = 1
——试=“drop_triggers create_triggers: 2: 2”
——no-drop-new-table
——no-drop-triggers
——no-swap-tables
——chunk-index“our_id”
——改变“添加newcol BIGINT(20)无符号NOT NULL AUTO_INCREMENT主键第一”
D
=
网站
,
t
=
largetable
——nocheck-plan
|
你可以看到的一些细节其他旗帜,为什么我们使用他们Percona工具包手册。雷竞技下载官网
一旦我们跑命令客户关注,作为他们的监视工具没有显示任何工作(这是通过设计,raybet雷竞技竞猜在线官网pt-online-schema-change不想伤害你的运行环境)。客户跑了strace - p验证工作。这不是一个很好的选择,因为它坠毁pt-online-schema-change。
在这一点上,我们知道应用程序(管理)不会允许我们采取新的元数据锁表创建触发器,当我们通过元数据锁定窗口。
那么,我们如何恢复?
首先,让我们从一张白纸开始。我们发出以下命令来创建一个新表,__largetable_new创建的表吗pt-online-schema-change:
|
1
2
3
|
创建
表
mynewlargetable
就像
__largetable_new
;
重命名
表
__largetable_new
来
__largetable_old
,
mynewlargetable
来
__largetable_new
;
下降
表
__largetable_old
;
|
现在原始表上的触发器,largetable更新新的空表,我们的新模式。
现在,让我们来解决这个问题的实际的数据已经在移动largetable来__largetable_new。这就是pt-archiver出现的原因。我们制定以下命令:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
pt
- - - - - -
存储服务器
——执行
——max-lag = 10
——源D =网站、t = largetable i = our_id
——t = __largetable_new桌子D =网站
——“1 = 1”
——no-check-charset
——没有删除
——no-check-columns
——txn-size = 500
——限制= 500
——忽略
——统计
|
我们使用pt-archiver慢慢将记录无损复制到新表基础上our_id和1 = 1(所有记录)。在这一点上,我们定期检查MySQL数据目录的一天ls - l比较表大小。
一旦表文件是接近相同的大小,我们跑计数表。我们注意到一些有趣的东西:新表具有成千上万的记录比原来的表。
这关心我们。我们想知道“黑客”是一个错误。在这一点上我们跑一些验证查询:
|
1
2
3
4
|
选择
最小值
(
our_id
)
从
__largetable_new
;
选择
马克斯
(
our_id
)
从
__largetable_new
;
选择
最小值
(
our_id
)
从
largetable
;
选择
马克斯
(
our_id
)
从
largetable
;
|
我们了解到,有老活表中不存在的记录。这意味着pt-archiver和删除触发器可能错过彼此(例如,pt-archiver已经在一个事务中但没有书面记录新表删除触发器之前已经解雇了)。
我们了更多的查询:
|
1
|
选择
数
(
*
)
从
largetable
l
在哪里
不
存在
(
选择
our_id
从
__largetable_new
n
在哪里
n
。
our_id
=
l
。
our_id
)
;
|
他们回来没有。
|
1
|
选择
数
(
*
)
从
__largetable_new
n
在哪里
不
存在
(
选择
our_id
从
largetable
l
在哪里
n
。
our_id
=
l
。
our_id
)
;
|
我们的结果显示,4000名新表中的记录。这表明我们最终与额外的记录从原始表中删除。我们跑其他查询基于他们的数据来验证。
为我们的应用程序中,这不是一个大问题,它可以轻松地使用一个简单的处理删除根据惟一索引(即查询。,if it doesn’t exist in the original table, delete it from the new one).
现在完成pt-online-schema-change行动。我们需要做的就是原子重命名或删除互换。这应该是尽快完成,以避免运行处于退化状态,所有写入新的旧的表复制。
|
1
|
重命名
表
largetable
来
__largetable_old
,
__largetable_new
来
largetable
;
|
然后将触发安全:
|
1
2
3
|
下降
触发
pt_osc_website_largetable_ins
;
下降
触发
pt_osc_website_largetable_upd
;
下降
触发
pt_osc_website_largetable_del
;
|
在这一点上是安全等待旧表清除缓冲池在下降之前,为了确保没有影响服务器(也许一个星期是安全的)。你可以检查information_schema更准确的阅读:
|
1
2
3
4
5
6
7
|
选择
数
(
*
)
从
INFORMATION_SCHEMA
。
INNODB_BUFFER_PAGE
在哪里
TABLE_NAME
=
“网站。__largetable_old”
;
+
- - - - - - - - - - - +
|
数
(
*
)
|
+
- - - - - - - - - - - +
|
279175年
|
+
- - - - - - - - - - - +
1
行
在
集
(
8.94
证券交易委员会
)
|
一旦这个→0时你可以问题:
|
1
|
下降
表
__largetable_old
;
|






@manjot辛格,我只是想知道pt-archiver副本中的数据可重复读隔离级别与删除触发器冲突的原因是什么?有可能提到隔离用于pt-online-schema-change以及pt-archiver吗?