返回

文章详情

深入阅读Postgres内部:数据库集群、数据库和表

Hacker News2026年6月29日 12:59

2026年6月28日,我正在深入研究Postgres的内部结构,同时我想写下我的笔记,以保持我对学习的负责,并尝试内化我的阅读。感谢铃木弘信提供这个伟大的参考资料以及他在Postgres上的工作。以下是源链接:https://www.interdb.jp/pg/index.html。 数据库集群的逻辑结构#在PostgreSQL的上下文中,数据库集群并不是数据库服务器的集合(SQL标准使用目录集群这个术语)。它是由单个PostgreSQL实例管理的一组数据库。这个定义在字典意义上是正确的,但通常当你听到数据库集群时,你会假设它是多个节点/数据库实例作为单一系统运作。数据库是表、索引、视图等数据库对象的集合。在PostgreSQL中,数据库也是数据库对象,由Oid表示,Oid是无符号整型对象标识符。 sql SELECT oid, datname FROM pg_database ORDER BY oid; oid datname 1 template1 4 template0 5 postgres (3 rows) 内置对象(该查询中的数据库)具有硬编码的低值。其他用户创建的表/对象的OID从16384开始(OID 1-16383是保留或由init对象使用)。 数据库集群 · 一个PostgreSQL实例 template1oid 1 template0oid 4 postgresoid 5 shopoid 16384 pg_database列出了每个数据库(每个集群一个共享目录) 对象在'shop'表中 orders表oid 16386 orders_pkey索引oid 16395 视图、序列……更多对象oid……每个对象由其自己的Oid标识 这些对象及其关系存储在系统目录中,这些目录只是PostgreSQL中的常规表。一些例子包括: 表 描述 pg_class 表和其他类似于表的对象(视图、索引、TOAST表等) pg_database 存储可用数据库的信息。 pg_index 索引信息 ... ... 关于目录的一些琐事:pg_database在一个集群的所有数据库中是共享的(每个集群一个表),而大多数系统目录是按数据库创建的,pg_class存储索引,还有pg_index目录。好的,原因是pg_class用于通用关系信息。pg_index和其他相应目录有自己的自定义模式。这有助于分离关注点,避免将来出现pg_class2表(虽然过于夸张,但想起了著名的merchants2表 https://jimmyhmiller.com/ugliest-beautiful-codebase )。如上所述,这些只是您可以运行查询的常规表(自担风险!)。许多内置对象(如类型、函数和操作符)存储在这些表中,用户定义的对象以相同的方式添加到这些表中。这些OID在新行添加到目录表时自动创建。例如,当注册扩展(例如pgvector)时,发生的情况是pgvector被添加到pg_extension表中,并自动创建了OID。这一行为以前也适用于用户定义的表。时间轴历史如下: PG <= 8.0 : 所有表行都是用OID创建的。 8.1 <= PG < 12 : 自动OID生成是一个自选功能。要启用,用户需要使用CREATE TABLE foo (...) WITH OIDS;创建表,或启用GUC default_with_oids。 PG >= 12 : 此功能完全移除。 数据库集群的物理结构#Postgres集群在数据目录中存储一切。其路径由PGDATA环境变量设置。常见的默认位置是/var/lib/pgsql/data和/var/lib/postgresql/<version>/main。initdb负责设置和创建此目录,Postgres安装程序自动完成。当调用brew install postgresql@18时,postgres@18.rb在安装Postgres后会在其后安装方法中运行下面的行: system bin/"initdb", "--locale=en_US.UTF-8", "-E", "UTF-8", postgresql_datadir unless pg_version_exists? 类似的逻辑通过其他Postgres安装方法实现(Windows的EDB,apt/deb等)。在$PGDATA内部,有很多子目录: $PGDATA/ ├── base/ # 每个数据库一个子目录 │ └── {OID}/ # 表和索引作为文件(relfilenode) ├── global/ # 集群范围的目录(例如pg_class) ├── pg_wal/ # WAL段文件 ├── pg_xact/ # 事务提交状态(clog) ├── pg_tblspc/ # 外部表空间的符号链接 ├── PG_VERSION #主要版本号 ├── postgresql.conf # 主要服务器配置 └── ... # 15+ 更多 完整列表见 https://www.postgresql.org/docs/current/storage-file-layout.html 。子目录的变化似乎非常罕见。这里的表格显示了一些命名变更和PG9和PG10中的新添加。我还检查了Postgres源代码,并发现当前日志文件子目录是在PG10版本中添加的。它是在PG10开始包含的19dc233中添加的: bash git tag --contains 19dc233c32f | grep -E '^REL' | sort -V | head REL_10_0 REL_10_1 REL_10_2 ... 数据库子目录布局#如上所述,每个数据

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