You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

从MySQL 5.7(Ubuntu 16.04)迁移至MySQL 8.0(Ubuntu 20.04)时导入备份文件出现无效日期时间值错误的解决咨询

解决MySQL 8.0导入夏令时无效timestamp数据的问题

我之前也碰到过一模一样的夏令时时间导入坑——MySQL 8.0在时间合法性校验上确实比5.7严格太多,尤其是这种夏令时跳变产生的「压根不存在的时间点」(比如欧洲CEST时区3月最后一个周日的2:00-3:00,时钟直接从2点跳到3点,这个区间的时间实际是不存在的),5.7会宽松允许存储,但8.0默认的严格模式直接就会抛出1292错误卡住导入。

下面是几个可行的解决办法,按操作复杂度从低到高排序:

方法一:临时调整SQL模式,跳过严格校验

这是最快速的临时解决方案,适合紧急导入场景:

  1. 登录新服务器的MySQL 8.0:
    mysql -u username -p
    
  2. 临时修改当前会话的SQL模式,关闭时间相关的严格校验:
    SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
    
    要是还是报错,也可以彻底关闭所有严格校验(注意:导入完成后一定要改回默认,避免后续数据写入出现不规范问题):
    SET sql_mode = '';
    
  3. 执行导入命令(假设你的备份压缩包是backup.sql.gz):
    zcat backup.sql.gz | mysql -u username -p your_database_name
    
  4. 导入完成后,记得把SQL模式改回MySQL 8.0的默认值:
    SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
    

方法二:从源端重新导出时处理时区,避免夏令时冲突

如果可以重新导出备份,推荐从MySQL 5.7端调整时区参数,让时间以UTC格式导出,这样导入到8.0时就不会有夏令时冲突:
执行mysqldump时加上--skip-tz-utc参数,强制以UTC时间写入备份文件:

mysqldump -u username -p --skip-tz-utc --default-character-set=utf8mb4 your_database_name | gzip > backup_utc.sql.gz

这个操作会让导出的timestamp数据脱离服务器本地时区,以UTC时间的形式存储,导入到新服务器时,MySQL会自动根据当前时区转换,完美避开夏令时的无效时间点。

方法三:临时修改表结构,用datetime中转导入

如果前两种方法都不适用,可以先把目标库的timestamp字段临时改成datetime,导入后再改回:

  1. 在MySQL 8.0中,修改涉及的表结构:
    ALTER TABLE your_table MODIFY COLUMN timestamp datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
    
  2. 执行导入命令——datetime类型不会校验时间是否符合夏令时规则,会直接存储原始时间字符串。
  3. 导入完成后,再把字段改回timestamp
    ALTER TABLE your_table MODIFY COLUMN timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
    
    小贴士:只要新旧服务器的时区一致,这个转换过程不会出现数据误差,MySQL会自动处理时区映射。

最后补充个小检查:虽然你说新旧服务器系统时区都是CEST,但可以用SELECT @@global.time_zone, @@session.time_zone;确认MySQL的全局/会话时区是否都是SYSTEM(跟随系统时区),避免隐性的时区差异问题。

内容的提问来源于stack exchange,提问作者merlin

火山引擎 最新活动