代码编织梦想

前面我们介绍了PG中的Concurrent VACUUM,详细请参考PostgreSQL之Concurrent VACUUM,这篇我们继续来了解一下PG中的Full VACUUM。
我们了解Concurrent VACUUM允许在执行的时候仍然允许对正在VACUUM的表进行读取操作,因此这个操作对业务的影响也比较小。但是Full VACUUM在执行期间是不允许对相关表进行任何操作的,所以它对业务的影响也比较大,那么为什么还需要Full VACUUM呢?

我们假如以下一种场景,一个表有三个Page,每个Page里面有6条Tuple,如下图所示。
在这里插入图片描述
然后我们执行以下操作,

testdb=# DELETE FROM tbl WHERE id % 6 != 0;
testdb=# VACUUM tbl;

VACUUM结束后,我们发现每个页面中现在只剩下一条Tuple了,不过仍然还是有三个Page存在。如果我们想查询这三条数据,那么仍然需要访问三个Page。由于每个Page是大小固定的,因此表的SIZE仍然没有变化。所以,Concurrent VACUUM动作后只是可以让页面中的部分空间可以重用,但是并不能真正释放空间。
为了解决真实可以释放空间这个问题,因此才有了Full VACUUM。
在这里插入图片描述上图是Full VACUUM的整个过程,可以总结为以下步骤:

  1. 创建新文件 -当针对某个表调用VACUUM FULL命令时,首先会获取表上的AccessExclusiveLock锁,然后创建一个新的表文件(大小为8KB),此后表不能被读写。
  2. 将活跃的tuples拷贝到新文件 -将老文件中活跃的tuples拷贝到新的文件中。
  3. 删除老文件,重建索引,更新统计信息、FSM及VM -在完成拷贝活跃tuples到新文件后,删除老的文件,然后重建索引,更新表对应的FSM和VM文件,更新相关的统计信息及数据。

Full VACUUM步骤的伪代码如下:

(1)  FOR each table
(2)       Acquire AccessExclusiveLock lock for the table
(3)       Create a new table file
(4)       FOR each live tuple in the old table
(5)            Copy the live tuple to the new table file
(6)            Freeze the tuple IF necessary
            END FOR
(7)        Remove the old table file
(8)        Rebuild all indexes
(9)        Update FSM and VM
(10)      Update statistics
            Release AccessExclusiveLock lock
       END FOR
(11)  Remove unnecessary clog files and pages if possibl

注:FULL VACUUM有两个注意事项:

  • Full VACUUM过程中表不能被访问
  • 由于是先创建新文件,拷贝后再删除老文件,最多会有2倍的空间占用

什么时候执行Full VACUUM?

这个没有一个标准,可以借用pg_freespacemap插件来查看表对应的FreeSpace大小。执行VACUUM后有什么变化,执行Full VACUUM后有什么变化。

testdb=# CREATE EXTENSION pg_freespacemap;
CREATE EXTENSION

testdb=# SELECT count(*) as "number of pages",
       pg_size_pretty(cast(avg(avail) as bigint)) as "Av. freespace size",
       round(100 * avg(avail)/8192 ,2) as "Av. freespace ratio"
       FROM pg_freespace('accounts');
 number of pages | Av. freespace size | Av. freespace ratio 
-----------------+--------------------+---------------------
            1640 | 99 bytes           |                1.21
(1 row)

testdb=# DELETE FROM accounts WHERE aid %10 != 0 OR aid < 100;
DELETE 90009

testdb=# VACUUM accounts;
VACUUM

testdb=# SELECT count(*) as "number of pages",
       pg_size_pretty(cast(avg(avail) as bigint)) as "Av. freespace size",
       round(100 * avg(avail)/8192 ,2) as "Av. freespace ratio"
       FROM pg_freespace('accounts');
 number of pages | Av. freespace size | Av. freespace ratio 
-----------------+--------------------+---------------------
            1640 | 7124 bytes         |               86.97
(1 row)

testdb=# SELECT *, round(100 * avail/8192 ,2) as "freespace ratio"
                FROM pg_freespace('accounts');
 blkno | avail | freespace ratio 
-------+-------+-----------------
     0 |  7904 |           96.00
     1 |  7520 |           91.00
     2 |  7136 |           87.00
     3 |  7136 |           87.00
     4 |  7136 |           87.00
     5 |  7136 |           87.00

testdb=# VACUUM FULL accounts;
VACUUM
testdb=# SELECT count(*) as "number of blocks",
       pg_size_pretty(cast(avg(avail) as bigint)) as "Av. freespace size",
       round(100 * avg(avail)/8192 ,2) as "Av. freespace ratio"
       FROM pg_freespace('accounts');
 number of pages | Av. freespace size | Av. freespace ratio 
