PG体系结构之物理结构

0    561    3

👉 本文共约5958个字,系统预计阅读时间或需23分钟。

PG内存结构请参考:https://www.xmmup.com/pgtixijiegouzhineicunjiegou.html

简介

  • PostgreSQL由一系列数据库组成。
  • 一套PostgreSQL程序称之为一个数据库群集。PG中的集群,也即database cluster,是由PostgreSQL服务端来管理的一组数据库(database)的集合。注意这里是数据库(database)的集合,不是数据库服务(database servers)的集合。一个PostgreSQL服务器运行在单个主机上,管理单个数据库集群。
  • 当initdb命令执行初始化数据库后,template0 , template1,和postgres数据库被创建。
  • template0和template1数据库是创建用户数据库时使用的模版数据库,他们包含系统元数据表。
  • initdb()刚完成后,template0和template1数据库中的表是一样的。但是template1数据库可以根据用户需要创建对象。用户数据库是通过克隆template1数据库来创建的
  • initdb()后马上创建pg_default和pg_global表空间
  • 建表时如果没有指定特定的表空间,表默认被存在pg_default表空间中。
  • 用于管理整个数据库集群的表默认被存储在pg_global表空间中。
  • pg_default表空间的物理位置为$PGDATA\base目录。
  • pg_global表空间的物理位置为$PGDATA\global目录。
  • 一个表空间可以被多个数据库同时使用。此时,每一个数据库都会在表空间路径下创建为一个新的子路径。
  • 创建一个用户表空间会在$PGDATA\pg_tblspc目录下面创建一个软连接,连接到表空间制定的目录位置。
  • 在PG中,当应用连接到一个数据库时,一般只能访问这个数据库中的数据,而不能访问其他数据库中的数据(除非使用dblink等其他手段)
  • 在PG中,表的术语称为“Relation”,而在其他数据库中叫“Table”
  • 在PG中,行的术语为“Tuple”,而在其他数据库中叫“Row”
  • 在PG中,服务端不支持汉字字符集GBK和GB18030

物理结构

实际上,pg的数据库集群本质上是一个目录。目录中包含一些子目录和很多的文件。在我们安装pg时,我们一般使用initdb的命令去初始化一个新的数据库集群。initdb 有个-D参数,通过它来指定应该存储数据库集群的目录。而集群中的database对应$PGDATA/base目录下的一个文件夹,文件夹的名称即oid。

$PGDATA目录下的文件和子目录的布局:

物理文件或文件夹名解释
PG_VERSION包含PG大版本号的文件
postgresql.auto.conf用于存储由ALTER SYSTEM设置的配置参数
postmaster.opts记录服务器上次启动时使用的命令行参数的文件
postmaster.pid一个锁文件,记录当前postmaster进程的pid,cluster data目录路径,postmaster进程启动时的时间戳,端口号,Unix-domain socket目录路径,有效的listen_address(ip地址或者*,如果为空表示server不基于tcp),共享内存端id。
current_logfiles记录日志采集器当前写入的日志文件的文件
base包含每个数据库的子目录,为默认表空间
global包含集群范围表的子目录,作为共享系统表目录,例如pg_database
pg_commit_ts包含事务提交时间戳数据的子目录
pg_dynshmem包含动态共享内存子系统使用的文件的子目录
pg_logical包含用于逻辑解码的状态数据的子目录
pg_multixact包含多事务状态数据的子目录(用于共享行锁)
pg_notify包含监听/通知状态数据的子目录
pg_replslot包含复制槽位数据的子目录
pg_serial包含关于已提交的可序列化事务信息的子目录
pg_snapshots导出快照的子目录
pg_stat包含统计子系统永久文件的子目录
pg_stat_tmp包含统计子系统临时文件的子目录
pg_subtrans包含子事务状态数据的子目录
pg_tblspc包含到表空间的符号链接的子目录
pg_twophase包含已准备事务状态文件的子目录
pg_wal包含WAL (Write Ahead Log)文件的子目录
pg_xact包含事务提交状态数据的子目录

数据库包含的文件种类:
√数据库文件:位置在$PGDATA/base目录下,数据库对象,如:数据库、表,索引,序列等对象。
√控制文件:用来记录数据库集群的状态信息,如:版本信息、集群所管理的各种文件信息、检查点信息、事务状态信息等
√参数文件:位置在$PGDATA目录下
√日志文件:记录数据修改操作的日志,用于系统发生故障时进行数据恢复。
√临时文件:存放数据库进行计算的过程中,生成的各种中间对象,如排序运算的外存归并单元。

PG体系结构之物理结构

相关物理文件

postmaster.pid :这个文件存在于数据目录中是为了帮助pg_ctl判断服务器当前是否在运行。

