暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL之base和global目录完全解析

ClickHouse周边 2021-06-08
1494

1. base目录 

        对于集簇里的每个数据库,在$PGDATA/base里都有一个子目录对应,子目录的名字为该数据库在 pg_database里的 OID。
#查看各个数据库的oid

        每一张表的数据(大部分)又是放在 $PGDATA/base/{dboid}/{relfilenode} 这个文件里面,relfilenode一般情况下和和tboid一致,但有些情况下也会变化,如TRUNCATE、REINDEX、CLUSTER以及某些形式的ALTER TABLE。

#查询relowner

#查询pg_class

包含文件

        在$PGDATA/base/{dboid}中通常会包含三种文件:例如16395、16395_fsm、16395_vm,分别是该数据库对应主表数据文件或索引数据文件、以_fsm(Free Space Mapping)后缀文件,其对应的空闲空间映射文件、以_vm(visibility map)后缀文件,其对应的可见性映射文件。

数据文件

        在表或者索引超过1GB之后,它就被划分成1GB大小的段。第一个段的文件名和文件节点相同,随后的段被命名为 filenode.1、filenode.2等等。这样的安排避免了在某些有文件大小限制的平台上的问题。

TOAST表

        如果一个表的列中可能存储相当大的项,那么该表就会有个与之相关联的TOAST(The Oversized-Attribute Storage Technique)表,它用于存储无法保留在在表行中的域值的行外存储。如果表有TOAST表,该表的pg_class.reltoastrelid链接到它的TOAST表。

TOAST表的存储策略

  • PLAIN:避免压缩和行外存储。只有那些不需要TOAST策略就能存放的数据类型允许选择(例如int类型),而对于text这类要求存储长度超过页大小的类型,是不允许采用此策略的。
  • EXTENDED:允许压缩和行外存储。一般会先压缩,如果还是太大,就会行外存储。
  • EXTERNA:允许行外存储,但不许压缩。类似字符串这种会对数据的一部分进行操作的字段,采用此策略可能获得更高的性能,因为不需要读取出整行数据再解压。
  • MAIN:允许压缩,但不许行外存储。不过实际上,为了保证过大数据的存储,行外存储在其它方式(例如压缩)都无法满足需求的情况下,作为最后手段还是会被启动。因此理解为:尽量不使用行外存储更贴切。

TOAST字段

  • chunk_id:用来表示特定TOAST值的OID,可以理解为具有同chunk_id值的所有行组成原表的TOAST字段的一行数据。
  • chunk_seq:用来表示该行数据在整个数据中的位置。
  • chunk_data:实际存储的数据。#创建测试表
#创建测试表,#查看toast表详情

#插入数据,查询pg_toast.pg_toast_16437

        可以发现在testtb3中数据长度为640000,但是在pg_toast.pg_toast_16393中所有行加起来1996*3+1381=7369远小于640000,是因为toast做了数据压缩,而且toast每行最大长度为1996。‬

FSM文件

        每一个堆和索引关系(除了哈希索引)都有一个空闲空间映射(FSM)来保持对关系中可用空间的跟踪。它伴随着主关系数据被存储在一个独立的关系分支中,以关系的文件节点号加上一个_fsm后缀命名。例如,如果一个关系的文件节点是12345,那么FSM被存储在一个名为12345_fsm的文件中,该文件与主关系文件在同一个目录中。

        空闲空间映射被组织成一棵FSM页面的树。底层FSM页面存储了在每一个堆(或索引)页面中可用的空闲空间,对于每一个这样的页面使用一个字节来表示。上层FSM页面则聚集来自于下层页面的信息。

        在每一个FSM页面中是一个二叉树,存储在一个数组中,每一个节点一个字节。每个叶节点表示一个堆页面或者一个下层FSM页面。在每一个非叶节点中存储了它孩子节点中的最大值。因此叶节点中的最大值被存储在根中。

        但是,在新建表时不会产生_fsm和_vm文件,直到pg执行VACUUM操作时,或者是第一次要使用_fsm或_vm文件时才会生成。

        pg提供了一个插件pg_freespacemap可供我们查询FSM,该插件提供了一种方法来检查空闲空间映射(FSM)。它提供了一个称为pg_freespace的函数,或者准确地说是两个重载的函数。这些函数显示空闲空间映射中为一个给定页面所记录的值,或者显示关系中所有页面的记录值。
        默认情况下,使用仅限于超级用户和pg_stat_scan_tables 角色的成员。可以使用GRANT给其他人授予访问权限。

