digoal
2024-04-08
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作为本地授时服务),以确保时钟的准确性.
可参考: