我希望实现一个表,该表可通过 3 个以上节点的 Percona XtraDB 集群访问。我预计它会以每月大约 100 万行的速度增长,并且数据将保留大约 2 年(2400 万行)。
该模式相对简单,但为简洁起见,我将使用具有有序 UUID 值的二进制 (16) 的 PK 省略无聊的部分。可以在此处查看详细信息 ( https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/ )。
在单台机器上,这将/应该始终产生一个很好的基于时间的插入顺序(由于有序的 UUID v1),这将使数据在结构中保持其预期顺序。但是,如果我开始在 PXC 中使用多个节点,那么生成的 UUID 在不同主机上的时间顺序可能会乱七八糟。即使将时钟漂移保持在绝对最小值,在多个数据中心之间往返,我也不能 100% 确定时间戳总是在最后一个之后。
我的结论是创建一个启用 AUTO_INCREMENT 的 BIGINT 字段,这是复合 PK 中的第一部分 - 但是,就数据库而言,我也可以取消 UUID,而只依赖 BIGINT。
有没有人对此有任何想法?我错过了什么吗?似乎在集群中使用有序的 UUID v1 实际上会使事情变得更糟......
好的。您了解 UUID 中继承的问题,并了解如何“修复”它。
让我们从另一端开始……因为您要将数据保存 2 年,所以让我们从按日期分区开始。我不关心数据是
INT
,TIMESTAMP
,DATETIME
,BIGINT
还是重新排列的 V1 UUID。(但是,您可能应该使用与您的申请相匹配的日期。)PARTITION
按日期分成24个分区。每个月,DROP
最旧的分区和REORGANIZE
未来的分区分为未来和下个月。有关详细信息,请参阅我的博客。好的,这解决了您尚未遇到的问题——每月删除一百万行的丑陋开销。
但是,您关心的是时钟的订购。这不是真正的问题。而且不值得追逐。即使
INSERT
晚了一秒钟——甚至晚一个小时——它对插入的整体性能影响也很小。当然,表格“末尾”上的“下一个”行经过了很好的优化。但是将它插入到“最后一个”块的某处,甚至最后 100 个块中,就足够有效了。充其量,InnoDB 使块不会很满。在大量流失的稳定状态下,BTree 已满 69%。对于“点查询”,这个数字几乎是无关紧要的。对于范围扫描,它有一些影响。我建议防止碎片化比忽略它代价更大。
即使只有
AUTO_INCREMENT
,您也不能保证行会按顺序插入可见!想想多线程会发生什么:所以,放弃严格排序。