-- 时区 8 小时偏差:修复后核对 + 历史数据排查(默认只读,改数据的语句都已注释) -- 背景:生产 DB 容器 1Panel-mariadb-ZOpD 系统时区是 UTC,应用容器/JVM 是 +08, -- 驱动参数 serverTimezone=Asia/Shanghai ⇒ 会话时区(UTC) 与驱动连接时区(+08) 不一致。 -- 修复:application-prod.yml 的 url 加 connectionTimeZone=%2B08:00&forceConnectionTimeZoneToSession=true, -- 连接建立时把会话时区设为 +08:00,与驱动一致。 -- 预期: -- * timestamp 列(cms_* / ai_chat_* / sys_* / gxmu_review_* / shop_user_oauth)存的是真实时刻(epoch), -- 修复后读出来自动回正:「知识库管理-分类管理」的创建时间会从 09:11 变成 17:11(真实时间)。 -- * datetime 列(gxmu_* 业务表)如果创建时间来自列默认值 CURRENT_TIMESTAMP,存的是 UTC 字面量, -- 修复后仍然早 8 小时,需要按表核对后回填。 -- * 代码里用 java.util.Date 显式写 timestamp 列的行(TeacherAccountService 教师建号/授权/冻结), -- 存的是 epoch 偏晚 8 小时,修复后会显示晚 8 小时,需要 -8h 回填。 -- 1) 会话时区自检(部署后执行,session 应为 +08:00 或 Asia/Shanghai) SELECT @@global.time_zone AS global_tz, @@session.time_zone AS session_tz, @@system_time_zone AS system_tz, NOW() AS db_now, UTC_TIMESTAMP() AS db_utc; -- 2) 分类管理核对(修复后 create_time 应比修复前 +8 小时) SELECT category_id, title, create_time, update_time FROM cms_article_category ORDER BY category_id; -- 3) 教师账号(TeacherAccountService 用 new Date() 显式写入)—— 修复后可能晚 8 小时 SELECT COUNT(*) AS teacher_user_cnt FROM sys_user WHERE user_code IS NOT NULL; SELECT user_id, user_code, username, real_name, create_time, update_time FROM sys_user WHERE user_code IS NOT NULL ORDER BY create_time DESC LIMIT 30; -- 4) gxmu_* datetime 表排查:重点看 HOUR(create_time) < 8 的行(北京时间凌晨不可能大量建数据) -- 逐表替换表名继续:gxmu_declare / gxmu_student / gxmu_teacher / gxmu_sync_record / -- tzb_project_list / tzb_talent_list / wxxzx_* / qmgc_form / sjqn / ... SELECT 'gxmu_declare' AS tbl, COUNT(*) AS total, MIN(create_time) AS min_ct, MAX(create_time) AS max_ct, SUM(HOUR(create_time) < 8) AS early_hour_rows FROM gxmu_declare; -- 5) 【谨慎】教师建号行 -8h 回填模板:先跑第 3 步确认数量与样本,备份后再执行 -- START TRANSACTION; -- UPDATE sys_user -- SET create_time = create_time - INTERVAL 8 HOUR, -- update_time = update_time - INTERVAL 8 HOUR -- WHERE user_code IS NOT NULL -- AND create_time >= '<教师账号同步功能上线时间>'; -- UPDATE sys_user_role ur JOIN sys_user u ON u.user_id = ur.user_id -- SET ur.create_time = ur.create_time - INTERVAL 8 HOUR, -- ur.update_time = ur.update_time - INTERVAL 8 HOUR -- WHERE u.user_code IS NOT NULL -- AND ur.create_time >= '<教师账号同步功能上线时间>'; -- COMMIT; -- 6) 【谨慎】gxmu_* datetime 列 +8h 回填模板:必须先按表确认这些行是列默认值写的 UTC 字面量。 -- 代码里 LocalDateTime.now() 写入的行在 JVM=+08 时已经是正确北京时间,回填会多 8 小时。 -- START TRANSACTION; -- UPDATE gxmu_xxx -- SET create_time = create_time + INTERVAL 8 HOUR, -- update_time = update_time + INTERVAL 8 HOUR -- WHERE create_time < '<切换时间点>'; -- COMMIT;