Closed zhanjianS closed 4 years ago
这不是8小时啊,6-17 09:25 + 8 -> 6-17 17:25,比创建时间还早。。。
不好意思 没描述清楚,mysql的数据是原始数据 是正确的数据,但是通过全量+增量的方式同步到tidb后,updated_at发生改变,变成当前时间的时间-8小时,按理说tidb的数据应该是myql端一致的
能截一个完整数据的图?带上主键唯一键。 可以看看 tidb 的 audit log,看看 sql 是啥样。或者你拉这边的 debug 分支,日志开 debug 级别,看看输出的 sql 长啥样。 这种情况似乎只有 replace 不带 updated at 这列才可能发生。但非空列程序不会自己去删,有配置删掉这列吗?
我这边也碰到这个问题了。。。 datetime 字段 DEFAULT CURRENT_TIMESTAMP 发现日期被刷新了
然后同样还有一个datetime字段 没default值 就完全OK
刚去确定了下 , 问题出在运用了default 值 , SQL 传入是default 这个看来要从代码层面解决?
刚去确定了下 , 问题出在运用了default 值 , SQL 传入是default 这个看来要从代码层面解决?
我用下面的表试了一下没复现。能不能给个复现的例子?
CREATE TABLE `ttt` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`v` int(11) NOT NULL,
`add_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录修改日期',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_v` (`v`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4;
代码里只有生成列和源端 binlog 没有这一列的情况才会填 default
代码里只有生成列和源端 binlog 没有这一列的情况才会填 default
我晚点给你把binlog截取下,我这边的架构是几个库多源复制到汇总库,然后通过gravity做归档库同步的测试。
代码里只有生成列和源端 binlog 没有这一列的情况才会填 default
-- 源端 binlog INSERT INTO t_ticket_bet_order (order_id, bet_time, update_at, plan_sales_start_time, tester) VALUES (1276304325068455954, '2020-06-26 08:00:38.0', '2020-06-26 08:00:38.0', '2020-06-26 07:59:55.0', 0), (1276304325085233243, '2020-06-26 08:00:38.0', '2020-06-26 08:00:38.0', '2020-06-26 07:59:55.0', 0);
-- 归档 binlog -- 归档表数据基本和tidb一致 只不过update_at时间有秒级别偏差 可能自己测试机器性能导致应用时间偏差
REPLACE INTO test
.t_ticket_bet_order
(order_id
, bet_time
, update_at
, deducted
, plan_sales_start_time
)
VALUES (1276304325068455954, '2020-06-26 08:00:38', DEFAULT, 0, '2020-06-26 07:59:55');
REPLACE INTO test
.t_ticket_bet_order
(order_id
, bet_time
, update_at
, deducted
, plan_sales_start_time
)
VALUES (1276304325085233243, '2020-06-26 08:00:38', DEFAULT, 0, '2020-06-26 07:59:55');
-- tidb 表数据
+---------------------+---------------------+---------------------+----------+-----------------------+ | order_id | bet_time | update_at | deducted | plan_sales_start_time | +---------------------+---------------------+---------------------+----------+-----------------------+ | 1276304325068455954 | 2020-06-26 08:00:38 | 2020-06-26 13:21:02 | 0 | 2020-06-26 07:59:55 | | 1276304325085233243 | 2020-06-26 08:00:38 | 2020-06-26 13:21:03 | 0 | 2020-06-26 07:59:55 | +---------------------+---------------------+---------------------+----------+-----------------------+ 2 rows in set (0.00 sec)
create table t_ticket_bet_order (
order_id
bigint(20) NOT NULL,
bet_time
datetime NOT NULL,
update_at
datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deducted
tinyint(1) NOT NULL DEFAULT '0' ,
plan_sales_start_time
datetime NOT NULL DEFAULT '0001-01-01 00:00:00' ,
PRIMARY KEY (order_id
));
我确实无法理解。。。 源端BINLOG里还是时间 再gravity传输过后就变成了default。。。3个架构表结构一致
@Ryan-Git 非常抱歉 之前没注意到信息,现在不在公司有点不好看tidb的日志和重新拉取 说下几点情况: 1、没有进行数据列的过滤, 2、数据是有主键的 另外有一个现象 tidb端的表结构 在update_at去掉ON UPDATE CURRENT_TIMESTAMP属性时,进行mysql->tidb 数据重新同步时,数据是正常的,时间不会发生改变
代码里只有生成列和源端 binlog 没有这一列的情况才会填 default
-- 源端 binlog INSERT INTO t_ticket_bet_order (order_id, bet_time, update_at, plan_sales_start_time, tester) VALUES (1276304325068455954, '2020-06-26 08:00:38.0', '2020-06-26 08:00:38.0', '2020-06-26 07:59:55.0', 0), (1276304325085233243, '2020-06-26 08:00:38.0', '2020-06-26 08:00:38.0', '2020-06-26 07:59:55.0', 0);
-- 归档 binlog -- 归档表数据基本和tidb一致 只不过update_at时间有秒级别偏差 可能自己测试机器性能导致应用时间偏差
REPLACE INTO
test
.t_ticket_bet_order
(order_id
,bet_time
,update_at
,deducted
,plan_sales_start_time
) VALUES (1276304325068455954, '2020-06-26 08:00:38', DEFAULT, 0, '2020-06-26 07:59:55'); REPLACE INTOtest
.t_ticket_bet_order
(order_id
,bet_time
,update_at
,deducted
,plan_sales_start_time
) VALUES (1276304325085233243, '2020-06-26 08:00:38', DEFAULT, 0, '2020-06-26 07:59:55');-- tidb 表数据
+---------------------+---------------------+---------------------+----------+-----------------------+ | order_id | bet_time | update_at | deducted | plan_sales_start_time | +---------------------+---------------------+---------------------+----------+-----------------------+ | 1276304325068455954 | 2020-06-26 08:00:38 | 2020-06-26 13:21:02 | 0 | 2020-06-26 07:59:55 | | 1276304325085233243 | 2020-06-26 08:00:38 | 2020-06-26 13:21:03 | 0 | 2020-06-26 07:59:55 | +---------------------+---------------------+---------------------+----------+-----------------------+ 2 rows in set (0.00 sec)
create table t_ticket_bet_order (
order_id
bigint(20) NOT NULL,bet_time
datetime NOT NULL,update_at
datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,deducted
tinyint(1) NOT NULL DEFAULT '0' ,plan_sales_start_time
datetime NOT NULL DEFAULT '0001-01-01 00:00:00' , PRIMARY KEY (order_id
));
这个我还是重现不了。。。能给个重新步骤?MySQL版本是啥? 有几个怀疑的地方,
tester
怎么处理的?@zhanjianS 也看下源端和目标端的 show columns from
问题是TiDB
某些版本对这种列的描述是DEFAULT_GENERATED
,跟MySQL
不一致,被gravity
当做MySQL
的生成列处理了。
影响的是目标端是TiDB
的带DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
的列,跟全量还是增量没关系。(当然增量情况下只要不延迟这个影响其实很小)
我修一下。
| update_time | datetime | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
代码里只有生成列和源端 binlog 没有这一列的情况才会填 default
-- 源端 binlog INSERT INTO t_ticket_bet_order (order_id, bet_time, update_at, plan_sales_start_time, tester) VALUES (1276304325068455954, '2020-06-26 08:00:38.0', '2020-06-26 08:00:38.0', '2020-06-26 07:59:55.0', 0), (1276304325085233243, '2020-06-26 08:00:38.0', '2020-06-26 08:00:38.0', '2020-06-26 07:59:55.0', 0); -- 归档 binlog -- 归档表数据基本和tidb一致 只不过update_at时间有秒级别偏差 可能自己测试机器性能导致应用时间偏差 REPLACE INTO
test
.t_ticket_bet_order
(order_id
,bet_time
,update_at
,deducted
,plan_sales_start_time
) VALUES (1276304325068455954, '2020-06-26 08:00:38', DEFAULT, 0, '2020-06-26 07:59:55'); REPLACE INTOtest
.t_ticket_bet_order
(order_id
,bet_time
,update_at
,deducted
,plan_sales_start_time
) VALUES (1276304325085233243, '2020-06-26 08:00:38', DEFAULT, 0, '2020-06-26 07:59:55'); -- tidb 表数据 +---------------------+---------------------+---------------------+----------+-----------------------+ | order_id | bet_time | update_at | deducted | plan_sales_start_time | +---------------------+---------------------+---------------------+----------+-----------------------+ | 1276304325068455954 | 2020-06-26 08:00:38 | 2020-06-26 13:21:02 | 0 | 2020-06-26 07:59:55 | | 1276304325085233243 | 2020-06-26 08:00:38 | 2020-06-26 13:21:03 | 0 | 2020-06-26 07:59:55 | +---------------------+---------------------+---------------------+----------+-----------------------+ 2 rows in set (0.00 sec) create table t_ticket_bet_order (order_id
bigint(20) NOT NULL,bet_time
datetime NOT NULL,update_at
datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,deducted
tinyint(1) NOT NULL DEFAULT '0' ,plan_sales_start_time
datetime NOT NULL DEFAULT '0001-01-01 00:00:00' , PRIMARY KEY (order_id
));这个我还是重现不了。。。能给个重新步骤?MySQL版本是啥? 有几个怀疑的地方,
- 看下源端 show columns from t_ticket_bet_order,源端这个
tester
怎么处理的?- 看下目标端 show columns from t_ticket_bet_order,结果里列名大小写和源端一样吗?
@zhanjianS 也看下源端和目标端的 show columns from
表结构完全一致
对了 我中间是 M => M => Tidb 并不是直接TIDB 中间M=>M也是有这个问题的
代码里只有生成列和源端 binlog 没有这一列的情况才会填 default
-- 源端 binlog INSERT INTO t_ticket_bet_order (order_id, bet_time, update_at, plan_sales_start_time, tester) VALUES (1276304325068455954, '2020-06-26 08:00:38.0', '2020-06-26 08:00:38.0', '2020-06-26 07:59:55.0', 0), (1276304325085233243, '2020-06-26 08:00:38.0', '2020-06-26 08:00:38.0', '2020-06-26 07:59:55.0', 0); -- 归档 binlog -- 归档表数据基本和tidb一致 只不过update_at时间有秒级别偏差 可能自己测试机器性能导致应用时间偏差 REPLACE INTO
test
.t_ticket_bet_order
(order_id
,bet_time
,update_at
,deducted
,plan_sales_start_time
) VALUES (1276304325068455954, '2020-06-26 08:00:38', DEFAULT, 0, '2020-06-26 07:59:55'); REPLACE INTOtest
.t_ticket_bet_order
(order_id
,bet_time
,update_at
,deducted
,plan_sales_start_time
) VALUES (1276304325085233243, '2020-06-26 08:00:38', DEFAULT, 0, '2020-06-26 07:59:55'); -- tidb 表数据 +---------------------+---------------------+---------------------+----------+-----------------------+ | order_id | bet_time | update_at | deducted | plan_sales_start_time | +---------------------+---------------------+---------------------+----------+-----------------------+ | 1276304325068455954 | 2020-06-26 08:00:38 | 2020-06-26 13:21:02 | 0 | 2020-06-26 07:59:55 | | 1276304325085233243 | 2020-06-26 08:00:38 | 2020-06-26 13:21:03 | 0 | 2020-06-26 07:59:55 | +---------------------+---------------------+---------------------+----------+-----------------------+ 2 rows in set (0.00 sec) create table t_ticket_bet_order (order_id
bigint(20) NOT NULL,bet_time
datetime NOT NULL,update_at
datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,deducted
tinyint(1) NOT NULL DEFAULT '0' ,plan_sales_start_time
datetime NOT NULL DEFAULT '0001-01-01 00:00:00' , PRIMARY KEY (order_id
));这个我还是重现不了。。。能给个重新步骤?MySQL版本是啥? 有几个怀疑的地方,
* 看下源端 show columns from t_ticket_bet_order,源端这个`tester`怎么处理的? * 看下目标端 show columns from t_ticket_bet_order,结果里列名大小写和源端一样吗?
@zhanjianS 也看下源端和目标端的 show columns from
源端跟目标端结构 表结构都是这个,这边的字段类型是timestamp
@smilenazy @zhanjianS 试一下新版本?
已经可以了
gravity mysql->tidb 全量+增量同步 时updated_at字段的数据会发生改变,变成当前时间 (测试的比当前时间小8小时 是因为这边k8s时区问题)
batch模式下也存在这个问题,用的最新的版本gravity0.9.71
表结构
mysql的数据
同步后tidb的数据
模式配置