PostgreSQL码农集散地

DBA瑟瑟发抖!竟然是因为数据库服务器时钟跑快了一点点。

文中参考文档在github需点击阅读原文打开, 同时推荐2个学习环境: 

1、懒人Docker镜像, 已打包200+插件:《最好的PostgreSQL学习镜像》

2、有web浏览器就能用的云起实验室: 《免费体验PolarDB开源数据库》
3、PolarDB开源数据库内核、最佳实践等学习图谱:  https://www.aliyun.com/database/openpolardb/activity 
关注公众号, 持续发布PostgreSQL、PolarDB、DuckDB等相关文章. 

把系统时间调小对数据库有什么影响?

我们可能会遇到两种需要调整数据库服务器时钟的情况, 它们分别对数据库有什么影响? 你敢不敢拍胸脯调整? 调整时要不要重启数据库?

  • 数据库服务器的时钟跑太慢, 比真实时间小, 要调大.

  • 数据库服务器的时钟跑太快, 比真实时间大, 要调小.

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) , 学习数据库不迷路.  

近期正在写公开课材料, 未来将通过视频号推出, 欢迎关注视频号:

Image

文章中的参考文档请点击阅读原文获得.