pt-archiver Bug不会迁移max(id)那条数据

HH MySQL Perl414,7471字数 3568阅读11分53秒阅读模式

工具版本: pt-archiver 2.2.14

源表名: ord_order文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

目标表名: ord_order_1文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

表结构相同:文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

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)

使用如下语句始终会有一条 数据迁移不了文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

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

迁移完后查看数据,还有一条数据存在文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

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 并查看日志文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

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有文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

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')文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

很明显这样的条件是查询不到 第 184 条记录的文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

这是我们只能是自行修改 pt-archiver 文件代码, 相关代码在5813行(不同版本的pt-archiver就不同)文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

原来:文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

5813       $first_sql .= " AND ($col < " . $q->quote_val($val) . ")";

修改后:文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

5813       $first_sql .= " AND ($col <= " . $q->quote_val($val) . ")";

修改后再次运行下面代码:文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

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

并查看日志:文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

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') 是我们想要的答案了.文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

昵称: HH文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

QQ: 275258836文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

ttlsa群交流沟通(QQ群②: 6690706 QQ群③: 168085569 QQ群④: 415230207(新) 微信公众号: ttlsacom)文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

感觉本文内容不错,读后有收获?文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

逛逛衣服店,鼓励作者写出更好文章。文章源自运维生存时间-https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/

weinxin
我的微信
微信公众号
扫一扫关注运维生存时间公众号,获取最新技术文章~
HH
  • 本文由 发表于 18/01/2017 00:03:47
  • 转载请务必保留本文链接:https://www.ttlsa.com/mysql/pt-archiver-bug-cannot-migration-max-id-record/
评论  4  访客  4
    • 匿名
      匿名 9

      这个问题我也碰到过,人家是有参数控制的

        • 匿名
          匿名 9

          @ 匿名 是哪个参数?

            • 请输入您的QQ号
              请输入您的QQ号 1

              @ 匿名 参数 –safe-auto-increment

            • 请输入您的QQ号
              请输入您的QQ号 9

              @ 匿名 参数 –nosafe-auto-increment ,希望对大家有用

          评论已关闭!