tencent cloud

云数据库 PostgreSQL

动态与公告
产品动态
产品简介
产品概述
产品特性
产品优势
应用场景
信息安全说明
地域和可用区
产品功能列表
大版本生命周期说明
MSSQL 兼容版
产品计费
计费概述
实例类型与规格
购买方式
退费说明
欠费说明
备份空间收费说明
快速入门
创建 PostgreSQL 实例
连接 PostgreSQL 实例
管理 PostgreSQL 实例
数据导入
通过 DTS 迁移数据
内核能力介绍
内核版本概述
内核版本更新动态
查看内核版本
自研内核功能介绍
数据库审计
审计服务说明
开通审计服务
查看审计日志
修改审计服务
审计性能说明
用户指南
实例管理
升级实例
CPU 弹性扩容
只读实例
账号管理
数据库管理
参数管理
日志管理及分析
备份与恢复
数据迁移
插件管理
网络管理
访问管理
数据安全
租户及资源隔离
安全组
监控与告警
标签
AI 实践
使用 tencentdb_ai 插件调用大模型
使用 tencentdb_ai 插件构建 AI 应用
结合 Supabase 快速构建基于云数据库 PostgreSQL 的后端服务
实践教程
跨库访问
如何在 PostgreSQL 中自动创建分区
基于 pg_roaringbitmap 实现超大规模标签查找
一条 SQL 实现查询附近的人
如何配置云数据库 PostgreSQL 作为 GitLab 外部数据源
通过 cos_fdw 插件支持分级存储能力
通过 pgpool 实现读写分离
通过 auto_explain 插件实现慢 SQL 分析
使用 pglogical 进行逻辑复制
使用 Debezium 采集 PostgreSQL 数据
在 CVM 本地搭建 PostgreSQL 异地灾备环境
只读实例与只读组实践教程
如何使用云函数定时操作数据库
表膨胀处理
性能白皮书
测试方法
测试结果
API 文档
History
Introduction
API Category
Making API Requests
Instance APIs
Read-only Replica APIs
Backup and Recovery APIs
Parameter Management APIs
Security Group APIs
Performance Optimization APIs
Account APIs
Specification APIs
Network APIs
Data Types
Error Codes
常见问题
相关协议
Service Level Agreement
Terms of Service
词汇表
联系我们

异步 invalid buffer

PDF
聚焦模式
字号
最后更新时间: 2024-01-22 16:17:09

背景介绍

PostgreSQL 主从复制的逻辑在具有大量数据表的 DDL 变更时会导致从库恢复数据极其缓慢。为了避免此类问题,TencentDB 针对此类场景进行了优化和修改。

原理介绍

PostgreSQL 是通过物理复制实现主从复制。日志同步到备机之后,备机会解析 wal 日志,来与主库保持数据一致。在 PostgreSQL 从库在恢复一条 drop 类语句时要做的操作如下:
1. 恢复系统表,例如 pg_class,pg_attrbute,pg_type 等,相当于移除表的元信息。
2. close 表对应的文件。
3. 遍历 buffer 中的页面,如果缓存的是该表的页面,则标记为 invalid,后面其他进程可以使用该页面。
4. 发异步失效消息给其他 backend,通知该表已删除。
5. 删除表对应的物理文件。
但在 PostgreSQL 内核中第3步将会执行 DropRelFileNodesAllBuffers 函数。其函数需要遍历整个 shard_buffer,以查看 buffer 是否缓存有将要删除的表的数据,将其标记为失效。而 PostgreSQL 中页面大小默认为8K,以 shard_buffer 大小16GB为例,则一共有16GB/8K = 200W个 page,每删除一个表这里需要循环200万次,如果表上面有索引,每个索引也要循环200万次。
所以从业务上看,当存在大量表变更并且快速删除表操作的时候,由于主库可以并发执行所以感觉不出性能的影响,但是因为 PostgreSQL 的备库是单进程的 recovery,就会出现主备同步日志堆积,数据延迟的问题。

问题解决

腾讯云数据库 PostgreSQL 在 recover drop table 操作时,将表信息写入一个共享的 hash 表中。当存在表文件删除场景下,不再直接进行物理删除,将删除实际文件的动作作为异步动作存储其中。
当 invalid buffer 结束时将表从 hash 表中移除,这样,如果在此过程中发生打开文件失败,检查是否存在此 hash 表中即可。并且如果在新创建文件的时候也去遍历一下此队列,若队列中存在同名文件正在 invalid buffer,则等待即可。 而 PostgreSQL 关于表文件命名是一个 uint32 整数保存,采用的是“全局分配,局部存储”的方式,即一个实例下的所有数据库使用一个计数器生成文件号,生成的文件保存在各自库的目录下,分配时,如果当前库下已有同名文件,则尝试下一个,直到没有冲突为止,计数器绕圈后重新开始。
经过优化后,可以明显发现同类场景下主从同步性能增强了3W多倍。

帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