控制文件

PostgreSQL 控制文件在$PGDATA/global目录下名为pg_control

PG控制文件pg_control里存储的数据是一个ControlFileData结构。控制文件尽量保持小于512个字节以使其适合一个典型的磁盘驱动的物理簇的大小。这会减少由于电源故障而写控制文件直接失败的可能性。但控制文件的物理大小是8K,远大于512个字节。这样做是为了控制文件格式变化时保持物理大小不变,如果正在读一个不兼容文件,以使ReadControlFile能传递一个合适的错误版本控制文件信息而代替一个读错误。系统里定义了和自己匹配的控制文件版本变量PG_CONTROL_VERSION,启动时会做系统和控制文件的匹配校验

pg_controldata命令可以显示出控制文件中内容:

  • pg_control version number:控制文件的版本

  • Catalog version number:系统表版本号,PG9.4版本为201409291.PG版本由三个数字表示“X.Y.Z”,通常有重大功能变化X才会发生变化,Y变化通常指系统表发生了变化,Z变化系统表不会变化。若只是Z变化,通常只需要把二进制程序升级一个就可以,系统表没有变化,数据文件就是可以兼容

  • Maximum data alignment:数据结构最大的对齐值

  • Database block size:数据块的大小

  • Blocks per segment of large relation:在一些文件系统上,单个文件大小受限制,PG会把一个表的数据分到多个数据文件中存储,此值制定了每个数据文件最多多少个数据块,默认为131072个块,每个块8k,数据文件最大为1G

  • WAL block size:WAL日志块大小

  • Bytes per WAL segment:WAL日志块大小

  • Maximum length of identifiers:“name”类型的长度,实际上指一些数据库对象名称的最大长度,如表名、索引名的最大长度

  • Maximum columns in an index:一个索引最多多少列,目前为32个

  • Maximum size of a TOAST chunk:TOAST chunk的长度

  • Size of a large-object chunk:大对象的chunk大小

  • Date/time type storage:Date/time类型是用浮点数(double)类型表示还是由64bit的长整数表示,与不同类UNIX平台有关

    本人提供Oracle、MySQL、PG等数据库的培训和考证业务,私聊QQ646634621或微信db_bao,谢谢!
  • Float4 argument passing:Float4类型的参数是传值还是传引用

  • Float8 argument passing:Float8类型的参数是传值还是传引用

  • Data page checksum version:数据块checksum的版本,如果为0,数据块没有使用checksum。运行initdb时加了-k参数,PG才会在数据块上启用checksum功能

  • Database system identifier:数据库的唯一标识串,这个标识串是一个64bit的整数,其中包含了创建数据库的时间戳和initdb时初始化的进程号,因此通常不会重复

  • Database cluster state:记录实例的状态,包括以下几个值:

    • starting up:表示数据库正在启动状态,实际上目前没有使用此状态
    • shut down:数据库实例(非Standby)正常关闭后控制文件中就是此状态
    • shut down in recovery:Standby实例正常关闭后控制文件中就是此状态
    • shutting down:正常停库时,先做checkpoint,开始做checkpoint时,会把状态设置为此状态,做完后把状态设置为shut down
    • in crash recovery:数据库实例非异常停止后,重新启动后,会先进行实例的恢复,在实例恢复时的状态就是此状态
    • in archive recovery:Standby实例正常启动后,就是此状态
    • in production:数据库实例正常启动后就是此状态。Standby数据库正常启动后不是此状态
  • Latest checkpoint location:数据库异常停止后再重新启动时,需要做实例恢复,实例恢复的过程是从WAL日志中,找到最后一次的checkpoint点,然后读取这个点之后的WAL日志,重新应用这些日志,此过程称为数据库实例前滚,最后一次的checkpoint点的信息记录在“Latest checkpont”项中

  • Minimum recovery ending location:此值与Standby库应用WAL日志有关,需要注意的是主库与备库的控制文件中的checkpoint信息不同。在备库中,每replay一些WAL日志后,就会做一次checkpoint点,然后把这个checkpoint点的信息记录到控制文件中。当在备库replay一些日志,如果有一些脏数据刷新到磁盘中,会把产生脏数据的最新日志的位置记录到“Minimum recovery ending location”。为了能保证恢复到一个一致点。备库异常停机后,再启动,若备库提供只读服务或激活成主库,磁盘上的数据不一致,此时读备库会读到错误数据。因此replay日志要超过“Minimum recovery ending location”后,才能对外提供服务

  • Backup start location、Backup end location、End-of-backup record required

    “Backup start location”与“Backup end location”记录了一个WAL日志的位置。在主库上做“SELECT pg_start_backup(‘tangxxxx’);”,只是在主库的数据目录下生成了一个backup_label文件,这时拷贝主库,拷贝出来的数据文件中就包括了backup_label文件,备库启动时,若发现有backup_label文件,会从这个文件中记录的点开始恢复,同时备库会把此位置记录到控制文件的“Backup start location”中,“Backup end location”与“End-of-backup record required”记录了备库恢复过程中的一些中间状态