-----------------+--------------------+---------------------
             164 | 0 bytes            |                0.00
(1 row)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Post_Yuan/article/details/129830184

使用plsql往oracle的blob插入图片_post_yuan的博客-爱代码爱编程_plsql 插入图片

一、创建测试表 create table t_blob(a int, b varchar(10), c blob); 二、创建数据库目录,映射到服务器指定目录 create directory ffolder as

Postgresql的vacuum机制一些理解-爱代码爱编程

我们知道,postgresql(以下简称pg)多版本控制mvcc和oracle有所不同,oracle通过回滚段实现,数据更新之前先将旧版本数据写入回滚段,然后再将待更新数据写入原data block,而pg mvcc则是当元组发生更改时,直接在原数据data page插入一条新的记录,同时将原元组逻辑上标识为删除,这些标识为删除的元组也叫死元组。这就导致当

vacuum 数据库 用法_PostgreSQL中快速对系统表实现vacuum full-爱代码爱编程

vacuum full会锁表,而且效率很低,在实际中不可能使用vacuum来缩小pg_class,这样会有很长的停机时间。 其实要实现vacuum full最简单的方法就是将一个表重新复制一遍,create table b as select * from a;然后再使用b表代替a表使用就可以了。 鉴于pg_class是所有表的基础,我们就算将其拷

[postgresql]postgresql的VACUUM 介绍-爱代码爱编程

目录   定义 语法 描述 参数 输出 注意 定义 VACUUM 垃圾收集并根据需要分析一个数据库。 语法 VACUUM [ ( { FULL | FREEZE | VERBOSE | ANALYZE | DISABLE_PAGE_SKIPPING } [, ...] ) ] [ table_name [ (column_nam

PostgreSQL之vacuum学习-爱代码爱编程

文章目录 一、vacuum的背景1.1 常见数据库MVCC实现对比二、vacuum工作机制2.1 vacuum2.2 autovacuum 我们常用的关系型数据库有MySQL、Oracle、SQL Server、PostgreSQL等…但是vacuum的概念只有PG数据库有,而且运维过PG数据库的工程师都应该对它很熟悉,vacuum是PG数据库非

postgresql-vacuum和vacuum full走了几步棋-爱代码爱编程

Vacuum过程 vacuum的执行过程主要分为以下三步: 1. 清除dead tuples指向的index tuples 该过程中,vacuum会顺序扫描目标表,并构建一个dead tuples组成的list链表,该list链表会存储在maintenance_work_mem缓存中。然后vacuum根据dead tuples list移除dead tu

postgres vacuum full 和 vacuum-爱代码爱编程

vacuum full mail_message 是我使用vacuum full清理的第一个表 空间从20G-->4G 效果很显著 odoo 大量update或者delete后 磁盘空间会猛增。原理是postgresql并没有真正的删除 只是将删除数据的状态置为已删除,该空间不能记录被从新使用。若是删除的记录位于表的末端,其所占用的空间将会被物理释

postgresql之concurrent vacuum-爱代码爱编程

在前面一文PostgreSQL之tuple结构中我们初步了解到PG中是采用了MVCC多版本机制,数据在删除时并不会直接从页面中删除掉而是通过修改t_xmax将其标记为delete,更新数据也是通过把原数据标记为delete并

postgresql vacuum 和 vacuum full_ispringmw的博客-爱代码爱编程

转载自 https://www.modb.pro/db/63663 dead tuples tuple:元组,也就是一行数据 首先,简要解释什么是"死元组"和"膨胀". 当您在PostgreSQL中执行DEL

postgresql之vacuum processing-爱代码爱编程

Outline of concurrent vacuum 做了什么 真空处理对数据库中的指定表或所有表执行以下任务: 1.移除死元组(空间整理,包含表数据,索引数据) oracle如何进行空间整理?手动进行尺寸thrink 删除死元组并对每个页面的活元组进行碎片整理。删除指向死元组的索引元组 2.冷冻老的txid 必要时冻结老元组的

postgresql 13 可以并行vacuum index 你知道对吧-爱代码爱编程

POSTGRESQL 我们在大量的使用,但实话实话知识的更新永远是滞后的,VACUUM 是可以并行进行INDEX 的操作,这个事情是在 POSTGRESQL 13 的这个版本上被实现的。 实际上POSTGRESQL 经常被其他数据库专家攻击的部分,有2个。 一个是我们熟知的 BF 问题,一个就是经常被提到的 Vacuum 问题。如果POST