8c之VACUUM
最近学习一下8c相关东西,摘抄了一些文章加以参考
个人实验得出的一些总结
1、官方文档说vacuum full会释放磁盘空间,标准VACUUM(即不带FULL)不会,标准VACUUM也能把该表文件空间交还给操作系统的情况:表尾部有空页就能释放这个空页的空间,页包含页头部和行数据,也就是说如果每行数据都是死元组,那么整个这个页就是空闲的,实验场景,当我们insert一张新建的表或全是死元组的表时,insert的时候都是往尾部插入(类似oracle的insert /*+ append */往高水位线以上插入),而一旦delete整表后,则整表的所有页里面都是死元组,直接VACUUM 不带FULL也能把这个页就给回收空间了,见本文的实验“delete后,执行vacuum,表的大小从1GB变成了0KB”
2、vacuum full 表的情况下,select没法查询表,select会被vacuum full堵塞
3、vacuum full 表会释放表文件对应的磁盘空间,因为表对应的pg_class.relfilenode都变了
在PostgreSQL中,一次行的UPDATE或DELETE不会立即移除该行的旧版本。这种方法对于从多版本并发控制MVCC获益是必需的:即当旧版本仍可能对其他事务可见时,它不能被删除。但是最后,任何事务都不会再对一个过时的或者被删除的行版本感兴趣。它所占用的空间必须被回收来用于新行,这样可避免磁盘空间需求的无限制增长。这通过运行VACUUM完成。
VACUUM的标准形式移除表和索引中的死亡行版本并将该空间标记为可在未来重用。不过,它将不会把该空间交还给操作系统,除非在特殊的情况中表尾部的一个或多个页面变成完全空闲并且能够很容易地得到一个排他表锁。相反,VACUUM FULL通过把死亡空间之外的内容写成一个完整的新版本表文件来主动紧缩表。这将最小化表的尺寸,但是要花较长的时间。它也需要额外的磁盘空间用于表的新副本,直到操作完成。
例行清理的一般目标是多做标准的VACUUM来避免需要VACUUM FULL。自动清理守护进程尝试这样工作,并且实际上永远不会发出VACUUM FULL。在这种方法中,其思想不是让表保持它们的最小尺寸,而是保持磁盘空间使用的稳定状态:每个表占用的空间等于其最小尺寸外加清理之间被用完的空间。尽管VACUUM FULL可被用来把一个表收缩回它的最小尺寸并将该磁盘空间交还给操作系统,但是如果该表将在未来再次增长这样就没什么意义。因此,对于维护频繁被更新的表,适度运行标准VACUUM运行比少量运行VACUUM FULL要更好。
PostgreSQL有一个可选的但是被高度推荐的特性autovacuum,它的目的是自动执行VACUUM和ANALYZE 命令。当它被启用时,自动清理会检查被大量插入、更新或删除元组的表。这些检查会利用统计信息收集功能,因此除非track_counts被设置为true,自动清理不能被使用。在默认配置下,自动清理是被启用的并且相关配置参数已被正确配置。
“自动清理后台进程”实际上由多个进程组成。有一个称为 自动清理启动器的常驻后台进程, 它负责为所有数据库启动自动清理工作者进程。 启动器将把工作散布在一段时间上,它每隔 autovacuum_naptime秒尝试在每个数据库中启动一个工作者 (因此,如果安装中有N个数据库,则每 autovacuum_naptime/N秒将启动一个新的工作者)。 在同一时间只允许最多autovacuum_max_workers 个工作者进程运行。如果有超过autovacuum_max_workers 个数据库需要被处理,下一个数据库将在第一个工作者结束后马上被处理。 每一个工作者进程将检查其数据库中的每一个表并且在需要时执行 VACUUM和/或ANALYZE。 可以设置log_autovacuum_min_duration 来监控自动清理工作者的活动。
如果在一小段时间内多个大型表都变得可以被清理,所有的自动清理工作者可能都会被占用来在一段长的时间内清理这些表。这将会造成其他的表和数据库无法被清理,直到一个工作者变得可用。对于一个数据库中的工作者数量并没有限制,但是工作者确实会试图避免重复已经被其他工作者完成的工
原文地址:https://blog.csdn.net/weixin_55963561/article/details/144317747
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!