- A+
工具版本: pt-archiver 2.2.14
源表名: ord_order
目标表名: ord_order_1
表结构相同:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
root@test 15:09:54>show create table ord_order \G *************************** 1. row *************************** Table: ord_order Create Table: CREATE TABLE `ord_order` ( `order_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单ID', `amount` int(11) NOT NULL DEFAULT '0' COMMENT '订单金额', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `pay_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '支付类型', `serial_num` varchar(16) DEFAULT NULL COMMENT '余额交易流水号', PRIMARY KEY (`order_id`), KEY `idx$pay_type` (`pay_type`) ) ENGINE=InnoDB AUTO_INCREMENT=185 DEFAULT CHARSET=utf8mb4 COMMENT='订单表' 1 row in set (0.00 sec) |
使用如下语句始终会有一条 数据迁移不了
1 2 3 4 5 6 7 8 |
pt-archiver \ --source h=127.0.0.1,D=test,t=ord_order,u=root,p=oracle \ --dest h=127.0.0.1,D=test,t=ord_order_1,u=root,p=oracle \ --where '1=1' \ --no-check-charset \ --limit=10000 \ --progress=10000 \ --statistics |
迁移完后查看数据,还有一条数据存在
1 2 3 4 5 6 7 |
root@test 15:11:40>SELECT * FROM ord_order; +----------+--------+---------------------+----------+------------+ | order_id | amount | create_time | pay_type | serial_num | +----------+--------+---------------------+----------+------------+ | 184 | 0 | 2016-11-17 10:58:33 | 12 | NULL | +----------+--------+---------------------+----------+------------+ 1 row in set (0.00 sec) |
无奈之下只能打开 general_log 并且再次运行上面 pt-archiver 并查看日志
1 2 3 4 5 6 |
34 Query SELECT MAX(`order_id`) FROM `test`.`ord_order` 34 Query SELECT CONCAT(@@hostname, @@port) 35 Query SELECT CONCAT(@@hostname, @@port) 34 Query SELECT /*!40001 SQL_NO_CACHE */ `order_id`,`amount`,`create_time`,`pay_type`,`serial_num` FROM `test`.`ord_order` FORCE INDEX(`PRIMARY`) WHERE (order_id > 1) AND (`order_id` < '184') ORDER BY `order_id` LIMIT 10000 34 Quit 35 Quit |
可以看到主要的插叙语句,这里我们关注的SQL有
1 2 |
SELECT MAX(`order_id`) FROM `test`.`ord_order` SELECT /*!40001 SQL_NO_CACHE */ `order_id`,`amount`,`create_time`,`pay_type`,`serial_num` FROM `test`.`ord_order` FORCE INDEX(`PRIMARY`) WHERE (order_id > 1) AND (`order_id` < '184') ORDER BY `order_id` LIMIT 10000 |
发现第二条语句多加了一个条件 (order_id
< '184')
很明显这样的条件是查询不到 第 184 条记录的
这是我们只能是自行修改 pt-archiver 文件代码, 相关代码在5813行(不同版本的pt-archiver就不同)
原来:
1 |
5813 $first_sql .= " AND ($col < " . $q->quote_val($val) . ")"; |
修改后:
1 |
5813 $first_sql .= " AND ($col <= " . $q->quote_val($val) . ")"; |
修改后再次运行下面代码:
1 2 3 4 5 6 7 8 |
pt-archiver \ --source h=127.0.0.1,D=test,t=ord_order,u=root,p=oracle \ --dest h=127.0.0.1,D=test,t=ord_order_1,u=root,p=oracle \ --where '1=1' \ --no-check-charset \ --limit=10000 \ --progress=10000 \ --statistics |
并查看日志:
1 2 3 4 5 6 7 8 |
48 Query SELECT MAX(`order_id`) FROM `test`.`ord_order` 48 Query SELECT CONCAT(@@hostname, @@port) 49 Query SELECT CONCAT(@@hostname, @@port) 48 Query SELECT /*!40001 SQL_NO_CACHE */ `order_id`,`amount`,`create_time`,`pay_type`,`serial_num` FROM `test`.`ord_order` FORCE INDEX(`PRIMARY`) WHERE (1=1) AND (`order_id` <= '184') ORDER BY `order_id` LIMIT 10000 49 Query INSERT INTO `test`.`ord_order_1`(`order_id`,`amount`,`create_time`,`pay_type`,`serial_num`) VALUES ('184','0','2016-11-17 10:58:33','12',NULL) 49 Query commit 48 Query commit 48 Query SELECT /*!40001 SQL_NO_CACHE */ `order_id`,`amount`,`create_time`,`pay_type`,`serial_num` FROM `test`.`ord_order` FORCE INDEX(`PRIMARY`) WHERE (1=1) AND (`order_id` <= '184') AND ((`order_id` > '184')) ORDER BY `order_id` LIMIT 10000 |
由上面就可以很明显的看到 (order_id
<= '184') 是我们想要的答案了.
昵称: HH
QQ: 275258836
ttlsa群交流沟通(QQ群②: 6690706 QQ群③: 168085569 QQ群④: 415230207(新) 微信公众号: ttlsacom)

微信公众号
扫一扫关注运维生存时间公众号,获取最新技术文章~
04/02/2017 下午 5:07 沙发
这个问题我也碰到过,人家是有参数控制的
06/02/2017 下午 4:05 1层
@匿名 是哪个参数?
19/07/2017 下午 4:01 2层
@匿名 参数 –safe-auto-increment
28/04/2018 下午 3:04 1层
@匿名 参数 –nosafe-auto-increment ,希望对大家有用