大佬教程收集整理的这篇文章主要介绍了postgresql dead_tuple和live_tuple,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
--PG并没有像
Oracle那样的undo来存放旧版本;而是将旧版本直接存放于relation文件中。那么带来的问题就是dead tuple过多,导致relation文件不断增大而带来空间膨胀问题。 --
为了解决这个问题,
PG中引入了vacuuR_349_11845@后台进程,专门来清理这些dead tuple,并回缩空间 --创建测试数据
POSTGRes=#
create table t (ID int,
name varchar(50)
); create table POSTGRes=# insert into t
SELEct ID,'rudy'|| ID from generate_serIEs(1,100) ID; --查询统计信息,
可知n_live_tup为100,n_dead_tup为0
POSTGRes=#
SELEct
relname,n_live_tup,n_dead_tup from
pg_stat_
user_tables where
relname='t'; -[ RECORD 1 ]-----+------- relID | 88968 @R_
675_3296@ | public
relname | t seq_scan | 0 seq_tup_read | 0
idx_scan | IDx_tup_fetch | n_tup_ins | 100 n_tup_upd | 0 n_tup_del | 0 n_tup_hot_upd | 0 n_live_tup | 100 n_dead_tup | 0
last_vacuum |
last_autovacuum | last_analyze | last_autoanalyze |
VACUUM_count | 0 auto
VACUUM_count | 0 analyze_count | 0 autoanalyze_count | 0 --由以下
可知,没更新一次,n_dead_tup加1
POSTGRes=#
update t set name='dead tuple' where ID=1;
updatE 1
POSTGRes=#
SELEct
relname,n_dead_tup from
pg_stat_
user_tables where
relname='t';
relname | n_live_tup | n_dead_tup ---------+------------+------------ t | 100 | 1
POSTGRes=#
update t set name='dead tuple 2' where ID=1;
updatE 1
POSTGRes=#
SELEct
relname,n_dead_tup from
pg_stat_
user_tables where
relname='t';
relname | n_live_tup | n_dead_tup ---------+------------+------------ t | 100 | 2 --每删除一次数据 n_live_tup 和 n_dead_tup 均加1
POSTGRes=#
delete from t where ID<10;
deletE 9
POSTGRes=#
SELEct
relname,n_dead_tup from
pg_stat_
user_tables where
relname='t';
relname | n_live_tup | n_dead_tup ---------+------------+------------ t | 91 | 11 --此时的空间回收可以使用
VACUUM 进行
POSTGRes=#
VACUUM (verbose,analyze ) t; INFO:
VACUUMing "public.t" INFO: sc
Anned index "t_ID_IDx" to remove 9 row versions DETAIL: cpu 0.00s/0.00u sec elapsed 0.00 sec. INFO: "t": removed 9 row versions in 1 pages DETAIL: cpu 0.00s/0.00u sec elapsed 0.00 sec. INFO: index "t_ID_IDx" Now contains 101 row versions in 2 pages DETAIL: 9 index row versions were removed. 0 index pages have been
deleted,0 are currently reusable. cpu 0.00s/0.00u sec elapsed 0.00 sec. INFO: "t": found 11 removable,101 nonremovable row versions in 1 out of 1 pages DETAIL: 0 dead row versions c
Annot be removed yet. There were 2 unused item pointer
s. 0 pages are entirely empty. cpu 0.00s/0.00u sec elapsed 0.00 sec. INFO: analyzing "public.t" INFO: "t": sc
Anned 1 of 1 pages,containing 101 live rows and 0 dead rows; 101 rows in sample,101 estimated @R_577_1
0586@l rows
VACUUM POSTGRes=#
SELEct
relname,n_dead_tup,
last_vacuum,last_analyze from
pg_stat_
user_tables where
relname='t';
relname | n_live_tup | n_dead_tup |
last_vacuum | last_analyze ---------+------------+------------+-------------------------------+------------------------------- t | 101 | 0 | 2015-11-23 22:32
:17.970209-08 | 2015-11-23 22:32
:17.972155-08 --不带表名的
VACUUM会回收统计系统中的所有的表,此时系统会有大量的io操作,故不要
在数据库繁忙时操作
VACUUM (verbose,analyze ) ; -- 注意
VACUUM full会锁表和索引,而且是“AccessExclusiveLock”级别的。其实
VACUUM full会重建整个表,这个的功能实现在cluster.c文件中,因
为其行业相当于是一个cluster重建的一个变种
VACUUM的功能 1.回收空间 这个通常是大家
最容易想起来的功能。回收空间,将dead tuple清理掉。但是已经分配的空间,一般不会释放掉。除非做
VACUUM full,但
是需要exclusive lock。 一般不太建议,因为如果表最终还是会涨到这个高水位上,经常做
VACUUM full意义不是非常大。一般合理设置
VACUUM参数,进行常规
VACUUM也就够了。 2.冻结tuple的xID PG会在每条记录(tuple)的header中,存放xmin,xmax信息(增删改事务ID)。
transactionID的最大值为2的32次,即无符整形来表示。当
transactionID超过此最大值后,会循环使用。 这会带来一个问题:就是最新事务的
transactionID会小于老事务的
transactionID。如果这种情况发生后,PG就没有办法按
transactionID来区分事务的先后,也没有办法实现MVCC了。 因此PG用
VACUUM后台进程,按一定的周期和算法触发
VACUUM动作,将过老的tuple的header中的事务ID进行冻结。冻结事务ID,即将事务ID设置为
“2”(“0”表示无效事务ID;“1”表示bootstrap, 即初始化;“3”表示最小的事务ID)。PG认为被冻结的事务ID比任何事务都要老。这样就不
会出现上面的这种情况了。 3.更新统计信息
VACUUM analyze时,会更新统计信息,让PG的pl
Anner能够算出更准确的执行计划。auto
VACUUM_analyze_threshold和auto
VACUUM_analyze_scale_factor参数可以控制analyze的触发的频率。 4.更新visibility map
在PG中,有一个visibility map用来标记那些page中是没有dead tuple的。这有两个好处,一是当
VACUUM进行scan时,直接可以跳过这些page。 二是进行index-only scan时,可以先检查下visibility map。这样减少fetch tuple时的可见性判断,从而减少IO操作,提高性能。 另外visibility map相对整个relation,还是小很多,可以cache到内存中。 自动
VACUUM配置 自动
VACUUM的执行直接由auto
VACUUM参数值决定,默认值是on。 log_auto
VACUUM_min_duration:默认值为-1,关闭
VACUUM的日志记录,配置为0表示记录auto
VACUUM的所有log。参数设置为正整数表示对于在此时间内完成的
VACUUM操作不进行log记录,如果没能完成,则记录超出时间内的log。该参数对于了解对象执行
VACUUM操作的时间非常有用。 auto
VACUUM_max_workers:最大的auto
VACUUM进程的数量,默认值为3。参数大小的配置主要依据系统当前负载和资源。对于系统负载较重的情况,建议开启少量的进程为好,反之,空闲时间可以采用较大
值的方式。 auto
VACUUM_naptime:检查数据库的时间间隔。
默认为1分钟。
autovacuum_vacuuR_349_11845@_threshold:参数表示执行auto
VACUUM操作之前,对单个表中记录
执行DML操作的最少行数。达到该行数时自动激活auto
VACUUM操作。该参数针
对数据库中的所有表,还可以通过对单个表配置不同的值来改变相应表的auto
VACUUM操作。默认值是50。 auto
VACUUM_analyze_threshold:激活自动analyze操作的最小行数。默认值50。机制与上面相同。
autovacuum_vacuuR_349_11845@_scale_factor:该参数采用百分比的方式设定阀值。默认值为20%,当DML涉及的数据量大于某个表的20%时,自动触发auto
VACUUM操作。同样可以通过对单个表进行阀值设定。 auto
VACUUM_analyze_scale_factor:机制与上面相同,到达阀值是自动激活analyze操作。同样可以通过对单个表进行阀值设定。 auto
VACUUM_freeze_max_age:为防止事务ID的重置,在启用
VACUUM操作之前,表的
pg_class .relfroZenxID字段的最大值,
默认为200万。
autovacuum_vacuuR_349_11845@_cost_delay:auto
VACUUM进程的时间延迟限制,默认值是20ms。对于单个表同样适用。
autovacuum_vacuuR_349_11845@_cost_limit:auto
VACUUM进程的开销延迟限制,默认值是-1,表示不进行开销限制,系统将会直接依据
VACUUM_cost_limit参数管理
VACUUM的开销。对于单个表同样适用。
大佬总结
以上是大佬教程为你收集整理的postgresql dead_tuple和live_tuple全部内容,希望文章能够帮你解决postgresql dead_tuple和live_tuple所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。