PostgreSQL FSM解析

FSM(Free Space Map),即空闲空间管理,是干嘛的呢?在PostgreSQL的mvcc机制中,当数据块中进行insert、update、delete这些操作时,都会产生一个旧版本的数据,当vacuum时便会清理掉这些旧版本数据,那这样就会出现数据块中存在很多空闲的空间,如果能够将这些空间再次利用起来当然是很好的,不然新插入数据时继续分配一个新的数据块,那数据文件的膨胀速度就会非常快,因此PostgreSQL便通过FSM来实现这一功能。
但是要实现这一功能需要面临几个问题,空闲的空间能不能存下我即将插入的数据?怎样找到能插入数据的空闲数据块,一个个遍历吗?那这样的话,插入一条数据的速度便会大打折扣,我们来看看FSM是如何实现这一功能的。
FSM不存储数据块的精确空间,而是将一个数据块的大小分成256份,例如默认的一个数据块是8k,那么序号1表示0~31k大小,序号2表示32~63k大小,依此类推。。。为什么这样设置呢,因为256刚好等于2^8,这样我们在每个数据块中使用一个字节就能表示这个数据块剩余的空间了。
在FSM的内部,使用二元数结构(binary tree)存储,每个页节点(1 byte)对应一个HEAP PAGE的剩余空间(如果是多级FSM,则也可以表示lower level FSM page的ROOT 节点的 VALUE),非页节点存储下级节点(FSM NODE OR FSM page)的大值。其结构如图所示(详细见:src/backend/storage/freespace/README)
在这里插入图片描述
同时需要注意一点,FSM文件不是在创建表的时候就会生成,例如:

bill=# create table t2(id int);
CREATE TABLE
bill=# select oid,relname from pg_class where relname='t2';
  oid  | relname 
-------+---------
 17554 | t2
(1 row)
pg12@oracle-> ls -l 17554*
-rw------- 1 pg12 pg12 0 Sep 18 00:50 17554

可以看到并没有fsm文件,而是在插入数据或者进行vacuum操作的时候会生成。

bill=# insert into t2 select generate_series(1,1000);
INSERT 0 1000
pg12@oracle-> ls -l 17554*
-rw------- 1 pg12 pg12 40960 Sep 18 00:50 17554
-rw------- 1 pg12 pg12 24576 Sep 18 00:50 17554_fsm

可以看到已经生成了一个17554_fsm的文件。

发布了70 篇原创文章 · 获赞 5 · 访问量 3150

猜你喜欢

转载自blog.csdn.net/weixin_39540651/article/details/100933665
FSM