PolarDB 共享存储架构下的"过去页面"问题解析
问题根源:为什么从库会读到过旧的 block
在 PolarDB 共享存储架构下,从库(只读节点)可能读到过旧页面的根本原因是:
内存淘汰机制:从库回放 WAL 后生成的新版本页面存储在 Buffer Pool 中,当 Buffer Pool 空间不足时,这些页面会被淘汰 主库刷脏延迟:主库不会立即将所有修改后的页面刷写到共享存储 版本不一致:当从库再次访问已被淘汰的页面时,从共享存储读取的是旧版本页面
具体流程:
// T1: 主库更新页面 P1 从版本 500 到 600,生成 WAL LSN=200
// T3: 从库回放 WAL,内存中 P1 版本为 600
// T4: 从库 Buffer Pool 淘汰 P1 页面
// T5: 从库再次访问 P1,从共享存储读取到版本 500(过旧页面)
解决方案:LogIndex 机制
PolarDB 通过 LogIndex 机制解决过去页面问题,核心思想是维护页面到 WAL 记录的映射关系 :
1. LogIndex 数据结构
LogIndex 是一个可持久化的 HashTable 结构:
Key: PageTag(标识具体数据页) Value: 修改该页面的所有 LSN 列表
2. 内存中的 LogIndex Memtable
// LogIndex Memtable 包含三个关键数组
- HashTable: 记录 Page 与 LSN List 的映射
- Segment: 存储 LogIndex Item,包含 LSN 链表
- Index Order: 记录 LogIndex 添加顺序
3. 延迟回放机制
从库的 Startup 进程基于 WAL Meta 生成 LogIndex,但不立即回放:
// 接收 WAL Meta 后:
1. 生成 LogIndex 记录
2. 将 Buffer Pool 中对应页面标记为 Outdate
3. 推进回放位点(不实际回放数据)
4. 实际回放延迟到访问时进行
代码实现细节
1. WAL Meta 处理
主库只传输 WAL Meta(不包含 payload)到从库:
// WAL Record 结构
struct XLogRecord {
general header portion; // 元数据部分
data portion; // 数据部分(不传输)
}
2. 页面回放触发
当从库访问页面时检查是否需要回放:
bool polar_logindex_restore_fullpage_snapshot_if_needed(
polar_logindex_redo_ctl_t instance,
BufferTag *tag,
Buffer *buffer)
{
// 检查是否是未来页面
if (!polar_is_future_page(GetBufferDescriptor(*buffer - 1)))
return false;
// 通过 LogIndex 查找需要回放的 WAL
// 从共享存储读取 WAL 并回放
}
3. 并行回放优化
从库实现两种回放方式:
背景回放进程:按 WAL 顺序依次回放 Buffer Pool 中的页面 Backend 进程:仅回放实际访问的页面
避免过旧页面的配置
1. 启用 LogIndex
# 必须启用共享存储模式
polar_enable_shared_storage_mode=on
# 配置 LogIndex 内存大小
polar_logindex_mem_size=64MB
2. 优化 Buffer Pool
# 适当增大 Buffer Pool 减少页面淘汰
shared_buffers=4GB
# 启用复制缓冲区处理热点页面
polar_enable_copy_buffer=on
polar_copy_buffer_size=128MB
3. 监控关键指标
-- 监控 LogIndex 状态
SELECT * FROM polar_logindex_stat();
-- 检查页面回放情况
SELECT * FROM polar_stat_buffercache();
-- 监控刷脏延迟
SELECT * FROM polar_stat_io_info;
Notes
LogIndex 机制通过延迟回放和并行回放,将 WAL 回放延迟降低到毫秒级 从库读取页面时,会先检查 Buffer Pool,若不存在或已过期,则通过 LogIndex 找到需要回放的 WAL 记录 LogIndex 记录会异步刷写到共享存储,确保持久化 通过 Bloom Filter 优化 LogIndex 查找效率
文章转载自PolarDB,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




