Oracle 11gR2 Exadata
我需要唯一标识何时及时创建记录。序列缓存意味着我不能使用基于序列的 ID,而批量插入意味着在一个批次中插入的所有记录都将具有相同的时间戳值(即使使用 TIMESTAMP(9))。类似于 Twitter 的since_id 概念。
到目前为止我想到的最好的选择
- 创建用于每个唯一时间戳的附加序列
- 不批量插入记录以强制每条记录使用唯一的时间戳
- 不缓存序列,尽管有一些讨论认为这不会解决 Exadata 下的问题
这是我的要求:我有一个 API,它允许用户提供一个序列作为标记并请求从那时起的所有记录。例如,他们请求标记为 7 的 1000 条记录,他们将从我的表中获取 1000 条 ID 大于 1007 的记录。例如,假设返回的 1000 条记录中数字最大的 ID 是 2045,因此我们返回 2045 为标记 后来,客户请求 1000 条记录,标记为 2045,期望获得下一批 1000 和新标记。
非常简单的方法可以让他们以适合他们的任何大小获取所有记录而不会丢失任何记录。但是,由于跨多个 Exadata 节点的序列缓存,在客户端请求标记为 1007 的 1000 条记录时,可能尚未创建 ID 为 2020 的记录。因此,当他们使用 2045 标记进行下一个请求时,他们将永远错过 2020 年的记录。使用 ID 获取关联记录的时间戳可以解决这个问题,但是我必须确保始终将记录单独插入表中以保证唯一的时间戳。
假设:
- 不是为批量/批量插入的单个记录获取单独时间戳的方法
- 即使在序列上使用 NOCACHE 时,多个节点也可能导致记录的插入是非时序的(例如,序列值为 180 的记录可以使用大于序列值为 179 的记录的 systimestamp 写入)
希望我只是没有找到正确的术语来搜索现有答案。我觉得这是一个多年来应该通过一些模式来解决的问题。我认为Twitter已经解决了它......
我建议按时间戳排序。只要在同一事务中插入唯一具有相同时间戳的记录,就可以使用基于序列的 ID 作为二级排序。
好吧,事实证明,在初始插入完成后,我需要使用同步过程为每条记录分配一个 ID。
正如向我指出的那样,我真正想要的是一个提交序列。不幸的是,即使时间戳也不会提供,因为它是在插入时生成的,而不是在提交时生成的。因此,在某些情况下,一组记录 (A) 的时间戳可能在第二组记录 (B) 之前,但组 B 实际上可以首先提交到数据库。那我就没有解决原来的问题。
最后,我们通过使用表锁定(在“序列”表上)和跳过锁定的过程使用了本质上是同步的家庭实现的序列。因此,我们不必通过单线程来减慢我们的插入过程,但我们保证了一个 ID,该 ID 保证在该 ID 提交到记录时的提交顺序中。