DBA瑟瑟发抖!竟然是因为数据库服务器时钟跑快了一点点。
文中参考文档在github需点击阅读原文打开, 同时推荐2个学习环境:
1、懒人Docker镜像, 已打包200+插件:《最好的PostgreSQL学习镜像》
把系统时间调小对数据库有什么影响?
我们可能会遇到两种需要调整数据库服务器时钟的情况, 它们分别对数据库有什么影响? 你敢不敢拍胸脯调整? 调整时要不要重启数据库?
数据库服务器的时钟跑太慢, 比真实时间小, 要调大.
数据库服务器的时钟跑太快, 比真实时间大, 要调小.
1、数据库服务器的时钟跑太慢, 比真实时间小, 要调大. 这个情况闭着眼睛都可以调, 因为没有影响时间的自增性.
2、数据库服务器的时钟跑太快, 比真实时间大, 要调往回小. 如果遇到这种情况的话, 需要考虑对数据库和业务带来的影响.
调小数据库时间会有哪些影响?
影响1、当事务结束时, 会向WAL写一笔abort/commit的record, record里包含时间戳. 这个时间戳有啥用? 当执行时间点恢复(PITR)时, 根据这个时间戳来判断是否已恢复到目标位置. 原理参考: 《PostgreSQL 最佳实践 - 任意时间点恢复源码分析》
假设时间往回调2分钟, 当执行时间点恢复时, 可能不能恢复到你想要的这个新的变小时间点到2分钟后的这段,因为commit ts提前了。
record1 2024-04-07 10:01:00
record2 2024-04-07 10:02:00
record3 2024-04-07 10:03:00
调整后record4 2024-04-07 10:01:00
record5 2024-04-07 10:02:00
record6 2024-04-07 10:03:00
record7 2024-04-07 10:03:01
如果要恢复到2024-04-07 10:02:00, 那么只能恢复到record2. 不能恢复到record5.
这种情况有解, 只是比较麻烦, 我们可以通过采用指定xid进行恢复, 因为xid是始终自增的(epoch+xid).
影响2、采用数据库时间函数now,clock_timestamp等获取时间作为default值的字段. 在时间流逝追平之前的窗口内: 后插入/修改记录的时间戳 比 先插入/修改的时间戳小.
业务sql里采用数据库时间函数now,clock_timestamp等获得时间. 在时间流逝追平之前的窗口内: 后插入/修改记录的时间戳 比 先插入/修改的时间戳小.
这种情况, 业务的问题可能需和业务研发和分析师沟通, 从业务逻辑判断是否会造成影响。
影响3、系统表里有一些用来记录某些动作的刷新时间的字段, 例如autovacuum, autoanalyze时间戳, 统计信息reset时间.
没有什么影响, 顶多就是短暂的判断不准.
影响4、外部的awr工具获取统计信息的快照的时间. 这些时间也可能出现错乱.
这种情况, 如果采用自增ID作为快照标记,看起来没问题。
如何解决数据库服务器时间不准的问题?
在数据库服务器上, 可以使用ntp、chrony、openntpd等时间同步工具来同步公共授时时钟(或自建ntp server作为本地授时服务),以确保时钟的准确性.
可参考:
https://zhuanlan.zhihu.com/p/613929123
欢迎关注我的github (https://github.com/digoal/blog) , 学习数据库不迷路.
近期正在写公开课材料, 未来将通过视频号推出, 欢迎关注视频号:
文章中的参考文档请点击阅读原文获得.