学习制作网页的网站,深圳市住房建设部官方网站,cmsinitiatingoccupancyfraction,网站营销 海外专栏内容#xff1a;postgresql内核源码分析个人主页#xff1a;我的主页座右铭#xff1a;天行健#xff0c;君子以自强不息#xff1b;地势坤#xff0c;君子以厚德载物#xff0e; 目录
前言
表数据膨胀的由来
什么时候产生膨胀
首先是update
还有delete
如何消… 专栏内容postgresql内核源码分析个人主页我的主页座右铭天行健君子以自强不息地势坤君子以厚德载物 目录
前言
表数据膨胀的由来
什么时候产生膨胀
首先是update
还有delete
如何消除膨胀
结尾 前言
本文是基于postgresql 15的代码进行分析解读演示是在centos8系统上进行。
在我们使用postgresql数据库时总会产生一些数据膨胀导致查询变慢索引失效为什么会有数据膨胀呢产生后我们怎么做才能让数据库恢复正常呢 表数据膨胀的由来
话说数据库的四大特性ACIDpostgresql采用了一种MVCC(Multi Version Concurrency Control)机制来保证事务的原子性和隔离性。 那什么是MVCC呢简单说就是利用事务号递增性来标识tuple的新旧版本达到不同事务内看到的tuple隔离下面我们用一个例子来看一下 查看一张表的当前数据 postgres# select ctid,xmin,xmax,id from t1; ctid | xmin | xmax | id ----------------------- (0,1) | 1699 | 0 | 1 (0,2) | 1700 | 0 | 2 (2 rows) 我们在一个事务中执行更新并回滚 postgres*begin; BEGIN postgres*# select txid_current(); txid_current -------------- 1702 (1 row) postgres*update t1 SET namea where id1; UPDATE 1 postgres*rollback; ROLLBACK 我们在插入数据 insert into t1(id) values(3); insert into t1(id) values(4); postgres# select ctid,xmin,xmax,id from t1; ctid | xmin | xmax | id ----------------------- (0,1) | 1699 | 1702 | 1 (0,2) | 1700 | 0 | 2 (0,4) | 1703 | 0 | 3 (0,5) | 1704 | 0 | 4 (4 rows) 发现ctid为03的位置被跳过了因为有一个id1的tuple版本占了只是它可见性判断时被判定为不可见所以我们看不到它但确实是占用了一个位置。 什么时候产生膨胀 那些常见情况下为产生多版本数据呢 首先是update
我们来看一下update的演示
我们update一条数据后它的位置变到了最后说明又一条旧版本详细表的update代码解析详见我的专栏 postgres# update t1 SET namea where id1; UPDATE 1 postgres# select ctid,xmin,xmax,id from t1; ctid | xmin | xmax | id ----------------------- (0,2) | 1700 | 0 | 2 (0,4) | 1703 | 0 | 3 (0,5) | 1704 | 0 | 4 (0,6) | 1705 | 0 | 1 (4 rows) 还有delete
这里不会产生多版本但是delete后tuple并不会从表里真正删掉而是打了一个标记这样做的目的其它和多版本是一致的因为可能还有其它事务在引用。
下面我们看一下例子 postgres# delete from t1 where id 1; DELETE 1 postgres# select ctid,xmin,xmax,id from t1; ctid | xmin | xmax | id ----------------------- (0,2) | 1700 | 0 | 2 (0,4) | 1703 | 0 | 3 (0,5) | 1704 | 0 | 4 (3 rows) postgres# insert into t1(id) values(5); INSERT 0 1 postgres# select ctid,xmin,xmax,id from t1; ctid | xmin | xmax | id ----------------------- (0,2) | 1700 | 0 | 2 (0,4) | 1703 | 0 | 3 (0,5) | 1704 | 0 | 4 (0,7) | 1707 | 0 | 5 (4 rows) 我们delete后又insert发现空闲06没有被利用而是从07开始 如何消除膨胀
postgresql在运行过程中采用了两种方式
一是页面裁剪;
二是autovacuum;
那它们是如何做的呢请看本专栏内容。 结尾
作者邮箱studysenllang.onaliyun.com 如有错误或者疏漏欢迎指出互相学习。
注未经同意不得转载