电科金仓数据库(KingbaseES)存储管理深度解析
电科金仓 KingbaseES 在
存储
管理层面构建了一套完整的技术体系,涵盖超大字段处理、I/O 性能分层以及内存大页优化三大核心模块。下面从原理到实践,逐一拆解这三个关键机制。
一、TOAST 技术:超大字段的”压缩与分片”之道
1.1 为什么需要 TOAST?
KingbaseES 以**页(Page)**作为数据文件存储的基本单位,默认大小为 8KB,且严格禁止单行数据跨页存储。这意味着页大小就是行大小的硬上限。
当业务中出现 TEXT、BYTEA、JSONB 等大字段时,若不加处理,一行数据极易突破这一上限。TOAST(The Oversized-Attribute Storage Technique,超大属性存储技术)正是为此而生——通过压缩 + 切片行外存储两种手段,将超大字段”瘦身”后安全落盘,且对用户完全透明。
1.2 TOAST 的触发机制
| 阶段 | 触发条件 | 行为 |
|---|---|---|
| 压缩 | 字段数据 > 2KB(TOAST_TUPLE_THRESHOLD) | 优先对数据进行压缩 |
| 行外存储 | 压缩后仍 > 2KB | 切片写入独立 TOAST 表,原字段替换为指针 |
| 不处理 | 数据 ≤ 2KB | 直接存储在主表行内 |
每张主表都有一张唯一关联的 TOAST 表,命名规则为
pg_toast.pg_toast_<主表OID>,结构固定为三列:chunk_id(块标识)、chunk_seq(块序号)、chunk_data(实际数据)。
1.3 四种 TOAST 存储 策略
1 | PLAIN → 禁止压缩 + 禁止行外存储(适用于 INTEGER 等定长类型) |
查看与修改策略的方式:
1 | -- 查看字段存储策略 |
注意:修改 TOAST 策略不会影响已有数据的存储方式,仅对后续写入生效。
1.4 实验 验证:EXTENDED vs EXTERNAL 的差异
以下实验直观展示了两种策略在行外存储时的本质区别:
EXTENDED 策略(先压缩,再行外存储):
1 | name 字段长度达到 327,680 字节时,TOAST 表仅产生 2 行: |
EXTERNAL 策略(禁止压缩,直接行外存储):
1 | name 字段长度为 5,120 字节时,TOAST 表产生 3 行: |
核心结论: EXTENDED 策略下,压缩优先于行外存储;一旦数据(压缩后)超过 2KB,无论哪种策略,均会触发行外存储。
二、逻辑读与物理读:I/O 性能的分层理解
2.1 KingbaseES 的 内存 区域划分
KingbaseES 的数据访问路径涉及三
类
内存区域,理解它们是分析 I/O 性能的基础:
| 内存区域 | 作用 | 可见范围 |
|---|---|---|
shared_buffers | 共享数据库块缓冲,所有关系表的读写必经之路 | 所有会话共享 |
temp_buffers | 临时表专用缓冲 | 仅当前会话可见 |
work_mem / maintenance_work_mem | 排序、Hash 等操作的工作内存,不足时溢出到临时文件 | 仅当前会话可见 |
2.2 四种数据访问方式
1 | Hit(逻辑读命中) → 直接在 shared/local buffer 中找到数据,零磁盘 IO |
2.3 通过 sys_stat_statements 量化 I/O
sys_stat_statements 视图是诊断
SQL
性能的核心工具,关键字段含义如下:
| 字段 | 含义 | I/O 类型 |
|---|---|---|
shared_blks_hit | shared_buffer 命中块数 | 逻辑读(无 IO) |
shared_blks_read | 从 OS 缓存/磁盘读入 shared_buffer 的块数 | 物理读 |
shared_blks_written | 从 shared_buffer 写出的块数 | 物理写 |
local_blks_read | 临时表缓冲未命中,从 OS 读入的块数 | 物理读 |
temp_blks_read | 从临时文件读入 work_mem 的块数 | 物理读(排序溢出) |
temp_blks_written | 从 work_mem 写入临时文件的块数 | 物理写(排序溢出) |
与 Oracle 的重要区别: KingbaseES 的
read/written统计包含操作系统缓存层,即使数据已在 OS Page Cache 中命中,也会被计入物理读,而 Oracle 的物理读统计不考虑 OS 缓存层。
2.4 性能诊断思路
1 | 逻辑读高(shared_blks_hit 大) → 缓存利用率好,性能优 |
KWR 报告中的 TOP SQL 模块可直接定位高 I/O 消耗的 SQL 语句,是日常巡检的重要入口。
三、Hugepage 配置:锁定共享内存,告别 Swap
3.1 为什么要配置 Hugepage?
Linux
默认以 4KB 为单位管理内存,维护虚拟地址到物理地址映射的 Page Table 会随内存增大而急剧膨胀。对于 KingbaseES 这类需要大 shared_buffers 的数据库,开启 标准 Hugepage(2MB/页) 带来三重收益:
- 降低 Page Table 开销:同等内存下,Hugepage 的页表条目数仅为普通页的 1/512
- 锁定物理内存:Hugepage 预分配且不可被 Swap 换出,避免
shared_buffers被置换到磁盘 - 提升 TLB 命中率:更大的页面覆盖更多地址空间,减少 TLB Miss
透明大页(Transparent Hugepage)与标准大页同时存在时可能引发性能问题,强烈建议禁用透明大页。
3.2 标准 Hugepage 配置步骤
第一步:计算所需 Hugepage 数量
1 | # 获取数据库主进程 PID |
第二步:分配并持久化 Hugepage
1 | # 临时生效 |
第三步:验证分配结果
1 | cat /proc/meminfo | grep -i huge |
3.3 禁用透明大页
在 /etc/rc.local 中添加以下内容并重启:
1 | if test -f /sys/kernel/mm/transparent_hugepage/enabled; then |
3.4 配置数据库参数
在 kingbase.conf 中设置:
1 | huge_pages = try # 推荐:优先使用大页,不足时自动回退到普通页 |
验证是否生效: 重启数据库后,执行 pmap <新PID> | awk '/rw-s/ && /zero/',若无输出,则说明 Hugepage 已成功接管 shared_buffers 内存区域。
总结:三大机制的协同价值
这三项技术共同构成了 KingbaseES 存储管理的核心骨架:
| 技术 | 解决的核心问题 | 关键参数/阈值 |
|---|---|---|
| TOAST | 超大字段突破 8KB 页限制 | TOAST_TUPLE_THRESHOLD = 2KB |
| 逻辑读/物理读 | 量化 SQL 的 I/O 消耗,定位性能瓶颈 | sys_stat_statements 视图 |
| Hugepage | 锁定 shared_buffers,消除 Swap 风险 | huge_pages = try |
三者从数据存储形态、I/O 行为分析、内存资源管理三个维度相互补充——TOAST 决定数据如何存,逻辑/物理读决定如何量化访问代价,Hugepage 则保障内存访问的稳定性与效率。掌握这三个机制,是深入理解 KingbaseES 性能调优的重要基础。
存储管理深度解析/d16d47271bae52213042e1a0a350778b.webp)
存储管理深度解析/3ad0aa0f8f4179381fb9cf274aa4cc1d.webp)



