PostgreSQL使用固定的页面大小,并且不允许元组跨越多个页面。为了存储大数据,PG引入了TOAST技术-The Oversized-Attribute Storage Technique。这种技术在底层将大的数据压缩或分解成多个物理行,并且这些处理对用户都是无感的。
数据库会默认为各类数据类型应用不同的存储类型。
对列的存储类型不满意时也可以进行修改。
修改列的存储类型的语句是:
ALTER TABLE name ALTER [ COLUMN ] column_name SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
复制
(左右滑动查看完整内容)
修改可能会遇到一些小问题。
下边演示一下。
postgres=# create table toast_1 (id int ,name text);
CREATE TABLE
postgres=# \d+ toast_1
Table "public.toast_1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
id | integer | | | | plain | |
name | text | | | | extended | |
Access method: heap
复制
(左右滑动查看完整内容)
针对有行外存储的表,可以通过如下语句确认toast相关信息。
postgres=# select reltoastrelid,oid,relname from pg_class where relname='toast_1';
reltoastrelid | oid | relname
---------------+-------+---------
24885 | 24882 | toast_1
(1 row)
[postgres13@rhel711g 13577]$ ls -lrth {24882,24885}
-rw------- 1 postgres13 postgres13 0 Aug 10 16:11 24882
-rw------- 1 postgres13 postgres13 0 Aug 10 16:11 24885
复制
(左右滑动查看完整内容)
插入一条数据后再查
postgres=# insert into toast_1 values (1,'1');
INSERT 0 1
[postgres13@rhel711g 13577]$ ls -lrth {24882,24885}
-rw------- 1 postgres13 postgres13 0 Aug 10 16:11 24885
-rw------- 1 postgres13 postgres13 8.0K Aug 10 16:16 24882
复制
(左右滑动查看完整内容)
插入条超过8k的数据在查
[postgres13@rhel711g 13577]$ ls -lrth {24882,24885}
-rw------- 1 postgres13 postgres13 8.0K Aug 10 16:18 24882
-rw------- 1 postgres13 postgres13 8.0K Aug 10 16:20 24885
复制
(左右滑动查看完整内容)
坑来了
第一个
我们想改成行内存储
使用如下命令:
postgres=# alter table toast_1 alter name set storage PLAIN ;
ALTER TABLE
复制
(左右滑动查看完整内容)
再次查询toast信息,发现还是存在行外存储。
postgres=# select reltoastrelid,oid,relname from pg_class where relname='toast_1';
reltoastrelid | oid | relname
---------------+-------+---------
24885 | 24882 | toast_1
(1 row)
复制
(左右滑动查看完整内容)
postgres=# vacuum FULL toast_1;
ERROR: row is too big: size 30696, maximum size 8160
复制
(左右滑动查看完整内容)
提示行过大,原因就是该元组超过了一个页面的大小,没法存放只能使用行外存储。
因此对于超大的数据,只能采用行外存储方式。
如果正常的话,执行完vacuum full的效果。
postgres=# vacuum FULL toast_1;
VACUUM
postgres=# select reltoastrelid,oid,relname from pg_class where relname='toast_1';
reltoastrelid | oid | relname
---------------+-------+---------
0 | 24882 | toast_1
(1 row)
复制
文章转载自瀚高PG实验室,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
外国CTO也感兴趣的开源数据库项目——openHalo
小满未满、
475次阅读
2025-04-21 16:58:09
9.9 分高危漏洞,尽快升级到 pgAdmin 4 v9.2 进行修复
严少安
356次阅读
2025-04-11 10:43:23
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
334次阅读
2025-04-15 14:48:05
openHalo问世,全球首款基于PostgreSQL兼容MySQL协议的国产开源数据库
严少安
306次阅读
2025-04-07 12:14:29
postgresql+patroni+etcd高可用安装
necessary
172次阅读
2025-03-28 10:11:23
转发有奖 | PostgreSQL 16 PGCM高级认证课程直播班招生中!
墨天轮小教习
149次阅读
2025-04-14 15:58:34
墨天轮PostgreSQL认证证书快递已发(2025年3月批)
墨天轮小教习
129次阅读
2025-04-03 11:43:25
SQL 优化之 OR 子句改写
xiongcc
94次阅读
2025-04-21 00:08:06
融合Redis缓存的PostgreSQL高可用架构
梧桐
89次阅读
2025-04-08 06:35:40
PostgreSQL拓展PGQ实现解析
chirpyli
87次阅读
2025-04-07 11:23:17