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

【从Oracle到PG】PostgreSQL数据库物理文件目录结构

上篇文章提到,PostgreSQL的对象包括tablespace、database、schema、table、index、sequence等,其中tablespace和database在操作系统层面都是存放数据文件的实体目录,schema是逻辑概念的命名空间,而table、index等则会以数据文件的方式存放在对应的tablespace和database的目录里。

往期相关文章:

从Oracle到PG-PostgreSQL数据库体系结构概述

从Oracle到PG-PostgreSQL对象的逻辑结构关系

相对于Oracle的datafile形式,PostgreSQL的数据文件的目录结构似乎要复杂得多,这个和MySQL在database下存储数据文件有一点点相似。

下面这个图来自Hironobu SUZUKI的技术文档“The Internals of PostgreSQL”中的Logical structure of a database cluster章节

The Internals of PostgreSQL
for database administrators and system developers

http://www.interdb.jp/pg/pgsql01.html

PostgreSQL在进行db初始化之后,会在PGDATA下产生以下目录文件,下面是我使用源码编译安装pg-11.5的例子:

更多详情可查看PostgreSQL官档:

https://www.postgresql.org/docs/11/storage-file-layout.html

PostgreSQL-11.5官档第68章关于PGDATA路径下的目录结构的介绍:

pg-11.5 $PGDATA目录

下面我们进入base这个默认表空间目录

    [postgres@akendb01]$pwd
    /aken/data/pgsql/1105/data/base
    [postgres@akendb01]$ls -l
    total 60
    drwx------ 2 postgres postgres 8192 Aug 26 21:28 1
    drwx------ 2 postgres postgres 8192 Aug 26 21:28 13286
    drwx------ 2 postgres postgres 8192 Sep 25 21:54 13287
    drwx------ 2 postgres postgres 8192 Sep 25 22:10 16386
    drwx------ 2 postgres postgres 8192 Aug 29 21:16 16387
    [postgres@akendb01]$

    发现base里面有5个子目录,实际上分别代表pg集簇实例里面的5个database,这些database默认都存放在pg_default这个表空间里面(即这里的base)。

      [postgres@akendb01]$psql
      psql (11.5)
      Type "help" for help.
      (postgres@[local]:5432)[postgres]#\l --查看当前实例的database。
      List of databases
      Name | Owner | Encoding | Collate | Ctype | Access privileges
      -----------+----------+----------+---------+-------+-----------------------
      akendb01 | postgres | UTF8 | C | C |
      akendb02 | postgres | UTF8 | C | C |
      postgres | postgres | UTF8 | C | C |
      template0 | postgres | UTF8 | C | C | =c/postgres +
      | | | | | postgres=CTc/postgres
      template1 | postgres | UTF8 | C | C | =c/postgres +
      | | | | | postgres=CTc/postgres
      (5 rows)
      (postgres@[local]:5432)[postgres]#


      接着查看某个表的数据文件存放路径:database=akendb01,schema=public,tablename=table01。

        (postgres@[local]:5432)[postgres]#\c akendb01
        You are now connected to database "akendb01" as user "postgres".
        (postgres@[local]:5432)[akendb01]#\dt
        List of relations
        Schema | Name | Type | Owner
        --------+---------+-------+--------
        public | table01 | table | aken01
        (1 row)
        1. 直接通过表名的方式查看:

          (postgres@[local]:5432)[akendb01]#select pg_relation_filepath('table01'::regclass);
          pg_relation_filepath
          ----------------------
          base/16386/32797 --这里的32797表示该表的filenode id
          (1 row)
          (postgres@[local]:5432)[akendb01]#exit
          [postgres@akendb01]$cd $PGDATA/base/16386/
          [postgres@akendb01]$ls -l *32797*
          -rw------- 1 postgres postgres 8192 Sep 22 10:58 32797
          -rw------- 1 postgres postgres 16384 Sep 12 22:04 32797_fsm
          -rw------- 1 postgres postgres 0 Sep 12 22:01 32797_vm
          [postgres@akendb01]$


          2.通过oid的方式,这里的pg表的oid类似Oracle的object_id,而filenode则类似Oracle的data_object_id,表示该表的真正路径。

          默认情况下,pg中表的oid的初始值和filenode id相等,当执行过truncate、vacuum full等操作后filenode会发生变化。

          --查看表的oid和filenode id:

            (postgres@[local]:5432)[akendb01]#select relname,oid,relfilenode from pg_class where relname='table01';
            relname | oid | relfilenode
            ---------+-------+-------------
            table01 | 32797 | 32797
            (1 row)
            (postgres@[local]:5432)[akendb01]#


            --通过oid查看表数据文件路径:

              (postgres@[local]:5432)[akendb01]#select pg_relation_filepath(32797);
              pg_relation_filepath
              ----------------------
              base/16386/32797
              (1 row)
              (postgres@[local]:5432)[akendb01]#


              --对表执行truncate操作

                (postgres@[local]:5432)[akendb01]#truncate table01;
                TRUNCATE TABLE
                (postgres@[local]:5432)[akendb01]#select relname,oid,relfilenode from pg_class where relname='table01';
                relname | oid | relfilenode
                ---------+-------+-------------
                table01 | 32979 | 49166
                (1 row)


                可以看到,当发生truncate操作后,表的filenode id发生了变化,由原来的32979变成了49166。

                再次查看table01的数据文件路径:

                  (postgres@[local]:5432)[akendb01]#select pg_relation_filepath(32979);
                  pg_relation_filepath
                  ----------------------
                  base/16386/49166
                  (1 row)
                  (postgres@[local]:5432)[akendb01]#


                  可以看到,filenode id代表的是表的实际路径,table01的数据文件路径跟着filenode发生了变化。

                  最后,借用Hironobu SUZUKI大师的一张图来总结一下PostgreSQL的物理文件结构:

                  图片来源:http://www.interdb.jp/pg/pgsql01.html#_1.2.

                  ---本文完---

                  欢迎投稿



                          中国开源软件推进联盟PostgreSQL分会,欢迎大家积极投稿,向PGer分享自己的实践经验、心得体会,共建PG中国生态。

                  投稿邮箱:

                  partner@postgresqlchina.com


                  最后修改时间:2019-12-27 09:32:24
                  文章转载自开源软件联盟PostgreSQL分会,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                  评论