![](https://i-blog.csdnimg.cn/direct/3721b250999545edaf599600d0c5a7da.jpeg?x-oss-process=image/resize,m_fixed,h_224,w_224)
PostgreSQL存储原理
文章平均质量分 79
PostgreSQL内部存储原理解析、源码研究。
南風_入弦
这个作者很懒,什么都没留下…
展开
-
08-PG清理——Autovacuum
vacuum 可以清理死元组,但多久调用一次vacuum是很难界定的,对于频繁更新的表,我们需要及时的vacuum,避免积累过多的死元组而致使数据库性能下降,而且死元组过多的积累必将导致下次vacuum执行缓慢;另外,如果表不频繁更新,而频繁的执行vacuum会造成不必要的资源浪费,为此PostgreSQL引入autovacuum机制,由postmaster 拉起一个单独的进程autovacuum来根据表的死元组的阈值来自动vacuum。原创 2024-08-03 09:30:23 · 849 阅读 · 0 评论 -
06-PG存储——HOT
引入HOT后,在更新一行时,如果更新的行和旧的行在同一个页面上(可以配置较小的fillfactor参数,给更新留足空间),那么就不会再修改改行的索引记录,而是在旧元组标记为Heap Hot Updated,而同页面内的新行标记为Heap Only Tuple,两个标志位分别保存在自己元组的t_infomask2字段中。我们知道,PG删除行或更新行不会真正的清除旧的记录,而是将其标记为删除,在事务中不可见,但是数据的变更会影响索引的引用,因为索引的叶块保存的是索引键值(列)和键值所在的块号和偏移量。原创 2024-08-03 09:29:39 · 348 阅读 · 0 评论 -
10-PG清理——VACUUM FULL
然后,vacuuming可以删除过时的元组,并为已经存在的页面中的新元组释放一些空间。对于大型对象,它的开销可能太大,因此该扩展还提供了另一个名为pgstattuple_approx的函数,该函数跳过可见性映射中跟踪的页,以显示近似的数字。因此,一种常见的方法是在不同的系统之间分摊负载:在主服务器上保持快速OLTP查询,并将所有OLAP事务定向到副本。如果表或索引文件的大小增加了,vacuum可以清理页中的一些空间,但很少能减少页的数量。在某些情况下,长事务是应用程序或驱动程序bug的结果,而不是必须的。原创 2024-08-03 09:30:38 · 629 阅读 · 0 评论 -
07-PG清理——VACUUM
PG采用了和其他RDBMS完全不同的方式实现了多版本并发控制(简称MVCC)。在Oracle或InnoDB中,当我们删除或更新一条记录时,数据库会将删除的记录放到undo段中,undo段中的记录前镜像保证了数据库的一致性。这种实现方式经常会遇到两个问题,一个是在Oracle 常见的01555错误,遇到这种错误DBA一般会调大undo_retention参数或增大UNDO表空间;另一个问题就是delete大量数据时可能会造成其他事务查询效率降低,而回滚delete操作更是让DBA头疼。原创 2024-08-03 09:30:06 · 1118 阅读 · 0 评论 -
09-PG清理——冻结
在PG中,事务ID(XID)为无符号的32bit数字,所以理论上事务ID最大值为2^32,约为42亿,消耗完成之后就会从头开始分配,0,1,2三个XID为内部XID,新的XID从3开始。原创 2024-08-02 12:07:55 · 581 阅读 · 0 评论 -
04-PG存储——Tuple提示位
四个提示位分别为xmin_commited、xmin_invalid、xmax_commited和xmax_invalid。可以在/soft/postgresql-14.6/src/include/access/htup_details.h中看到这四个提示位信息/**/ 上述源码描述了infomask不同位代表的不同信息。现在我们只关注四个提示位。原创 2024-08-02 12:02:05 · 543 阅读 · 0 评论 -
05-PG存储——页面修剪
按照fillfactor为75%,我们插入3条记录就会把页面占满 ( 8192*0.75)/2028 =3.03。2028 为4字节的id列,2000字节的name列和24字节的元组首部大小。关于页面修剪的源码位于/soft/postgresql-14.6/src/backend/access/heap/pruneheap.c。页面修剪是指在读取或更新堆表页面时,自动删除在任何快照中都不再可见的元组(即xmax<snapshot.xmin)。此时页面已经无法再存放新数据了,下次update将触发页面裁剪。原创 2024-08-02 12:02:38 · 222 阅读 · 0 评论 -
02-PG存储——表空间和数据文件
还有一个不常用的分支为init分支,后缀为_init,对于在建表时指定unlogged参数的表和对应的索引,这些表的所以操作都不会写入wal日志,这样存储可以提高效率,但是在发生故障时,您将无法恢复一致的数据。最开始时,一个表创建时,只会有一个名为oid的主分支,随着表数据越来越多,当主分支超过1G时(编译时由–with-segsize 指定),主分支会另创建一个文件,名为oid.1,此文件再超过1G时,创建oid.2。随着表数据增多,也会创建_fsm和vm分支,增长规则也会跟主分支一样。原创 2024-08-02 12:00:11 · 247 阅读 · 0 评论 -
03-PG存储——Page和Tuple
每个page(也叫block)包含page header、Iterm Pointers、free space、tuples、special space。上面就是/soft/postgresql-14.6/src/include/storage/bufpage.h 中给出的page页结构图,我们也可以使用pageinspect插件查看PostgreSQL中的页结构8192标记为特殊空间,它可以包含访问方法想存放的任何东西。原创 2024-08-02 12:00:56 · 562 阅读 · 0 评论 -
01-PG存储——Cluster和Database
数据库集簇初始化后,会创建两个表空间pg_default和pg_global,这两个表空间分别对应base和global目录。pg_default为默认表空间,初始化集簇后,如果没有特殊指定,我们创建的数据库和表等对象皆存放至此;Cluster意为数据库集簇,这个和Oracle的集群概念是完全不一样的,一般我们在执行initdb后,会在PGDATA环境变量指定的目录下生成一系列的目录和文件,这些文件保证PostgreSQL实例能正常启动和运行,我们成这些文件的集合为数据库集簇。原创 2024-08-02 11:59:30 · 639 阅读 · 0 评论