重庆思庄Oracle、KingBase、PostgreSQL、Redhat认证学习论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 77|回复: 0
打印 上一主题 下一主题

pg中的系统列ctid

[复制链接]
跳转到指定楼层
楼主
发表于 2026-7-12 20:21:36 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
pg中每个表都有几个系统隐藏列:tableoid, xmin, xmax,cmin,cmax,ctid。其中tableoid表示表的oid,cmin、cmax、xmin和xmax是mvcc的实现有关,今天主要来看下ctid。

ctid:
ctid表示行版本在表中的物理位置。它属于对象标识符类型(oid,Object Identifier Types),是一种行标识符,它的数据使用的元组标识符(tid,tuple identifier)。
元组ID是一对(块号,块内的元组索引),用于标识当前行的物理位置。


postgres=# select tableoid, xmin, xmax,cmin,cmax,ctid from tb1;
tableoid | xmin | xmax | cmin | cmax | ctid
----------+------+------+------+------+-------
    16384 |  487 |  550 |    0 |    0 | (0,3)
    16384 |  487 |    0 |    0 |    0 | (0,4)
(2 行记录)



如果想要根据ctid查询,我们可以使用单引号括起来的类型值格式进行查询.
postgres=# select tableoid, xmin, xmax,cmin,cmax,ctid from tb1 where ctid='(0,3)';
tableoid | xmin | xmax | cmin | cmax | ctid
----------+------+------+------+------+-------
    16384 |  487 |  550 |    0 |    0 | (0,3)
(1 行记录)

这一点还是比较有用的,有时候我们可能会遇到页面损坏的异常,报错信息可能如下:
ERROR:  invalid page in block 1877 of relation base/16402/45678


其中block 1877,就是对应ctid的块号。在主从环境下,当主库发生页损坏,我们在从库上执行读取操作通ctid过滤把损坏的数据找回来。还可以根据块号,定位具体损坏的数据文件等等。


此外,我们知道,数据文件的块的大小,默认是8K,我们还可以根据表数据包含的块数,计算表占的存储大小(块数*8k)。


借助系统视图pg_class,其中relpages,reltuples分别代表块数,记录数。但是这个值不一定是准确的,在查看之前,可以先执行analyze tablename
命令。


postgres=# create table t1 (id int,c_name varchar(100));
CREATE TABLE
postgres=# insert into t1 select generate_series(1,100000),'zsan';
INSERT 0 100000
postgres=# select relpages,reltuples from pg_class where relname = 't1';
relpages | reltuples
----------+-----------
        0 |         0
(1 行记录)


postgres=# analyze t1;
ANALYZE
postgres=# select relpages,reltuples from pg_class where relname = 't1';
relpages | reltuples
----------+-----------
      541 |    100000
(1 行记录)


可以看到表中包含541个数据块,我们再看下表的大小是不是8*541=4328


postgres=# select pg_size_pretty(pg_relation_size('t1'));
pg_size_pretty
----------------
4328 kB
(1 行记录)




postgres=# select 541*8;
?column?
----------
     4328
(1 行记录)


总结
ctid是pg表的系统隐藏列,它表示行版本在表中的物理位置。它属于对象标识符类型(oid,Object Identifier Types),是一种行标识符,它的数据使用的元组标识符(tid,tuple identifier)。元组ID是一对(块号,块内的元组索引),用于标识当前行的物理位置。我们可以根据ctid查询表数据,在数据页损坏的场景,可以帮助定位具体损坏的数据文件以及恢复数据。








分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 支持支持 反对反对
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|重庆思庄Oracle、Redhat认证学习论坛 ( 渝ICP备12004239号-4 )

GMT+8, 2026-7-24 00:16 , Processed in 0.263961 second(s), 22 queries .

重庆思庄学习中心论坛-重庆思庄科技有限公司论坛

© 2001-2020

快速回复 返回顶部 返回列表