ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PostgreSQL TOAST机制:大字段存储、压缩与pg_toast诊断

PostgreSQL TOAST机制:大字段存储、压缩与pg_toast诊断 PostgreSQL 用久了你迟早会撞上一个让人挠头的现象一张表里存了 100MB 的文本翻遍主表的数据文件却发现它只占了几百 KB真正的大头全躲在一个叫pg_toast的角落里又或者反过来明明只是插入一条不大的记录磁盘写入却慢得离谱。这些反直觉的表现几乎都和 PostgreSQL 里一个低调但极其关键的技术有关——TOAST。TOAST 全称是 The Oversized-Attribute Storage Technique直译过来就是超大属性存储技术。它是 PostgreSQL 处理大字段text、bytea、jsonb、数组等变长类型的底层机制决定了这些字段能不能被压缩、要不要被搬出主表、以及读写时到底付出了多少代价。不管你是在做日志系统、内容平台、地理数据的存储还是整天和 jsonb 打交道只要碰大字段就一定会和 TOAST 打交道。这篇就把 TOAST 从触发条件、存储策略、压缩分块到落盘结构完整拆一遍再配上我实际动手跑出来的观测数据让你看完就能自己诊断生产环境里的 TOAST 问题。1. 先讲清楚 TOAST 到底在解决什么矛盾理解 TOAST 之前得先理解 PostgreSQL 存储层的一个硬约束。很多人对数据库能存大字段这件事想当然觉得既然字段类型叫 text、bytea那往里塞多大都行。能塞确实是能塞但塞进去之后怎么放、放哪里、取的时候怎么拼回来背后全是设计取舍。TOAST 就是被这个硬约束逼出来的方案。1.1 8KB 的页和一行必须装进一页PostgreSQL 的磁盘存储单位是页page也叫 block默认大小 8KB编译时的BLCKSZ通常就是 8192 字节。堆表heap table里所有的行都是按页组织的每一行必须完整地落在某一个页里不允许跨页。为什么不允许跨页因为堆表给每一行只维护一个行指针ItemId里面记录的是页内偏移一旦允许一行跨页指针就没法用一个偏移量表达顺序扫描和 MVCC 的页内可见性判断都会变得复杂。所以 PostgreSQL 干脆规定**一行数据的所有内容除
返回列表