PostgreSQL的存储结构介绍
PostgreSQL 是一个先进的开源关系型数据库管理系统,其存储结构设计非常复杂且高效。了解其存储结构有助于数据库管理员和开发人员更好地优化数据库的性能、设计数据模型以及进行故障排除。以下是 PostgreSQL 存储结构的详细概述。
1. 数据文件结构
PostgreSQL 的数据主要存储在磁盘上的一组文件中。这些文件位于 PostgreSQL 数据目录(通常称为 PGDATA
)中。数据目录包含以下主要子目录和文件:
- base/:存储实际的表和索引数据。
- global/:存储数据库级别的元数据文件,如数据库配置和全局事务ID。
- pg_xact/:存储事务日志(原名为 pg_clog/,在 PostgreSQL 10.0及以上版本更名为 pg_xact/)。
- pg_wal/:存储 Write-Ahead Logging(WAL)文件。
- pg_multixact/:存储多事务ID信息。
- pg_tblspc/:表空间信息的符号链接。
- pg_stat/ 和 pg_stat_tmp/:存储统计信息。
- pg_log/:存储错误日志和其他日志文件。
2. 表和索引文件
每个数据库在其数据目录(base/
目录)中都有一个子目录。这个子目录的名称是一个数字,代表数据库的 OID(对象标识符)。在这个子目录中,每个表和索引都有一个单独的文件,每个文件的名字是表或索引的 OID。
例如,在 base/12345/
目录下:
12345
是数据库 OID。56789
文件是表的 OID。- PostgreSQL 会根据表或索引的大小分割成多个文件,文件名格式通常为
56789
,56789.1
,56789.2
,以此类推。
3. 逻辑存储结构
3.1 页面和块
PostgreSQL 中的表和索引数据都存储在页面中。每个页面的大小通常为 8KB(可以在编译时配置)。页面是磁盘 I/O 操作的基本单位。页面又分为多个块(block),并使用块链表进行管理。
- 每个页面包含一个页头、数据、和页尾。页头包含页的元数据,如页的 LSN(日志序列号)。
- 数据部分存储行(元组)数据,每行有一条指向页(块)头部的指针。
- 页尾存储行的状态位(如行是否删除,但未进行物理删除)。
3.2 元组
数据行存储在页面的“元组”中。每个元组分为三部分:
- 元组头(Tuple Header):包含元数据,如行的事务 ID(XID)、行的大小和标记。
- 数据部分:实际的列值。
- 元组尾(Tuple Tail)(可选):用于存储TOASTed数据(超大对象数据)。
4. TOAST(The Oversized-Attribute Storage Technique)
当表中的数据行某些字段超过一定大小时,PostgreSQL 使用 TOAST 技术将这些大字段分解并存储在一个特殊的TOAST表中。每个TOAST表有自己的 OID,并有一个关联的主表。
5. 表空间
PostgreSQL 支持表空间,可以将数据库对象(如表和索引)存储在特定的文件系统位置。表空间是 PostgreSQL 用户定义的逻辑存储单位,对应于磁盘上的实际目录。
创建表空间:
CREATE TABLESPACE my_tablespace LOCATION '/path/to/directory';
使用表空间:
CREATE TABLE my_table (...) TABLESPACE my_tablespace;
6. 多版本并发控制(MVCC)
PostgreSQL 使用多版本并发控制(MVCC)机制来管理并发事务和数据一致性。在 MVCC 中,每个数据修改操作(如插入、更新和删除)会产生一个新的数据行版本,而旧的数据版本保留在存储中(直到被VACUUM清理)。
这意味着在读取数据时,不需要锁定数据行,从而大大提高了并发性能。MVCC 的基本原理如下:
- 插入(Insert):产生一个新的数据行版本,新的行 XID(事务 ID)标记当前事务。
- 更新(Update):旧行被标记为过期,并插入一个新行,新行 XID 设置为当前事务 ID。
- 删除(Delete):行被标记为删除,XID 设置为当前事务 ID。
- VACUUM:清理过期和无用的数据行,回收空间。
7. WAL(Write-Ahead Logging)
PostgreSQL 使用 WAL 来确保数据的持久性和一致性。WAL 日志记录所有修改数据库的数据变更,在数据实际写入数据文件之前。这样在发生崩溃时,可以通过重新应用 WAL 日志来恢复数据库到一致状态。
WAL 文件位于 pg_wal
目录下(在 PostgreSQL 10.0 之前是 pg_xlog
)。每个 WAL 文件默认大小为 16MB。
7.1 配置和管理 WAL
你可以通过修改 PostgreSQL 配置文件(postgresql.conf
)中的参数来管理 WAL。例如:
# 启用 WAL 压缩
wal_compression = on
# 设置重放 WAL 日志的检查点间隔
checkpoint_timeout = 5min
8. 索引
PostgreSQL 支持多种索引类型,包括 B-tree、Hash、GIN(Generalized Inverted Index)、GiST(Generalized Search Tree)、SP-GiST(Space-partitioned Generalized Search Tree)和 BRIN(Block Range INdexes)等。
建立索引:
CREATE INDEX idx_name ON table_name (column_name);
选择特定类型索引:
CREATE INDEX idx_name ON table_name USING gin (column_name);
每个索引类型有其特定的适用场景和性能特点。
9. 内存和缓存
PostgreSQL 使用多种内存区域和缓存策略来提高性能。
9.1 共享缓冲池
共享缓冲池(Shared Buffers)用于缓存表和索引数据。配置 shared_buffers
参数来设置共享缓冲区的大小。
shared_buffers = 1GB
9.2 工作内存
工作内存(Work Memory)用于执行查询时的内部操作,如排序和哈希连接。配置 work_mem
参数来设置工作内存大小。
work_mem = 64MB
9.3 维护工作内存
维护工作内存(Maintenance Work Memory)用于数据库维护操作,如 VACUUM 和 CREATE INDEX。配置 maintenance_work_mem
参数来设置维护工作内存大小。
maintenance_work_mem = 128MB
总结
PostgreSQL 的存储结构非常灵活和高效,通过了解其数据文件、表和索引文件、逻辑存储结构、MVCC、TOAST、WAL、表空间、内存和缓存管理,可以更好地进行数据库优化、性能调整和故障排查。如果对某一具体部分有更多问题,欢迎随时提问!
标签:存储,WAL,PostgreSQL,介绍,索引,pg,数据 From: https://blog.csdn.net/lee_vincent1/article/details/139785783