代码改变世界

postgresql在何时创建表和索引文件

  abce  阅读(1187)  评论(0编辑  收藏  举报

oracle中有个特性:deferred segment createion。那么在postgresql中,在创建表或者索引的时候,磁盘上对应的文件是立即创建还是插入第一行数据的时候创建呢?

来做个简单的测试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
postgres=# create table t1(a int);
CREATE TABLE
postgres=# select pg_relation_filepath('t1');
 pg_relation_filepath
----------------------
 base/13878/75000
(1 row)
 
postgres=# \! oid2name -d postgres -t t1
From database "postgres":
  Filenode  Table Name
----------------------
     75000          t1
postgres=#

 

现在我们看看文件是否已经被创建

1
2
$ ls -la $PGDATA/base/13878/75000
-rw------- 1 postgres postgres 0 Oct 31 19:18 /pg/11/data/base/13878/75000

文件已经被创建,但是是空文件。

 

但是还没有创建visibility map和free space map文件:

1
2
$ ls -la $PGDATA/base/13878/75000*
-rw------- 1 postgres postgres 0 Oct 31 19:18 /pg/11/data/base/13878/75000

  


如果我们在这个空表上创建一个索引会发生什么呢?

1
2
3
4
5
6
7
8
9
10
postgres=# create index i1 on t1 (a);
CREATE INDEX
postgres=# select pg_relation_filepath('i1');
 pg_relation_filepath
----------------------
 base/13878/75003
(1 row)
 
postgres=# \! ls -la $PGDATA/base/13878/75003
-rw------- 1 postgres postgres 8192 Oct 31 19:27 /pg/11/data/base/13878/75003

 

索引文件立即被创建了,但是不是一个空文件。恰好是一个page的大小。使用pageinspect我们可以确定这个页只是存放了元数据。

1
2
3
4
5
6
7
8
9
10
11
postgres=# create extension pageinspect;
CREATE EXTENSION
postgres=# SELECT * FROM bt_metap('i1');
 magic  | version | root | level | fastroot | fastlevel | oldest_xact | last_cleanup_num_tuples
--------+---------+------+-------+----------+-----------+-------------+-------------------------
 340322 |       3 |    0 |     0 |        0 |         0 |           0 |                      -1
(1 row)
 
postgres=# SELECT * FROM bt_page_stats('i1', 0);
ERROR:  block 0 is a meta page
postgres=#

  

到此为止,还有一个问题,free space map和visibility map文件是什么时候创建的呢?是在第一个插入之后?

1
2
3
4
5
postgres=# insert into t1 (a) values (1);
INSERT 0 1
postgres=# \! ls -la $PGDATA/base/13878/75000*
-rw------- 1 postgres postgres 8192 Oct 31 19:33 /pg/11/data/base/13878/75000
postgres=#

  

显然不是。正确的答案是在vacuum之后。

1
2
3
4
5
6
7
postgres=# vacuum t1;
VACUUM
postgres=# \! ls -la $PGDATA/base/13878/75000*
-rw------- 1 postgres postgres  8192 Oct 31 19:33 /pg/11/data/base/13878/75000
-rw------- 1 postgres postgres 24576 Oct 31 19:34 /pg/11/data/base/13878/75000_fsm
-rw------- 1 postgres postgres  8192 Oct 31 19:34 /pg/11/data/base/13878/75000_vm
postgres=#

  

 

编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示