PolarDB 物理复制SMO 同步机制

💡 原文中文,约9500字,阅读约需23分钟。
📝

内容提要

该文章讨论了在mtr中修改多个页面时可能出现的搜索操作错误的问题。通过引入sync_counter机制,可以避免错误,但会导致物理复制效率下降。作者提出了使用smo page queue或LogIndex SMO page queue的方法来解决这个问题,并减少store和restore操作。此外,还讨论了使用LogIndex和bw-tree的方法来解决非smo场景下的冲突问题。最后,作者提出了一些问题和可能的解决方案。

🔎

延伸解读

sync_counter 机制的性能代价

sync_counter 机制虽然避免了物理复制中因并行 apply redo log 导致的搜索错误,但其更新 sync_counter 时仍需持有 index x lock,这会与搜索操作的 index s lock 冲突。当只读节点读取频繁时,apply phase 需要等待,影响物理复制效率;同时,长时间等待 index x lock 也会导致新的搜索操作延迟。此外,乐观机制可能引发频繁的 store_position 和 restore_position 操作,即使 SMO 影响的页面与当前访问无关,也会

SMO page queue 的改进思路

文章提出 SMO page queue 方法,将发生 SMO 的页面 ID 传递到只读节点并记录在 SMO_array 中。在访问子页面或下一页时,通过过滤条件跳过不在 SMO_array 中的页面的 apply runtime redo 和 store/restore 操作,从而减少不必要的开销。进一步地,如果完全去掉 index_sync_all,仅依赖 SMO_array 判断,可以实现类似读写节点上 SMO 与搜索仅冲突于相关子树的效果,甚至使 SMO 之间也不冲突。

LogIndex 与 bw-tree 的版本管理差异

LogIndex 方法在访问页面时携带 LSN 信息,以获取指定版本的页面,避免访问到不存在的页面。与 bw-tree 相比,两者在内存中保存的页面版本不同:bw-tree 保存最老版本页面并维护 delta-chain,可读取任意版本;LogIndex 则内存保留最新版本,磁盘保留最老版本,读取指定版本需结合磁盘页面和解析的 redo log。此外,Aurora 和 Socrate 的 getPage(lsn) 协议返回大于等于 LSN 的任意页面,可能导致访问到未来页,而 LogIndex 和 bw-tree

apply phase 与 parse phase 的区分原因

物理复制严格区分 parse phase 和 apply phase。在 parse phase 期间,所有页面已 apply 到同一版本 m_applied_lsn,不会与用户请求冲突;而 apply phase 期间,用户读取与页面更新同时进行,因此冲突处理都集中在 apply phase。sync_counter 机制要求冲突时对齐到同一版本 m_next_apply_lsn,但缺点是该索引上的所有访问无论是否冲突都需对齐到最新版本,可能影响性能。区分两个阶段也是由于页面 SMO 操作引入的优化。

❓

Q&A

sync_counter机制的主要作用是什么?

sync_counter机制主要用于解决在mtr中修改多个页面时可能出现的搜索操作错误问题。

引入sync_counter机制后有什么缺点?

引入sync_counter机制后,物理复制效率下降,并且可能导致频繁的store和restore操作,影响性能。

如何使用SMO page queue来解决问题?

SMO page queue通过传递SMO page ID到RO节点,减少不必要的store和restore操作,从而提高性能。

LogIndex方法是如何工作的?

LogIndex方法通过带上lsn信息来访问指定版本的Page,避免访问到不存在的Page。

bw-tree和LogIndex有什么区别?

bw-tree在内存中保存的是最老版本的Page,而LogIndex则保留最新版本的Page,磁盘中保存最老版本。

在非SMO场景下如何解决冲突问题?

可以使用LogIndex和bw-tree的方法来解决非SMO场景下的冲突问题。

🏷️

标签

➡️

继续阅读