PostgreSQL存储空间回收

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介: 1.概述  随着数据库的运行,存储空间里会产生一些无用的数据,需要进行清理。 产生这些无用数据的原因有: ? 行被删除 ? 插入行的事务终止 ? 由更新产生的旧的行版本 需要回收的存储空间主要包括以下几个方面: ? 行版本(占用空间最大) ? 行版本指针(占用空间最小) ? 索引项   2.回收方法 2.1 表的单页清理 通过SELECT,UPDATE和DELETE访问表时,会触发表的单页清理。

1.概述 

随着数据库的运行,存储空间里会产生一些无用的数据,需要进行清理。
产生这些无用数据的原因有:
? 行被删除
? 插入行的事务终止
? 由更新产生的旧的行版本

需要回收的存储空间主要包括以下几个方面:
? 行版本(占用空间最大)
? 行版本指针(占用空间最小)
? 索引项

 

2.回收方法

2.1 表的单页清理

通过SELECT,UPDATE和DELETE访问表时,会触发表的单页清理。清理对象仅限于被废弃的行版本(对任何事务都不可见)。同时标记行版本指针为Dead状态。下次执行vacuum时,会回收不用的索引项和行版本指针。

删除前: 



删除后:


*)行版本指针共有4个状态,存储在lp_flags域:
Unused
Normal
Redirect
Dead

2.2 vacuum


通过vacuum或autovacuum清理时,被废弃的行版本,行版本指针和索引项都会得到清理。普通的vacuum不会释放存储空间给OS,除非在表文件的末尾有连续的空页。vacuum full会将整个数据重写一遍,仅保留有用的数据。vacuum full时要锁住整个表,会影响其它并发作业。

vacuum后:



3.更新的优化

满足以下条件时,采用称之为HOT(heap-only tuples)更新的技术提高性能。
1)新旧行版本存储在同一个页上
2)更新不涉及被索引列值的变更
通过行版本头部的ctid或者行版本指针的lp_flags(Redirect)+lp_off让旧版本指向新版本,形成一个HOT更新链。这样在更新时就可以重用原来的索引项,避免删除和追加索引项。索引项仍然指向旧的行版本指针,然后通过HOT更新链找到对应的新版本。
使用ctid或lp_flags(Redirect)+lp_off形成HOT更新链的区别在于:前者保留了旧的行版本,而后者用于旧的行版本已被回收的情况。当旧的行版本对某些活动事务仍然可见时,是不能被回收的。HOT更新时对于处于HOT更新链中间位置的行版本指针是可以被立即回收的(头指针被索引使用,尾指针指向最新的行版本,所以要保留)。

初始状态:只有一个版本


第一次更新:通过旧行版本头部的ctid指向新行班本


第二次更新:V1的行版本空间被再利用。并且通过Redirect将索引使用的第一个行版本指针引向保留下来的最老的行版本。


第三次更新:


最终由于其他操作触发废弃的行版本被回收:


4.性能提示


为了能让HOT更新充分发挥作用,需要尽量减少不必要的索引,并合理设置表的存储参数fillfactor。
fillfactor控制插入时页存储空间的使用率,取值范围为10%~100%,缺省值为100,即不为HOT更新保留空间。
对于频繁更新非索引列的表,应该将fillfactor适当设小。

5.参考


http://momjian.us/main/writings/pgsql/mvcc.pdf

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
8月前
|
数据库
【教程】truncate清空表数据,为什么数据库的空间还是和原来一样并没有释放|数据库释放表空间教程
【教程】truncate清空表数据,为什么数据库的空间还是和原来一样并没有释放|数据库释放表空间教程
|
10月前
|
存储 关系型数据库 Java
postgresql清理表空间
postgresql清理表空间
197 0
|
7月前
|
SQL 存储 关系型数据库
MySQL学习笔记-如何有效的回收表空间
MySQL学习笔记-如何有效的回收表空间
107 0
|
9月前
|
安全 关系型数据库 数据库
创建 PostgreSQL 表空间时没有指定空间的总大小
创建 PostgreSQL 表空间时没有指定空间的总大小
97 1
|
12月前
|
NoSQL Shell MongoDB
一日一技:单机单节点 MongoDB 为什么删除数据后不释放空间?
一日一技:单机单节点 MongoDB 为什么删除数据后不释放空间?
548 0
|
存储 SQL 关系型数据库
Mysql碎片整理:存储程序
定义变量;语句结束分隔符;存储函数;存储过程;游标在存储过程和存储函数中的使用;触发器的定义;事件的创建。
78 0
|
SQL 监控 关系型数据库
RDS怎么查看存储空间的详细使用情况?
RDS怎么查看存储空间的详细使用情况?
RDS怎么查看存储空间的详细使用情况?
|
关系型数据库 MySQL
Mysql空间清理,最硬核
Mysql空间清理,最硬核
484 0
Mysql空间清理,最硬核
|
关系型数据库 MySQL
mysql某个表中数据量大删数据后空间不释放
mysql某个表中数据量大删数据后空间不释放
|
监控 关系型数据库 MySQL
如何定位RDS MySQL内存使用率高?
打开performance_schema 控制台可开 打开内存监控 update performance_schema.setup_instruments set enabled = 'yes' where name like 'memory%'; 查看监控 select * from sys.
3931 0