系统表中的隐藏字段
oid
oid对象标识符,作为各种系统表的主键,用户创建的表默认无此隐藏列.
finance=# select oid,relname from pg_class where relname ='client';
oid | relname
-------+---------
24580 | client
(1 row)
如上client表对应的oid为24580
使用案例1,找到指定表对应的物理文件(finance库下的client表对应的物理文件)
--1.查看finance库对应的oid
finance=# select oid,datname from pg_database;
oid | datname
-------+-----------
5 | postgres
16395 | finance
1 | template1
4 | template0
(4 rows)
postgres=# show data_directory;
data_directory
-----------------------------
/opt/software/postgres/data
(1 row)
postgres=# \q --退出数据库
cd /opt/software/postgres/data
cd base
ls
1 4 5 16395(目录为finance数据库对应目录)
cd 16395
ls |grep 24580
24580(为client表对应的物理文件)
ctid
finance=# select ctid,c_name from client;
ctid | c_name
--------+--------
(0,1) | 张一
(0,2) | 张二
(0,3) | 张三
(0,4) | 张四
(0,5) | 张五
(0,6) | 张六
(0,7) | 张七
(0,8) | 张八
(0,9) | 张九
(0,10) | 李一
从上可以看出,ctid由俩个数字组成,第一个数字表示物理块号,第二个数字表示物理块中的行号.
postgres的多版本并发控制
postgresql中是通过把旧数据留在数据文件中,新插入一条数据来实现多版本功能.
旧数据通过vacuum方式进行释放,postgres默认打开了autovacuum,当时旧数据达到一定量时,postgres会自动执行vacuum操作.
事务ID : xid
无效事务ID:0
系统初始化时的事务ID:1
冻结的事务ID:2
即数据库正常的事务ID是从3开始.
物理存储结构
postgresql表数据删除和更新时都会产生旧版本数据,这些旧版本数据是通过vacuum操作进行清理,这时数据块中就会产生空闲空间.再往表中插入数据时,最好的办法是继续使用这些空闲空间存放这些新插入的数据.