vaccum

xtid:事务id ,0,invalid无效的1,Bootstrap初始化2 冻结的frozen,32位,42亿,有效21亿,环形
tuple:t_xmin,记录插入此元组的事务ID txid
t_xmax,记录删除或更新此元组的事务ID txid,如果这个元组没有被更新
或删除,t_xmax被设置为0,这意味这invalid
t_cid,记录命令ID(command id,cid),从0开始递增,表示当前事务中执行此命令之前
执行了多少个SQL命令,例如,假定我们在单个事务中执行3个insert命令
,BEGIN;INSERT;INSERT;INSERT;COMMIT;如果第一个命令插入这个元组
,则t_cid被设置为0,如果第2个命令插入该元组,则t_cid被设置在为
1,依此类推
t_ctid,记录指向自身或新元组的元组标识符(tuple identifier,tid),当这个元组更新
时,这个元组的c_tid指向新的元组,否则,t_ctid指向自己
3.事务回卷问题:100与21亿+100,100可见,如果变成21亿加101,100不可见,这就是事务回卷,将事务vaccum 进行冻结为2,则对后面的
永远可见,清理的速度比使用的快
4.postgresql的并发控制机制需要以下过程维护
4.1.删除dead tuple和指向对应的dead tuple的索引元组
4.2.删除clog不必要的数据
4.3.冻结旧txid
4.4.更新fsm和vm的统计信息

5.vaccum主要认为是清理dead tuple 和冻结事务id
1.从指定的表中获取每个表
2.获取表的ShareUpdateExclusiveLock锁,该锁允许从其他事务中读取
3.扫描所有页以获取所有dead tuple,并在必要时冻结tpule
4.删除指向相应dead tuple 的索引元组(如果存中活的)
5.为表的每个页执行以下处理,步骤6.7
6.删除dead tuple并重新分配页中的live tuple
7.更新目标表的相应的FSM和VM
8.如果最后一页没有任何元组,则截断最后一页
9.更新与vaccum处理的表的相关统计数据和系统目录
10.更新与vaccum处理相关的统计数据和系统目录
11.如果可能,删除不必要的文件和clog

 

Autovacuum 不会恢复死元组占用的磁盘空间。但是,运行VACUUM FULL命令会这样做。
不过,VACUUM FULL 有其性能含义。目标表在操作期间被独占锁定,甚至阻止对表的读取。
该进程还会制作表的完整副本,这在运行时需要额外的磁盘空间。我们建议不要运行 VACUUM FULL,
除非膨胀率非常高,并且查询受到严重影响。我们还建议使用最低数据库活动期。
Autovacuum 还使表的数据分布统计信息保持最新(它不会重建它们)。手动运行时,
ANALYZE命令实际上重建这些统计信息而不是更新它们。同样,
当统计信息已经通过常规自动清理进行最佳更新时重建统计信息可能会对系统资源造成不必要的压力。
您必须手动运行 ANALYZE 的时间是在将数据批量加载到目标表之后。
现有表中的大量(甚至数百)新行将显着扭曲其列数据分布
。新行将导致任何现有列统计信息过时。当查询优化器使用此类统计信息时,查询性能可能会非常缓慢。在这些情况下,
在数据加载后立即运行 ANALYZE 命令以完全重建统计信息是比等待自动清理启动更好的选择。


vaccum冻结处理:
lazy模式
eager模式
freeze操作会消耗大量的IO/CPU,对于不经常更新的表,可以合理增大,以减少冻结
autovaccum_freeze_max_age 2亿和vacuum_freeze_min_age的差值 50000000

autovaccum会定期调用几个autovaccum_worker进程,默认1分钟唤醒一次,由
autovaccum_naptime定义,并调用3个worker由{autovaccum_max_work}定义
触发条件:
vaccum threshold = vaccum base threshold + vacuum scale factor * number of tuple

当执行vaccum full时
1.Postgres首先获取表的AccessExclusiveLock锁并创建一个大小为8KB的新表,
AccessExclusiveLock锁不允许访问
2.将live tuple复制到新表中
3.删除旧文件,重建索引,并更新统计信息,FSM和VM

 

posted @ 2022-07-17 20:20  红丿领巾  阅读(108)  评论(0)    收藏  举报