timestamp 数据类型在 sql_mode 主从不一致引起的不同步问题解决

从节点同步出错。
无法同步,查看错误
Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 0 failed executing transaction ‘1c434876-08ed-11e9-b38c-7cd30aeb7e0a:518868’ at master log mysql-bin.000011, end_log_pos 518868. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.

select * from performance_schema.replication_applier_status_by_worker\G
*************************** 1. row ***************************
         CHANNEL_NAME: master1
            WORKER_ID: 1
            THREAD_ID: 28
        SERVICE_STATE: ON
LAST_SEEN_TRANSACTION: 1c434876-08ed-11e9-b38c-7cd30aeb7e0a:518868
    LAST_ERROR_NUMBER: 01677
    LAST_ERROR_MESSAGE: Worker 1 failed execution transaction '1c434876-08ed-11e9-b38c-7cd30aeb7e0a:518868' at master log maysql-bin.000163,
    end_log_pos 484600130;column 36 of table 'trade.account' cannot be converted from type 'int' to type 'temestamp'
 LAST_ERROR_TIMESTAMP: 2019-01-30 17:57:32

表结构定义为:

->   `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
->   `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

查看binlog 此表插入数据为:

   @39=1548833343 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */
   @40=1548833343 /* TIMESTAMP(0) meta=0 nullable=1 is_null=0 */

最后2字段 定义类型为timestamp.而因为此数据类型保存是为一个时间戳,

主节点的sql_mode

mysql> show variables like 'sql_mode';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_mode      |       |
+---------------+-------+
1 row in set (0.00 sec)

从节点的sql_mode

 mysql> show variables like 'sql_mode';
+---------------+--------------------------------------------+
| Variable_name | Value                                      |
+---------------+--------------------------------------------+
| sql_mode      | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |
+---------------+--------------------------------------------+
1 row in set (0.00 sec)

原因分析:

timestamp 数据类型是mysql 版本及sql_mode 影响的一个数据类型,相关内容这里不再细说。

时间戳数据存取

在MySQL上述三个大版本中,默认时间戳(Timestamp)类型的取值范围为’1970-01-01 00:00:01’ UTC 至’2038-01-19 03:14:07’ UTC,数据精确到秒级别,该取值范围包含约22亿个数值,因此在MySQL内部使用4个字节INT类型来存放时间戳数据:

1、在存储时间戳数据时,先将本地时区时间转换为UTC时区时间,再将UTC时区时间转换为INT格式的毫秒值(使用UNIX_TIMESTAMP函数),然后存放到数据库中。

2、在读取时间戳数据时,先将INT格式的毫秒值转换为UTC时区时间(使用FROM_UNIXTIME函数),然后再转换为本地时区时间,最后返回给客户端。

所以在binlog 日志中,可以看到sql 语句中。数据值是:1548833343 。而从节点 sql_mode=STRICT_TRANS_TABLES .
在严格模式下,类型转换出错了。
解决方法是把sql_mode 修改和主节点一致后, 重启从节点。可解决问题。

你可能感兴趣的:(MYSQL)