VM文件

        每一个堆关系都有一个可见性映射(VM)用来跟踪哪些页面只包含已知对所有活动事务可见的元组,它也跟踪哪些页面只包含未被冻结的元组。

        pg提供了一个插件pg_visibility可供我们查询VM,该插件提供了一种方式来检查一个表的可见性映射(VM)以及页级别的可见性信息。它还提供了函数来检查可见性映射的完整性以及强制重建可见性映射。

2. global目录 
        存储全局的系统表信息和全局控制信息。
  1. pg_control
    用于存储全局控制信息
  2. pg_filenode.map
    用于将当前目录下系统表的OID与具体文件名进行硬编码映射(每个用户创建的数据库目录下也有同名文件)。
  3. pg_internal.init
    用于缓存系统表,加快系统表读取速度(每个用户创建的数据库目录下也有同名文件)。
  4. 全局系统表文件
    数字命名的文件,用于存储系统表的内容。
    它们在pg_class里的relfilenode都为0,是靠pg_filenode.map将OID与文件硬编码映射。
    (注:不是所有的系统表的relfilenode都为0)
    select oid,relname,pg_relation_filepath(oid) from pg_class where relfilenode=0 order by 1;
    oid | relname | pg_relation_filepath
    -------+-----------------------------------------+----------------------
    1136 | pg_pltemplate | global/1136
    1137 | pg_pltemplate_name_index | global/1137
    1213 | pg_tablespace | global/1213
    1214 | pg_shdepend | global/1214
    1232 | pg_shdepend_depender_index | global/1232
    1233 | pg_shdepend_reference_index | global/1233
    1247 | pg_type | base/13593/1247
    1249 | pg_attribute | base/13593/1249
    1255 | pg_proc | base/13593/1255
    1259 | pg_class | base/13593/1259
    1260 | pg_authid | global/1260
    1261 | pg_auth_members | global/1261
    1262 | pg_database | global/1262
    2396 | pg_shdescription | global/2396
    2397 | pg_shdescription_o_c_index | global/2397
    2658 | pg_attribute_relid_attnam_index | base/13593/2658
    2659 | pg_attribute_relid_attnum_index | base/13593/2659
    2662 | pg_class_oid_index | base/13593/2662
    2663 | pg_class_relname_nsp_index | base/13593/2663
    2671 | pg_database_datname_index | global/2671
    2672 | pg_database_oid_index | global/2672
    2676 | pg_authid_rolname_index | global/2676
    2677 | pg_authid_oid_index | global/2677
    2690 | pg_proc_oid_index | base/13593/2690
    2691 | pg_proc_proname_args_nsp_index | base/13593/2691
    2694 | pg_auth_members_role_member_index | global/2694
    2695 | pg_auth_members_member_role_index | global/2695
    2697 | pg_tablespace_oid_index | global/2697
    2698 | pg_tablespace_spcname_index | global/2698
    2703 | pg_type_oid_index | base/13593/2703
    2704 | pg_type_typname_nsp_index | base/13593/2704
    2836 | pg_toast_1255 | base/13593/2836
    2837 | pg_toast_1255_index | base/13593/2837
    2846 | pg_toast_2396 | global/2846
    2847 | pg_toast_2396_index | global/2847
    2964 | pg_db_role_setting | global/2964
    2965 | pg_db_role_setting_databaseid_rol_index | global/2965
    2966 | pg_toast_2964 | global/2966
    2967 | pg_toast_2964_index | global/2967
    3455 | pg_class_tblspc_relfilenode_index | base/13593/3455
    3592 | pg_shseclabel | global/3592
    3593 | pg_shseclabel_object_index | global/3593
    4060 | pg_toast_3592 | global/4060
    4061 | pg_toast_3592_index | global/4061
    4171 | pg_toast_1247 | base/13593/4171
    4172 | pg_toast_1247_index | base/13593/4172
    4175 | pg_toast_1260 | global/4175
    4176 | pg_toast_1260_index | global/4176
    4177 | pg_toast_1262 | global/4177
    4178 | pg_toast_1262_index | global/4178
    4179 | pg_toast_1136 | global/4179
    4180 | pg_toast_1136_index | global/4180
    4181 | pg_toast_6000 | global/4181
    4182 | pg_toast_6000_index | global/4182
    4183 | pg_toast_6100 | global/4183
    4184 | pg_toast_6100_index | global/4184
    4185 | pg_toast_1213 | global/4185
    4186 | pg_toast_1213_index | global/4186
    6000 | pg_replication_origin | global/6000
    6001 | pg_replication_origin_roiident_index | global/6001
    6002 | pg_replication_origin_roname_index | global/6002
    6100 | pg_subscription | global/6100
    6114 | pg_subscription_oid_index | global/6114
      6115 | pg_subscription_subname_index           | global/6115
    复制
      pgdata
      ├── global # under global, all the filenode is hard-code
      │ ├── 1136 # pg_pltemplate
      │ ├── 1137 # pg_pltemplate_name_index
      │ ├── 1213 # pg_tablespace
      │ ├── 1214 # pg_shdepend
      │ ├── 1232 # pg_shdepend_depender_index
      │ ├── 1233 # pg_shdepend_reference_index
      │ ├── 1260 # pg_authid
      │ ├── 1261 # pg_auth_members
      │ ├── 1262 # pg_database
      │ ├── 2396 # pg_shdescription
      │ ├── 2397 # pg_shdescription_o_c_index
      │ ├── 2671 # pg_database_datname_index
      │ ├── 2672 # pg_database_oid_index
      │ ├── 2676 # pg_authid_rolname_index
      │ ├── 2677 # pg_authid_oid_index
      │ ├── 2694 # pg_auth_members_role_member_index
      │ ├── 2695 # pg_auth_members_member_role_index
      │ ├── 2697 # pg_tablespace_oid_index
      │ ├── 2698 # pg_tablespace_spcname_index
      │ ├── 2846 # pg_toast_2396
      │ ├── 2847 # pg_toast_2396_index
      │ ├── 2964 # pg_db_role_setting
      │ ├── 2965 # pg_db_role_setting_databaseid_rol_index
      │ ├── 2966 # pg_toast_2964
      │ ├── 2967 # pg_toast_2964_index
      │ ├── 3592 # pg_shseclabel
      │ ├── 3593 # pg_shseclabel_object_index
      │ ├── 4060 # pg_toast_3592x
      │ ├── 4061 # pg_toast_3592_index
      │ ├── 6000 # pg_replication_origin
      │ ├── 6001 # pg_replication_origin_roiident_index
      │ ├── 6002 # pg_replication_origin_roname_index
      │ ├── pg_control # global control file, use pgcheck -pc to see it.
      │ ├── pg_filenode.map # system table (oid -> filenode) mapping file.
      │ └── pg_internal.init # system table cache file, use pgcheck -pr to see it.
      复制


      近期文章推荐:
      PostgreSQL "表膨胀" 的救世主
      ClickHouse数据目录完全解析
      ClickHouse优化典藏

      更多精彩内容欢迎关注微信公众号



      文章转载自ClickHouse周边,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论