这是一个好问题,值得深入思考。
虽然我还不是特别精通,但是阅读官方文档对TSO的描述:
下面示例展示了 TSO 时间戳的二进制细节:
0000011000101000111000010001011110111000110111000000000000000100 ← 该值是二进制形式的 443852055297916932
0000011000101000111000010001011110111000110111 ← **前 46 位是物理时间戳**
000000000000000100 ← 后 18 位是逻辑时间戳
TSO 时间戳由两部分组成:
- 物理时间戳:自 1970 年 1 月 1 日以来的 UNIX 时间戳,单位为毫秒。
- 逻辑时间戳:递增计数器,用于需要在一毫秒内使用多个时间戳的情况,或某些事件可能触发时钟进程逆转的情况。在这些情况下,物理时间戳会保持不变,而逻辑时间戳保持递增。该机制可以确保 TSO 时间戳的完整性,确保时间戳始终递增而不会倒退。
你可以通过 SQL 语句更深入地查看 TSO 时间戳,示例如下:
SELECT @ts, UNIX_TIMESTAMP(NOW(6)), (@ts >> 18)/1000, FROM_UNIXTIME((@ts >> 18)/1000), NOW(6), @ts & 0x3FFFF\G
*************************** 1. row ***************************
@ts: 443852055297916932
UNIX_TIMESTAMP(NOW(6)): 1693161835.502954
(@ts >> 18)/1000: 1693161221.6870
FROM_UNIXTIME((@ts >> 18)/1000): 2023-08-27 20:33:41.6870
NOW(6): 2023-08-27 20:43:55.502954
@ts & 0x3FFFF: 4
1 row in set (0.00 sec)
前 46 位是物理时间戳 那么时间回调是不是意味着会导致TSO 变小,从而导致重复的出现?
如果是的话,感觉还是比较危险的。
这让我想起Oracle 10g一个常见的bug,就是时间回调有可能会导致RAC节点重启。