日志文件

pg_log(数据库运行日志)

pg_log表示数据库运行日志,pg_log默认是关闭的,需要配置postgresql.con相关的参数启用此日志,默认路径$PGDATA/pg_log/;记录各种Error信息,定位慢查询SQL,数据库的启动关闭信息,发生checkpoint过于频繁等的告警信息。

pg_xlog

pg_xlog ( WAL日志,即重做日志)也就是一些事务日志信息(transaction log)。

  • PostgreSQL在将缓存的数据刷入到磁盘之前,先写日志,这就是PostgreSQL WAL( Write-Ahead Log )方式,也就是预写日志方式
  • 默认存放在$pgdata/pg_wal,单个文件大小是16M,内容一般不具有可读性,默认强制开启,无法关闭;
  • 物理备份的时候需要备份此日志。

PostgreSQL提供WAL切换三种方式

  • pg_switch_xlog()函数可以手工切换WAL日志
  • WAL日志写满后触发归档
  • 设置archive_timeout

pg_clog

pg_clog(事务提交日志,记录的是事务的元数据,pg_clog是pg_xlog的辅助日志),这个日志告诉我们哪些事务完成了,哪些没有完成。

  • 一般位于:$PGDATA/pg_clog,这个日志文件一般非常小,但是重要性也是相当高,不得随意删除或者对其更改信息。
  • 内容一般不具有可读性,默认强制开启,无法关闭﹔
  • 物理备份的时候需要备份此日志。

口令文件(密码文件)

http://postgres.cn/docs/13/libpq-pgpass.html

一个用户主目录中的.pgpass文件能够包含在连接需要时使用的口令(并且其他情况不会指定口令)。在微软的 Windows 上该文件被命名为%APPDATA%\postgresql\pgpass.conf(其中%APPDATA%指的是用户配置中的应用数据子目录)。另外,可以使用连接参数passfile或者环境变量PGPASSFILE指定一个口令文件。

这个文件应该包含下列格式的行:

(你可以向该文件增加一个提醒:把上面的行复制到该文件并且在前面加上#)。前四个域的每一个都可以是文字值或者匹配任何东西的*。第一个匹配当前连接参数的行中的口令域将被使用(因此,在使用通配符时把更特殊的项放在前面)。如果一个条目需要包含:或者\,用\对该字符转义。如果指定了host连接参数,主机名字段会被匹配到host,否则如果指定了hostaddr参数则匹配到hostaddr,如果两者都没有给出,则会搜索主机名localhost。当连接是一个Unix域套接字连接并且host参数匹配libpq的默认套接字目录路径时,也会搜索主机名localhost。在一台后备服务器上,值为replication的数据库字段匹配连接到主服务器的里复制连接。否则数据库字段的用途有限,因为用户对同一个集簇中的所有数据库都有相同的口令。

在 Unix 系统上,口令文件上的权限必须不允许所有人或组内访问,可以用chmod 0600 ~/.pgpass这样的命令实现。如果权限没有这么严格,该文件将被忽略。在微软 Windows 上,该文件被假定存储在一个安全的目录中,因此不会进行特别的权限检查。

需要注意:
1、当密码包含冒号(:)时,必须用反斜杠(\:)进行转义
2、字符“*”可以匹配任何字段中的任何值(密码除外)
3、如果设置了环境变量PGPASSWORD,则不会读取~/.pgpass文件
4、Windows 7 64位上带有空格的路径的示例PGPASSFILE值:
设置PGPASSFILE = C:\Program Files\someapp\pgpass.conf
5、请注意,环境变量值不得使用“(双引号)
6、关于权限:在 Unix 系统上,口令文件上的权限必须不允许所有人或组内访问,可以用chmod 0600 ~/.pgpass这样的命令实现。如果权限没有这么严格,该文件将被忽略。在Windows上,该文件被假定存储在一个安全的目录中,因此不会进行特别的权限检查。

    头像

    小麦苗

    学习或考证,均可联系麦老师,请加微信db_bao或QQ646634621

    您可能还喜欢...

    发表评论

    您的电子邮箱地址不会被公开。

    14 + 5 =

     

    嘿,我是小麦,需要帮助随时找我哦
    • 18509239930
    • 个人微信

    • 麦老师QQ聊天
    • 个人邮箱
    • 点击加入QQ群
    • 个人微店

    • 回到顶部
    返回顶部