Postgresql的体系结构
PostgreSQL数据库是由一系列位于文件系统上的物理文件组成,在数据库运行过程中,通过整套高效严谨的逻辑管理这些物理文件。
通常将这些物理文件称为数据库,将管理这些物理文件的进程、进程管理的内存称为这个数据库的实例。
在PostgreSQL的内部功能实现上,可以分为系统控制器、查询分析器、事务系统、恢复系统、文件系统这几部分。
其中系统控制器负责接收外部连接请求,查询分析器对连接请求查询进行分析并生成优化后的查询解析树,从文件系统获取结果集或通过事务系统对数据做处理,并由文件系统持久化数据。
逻辑和物理存储结构
Database cluster是指由单个PostgreSQL服务器实例管理的数据库集合,组成数据库集簇的这些数据库使用相同的全局配置文件和监听端口、共用进程和内存结构。
逻辑存储结构
无法直接从集簇中的一个数据库访问该集簇中的另一个数据库中的对象。
数据库本身也是数据库对象,一个数据库集簇可以包含多个Database,多个user。
创建一个数据库的时候,会默认为这个database创建一个名为public的schema;在数据库中创建数据库对象时如果没有指定schema,那么都会在public下。
物理存储结构
数据库的文件,默认保存在initdb时创建的数据目录中。
数据目录结构
数据目录路径配置为PGDATA环境变量。
查看数据目录下有哪些子目录和文件:
tree -L 1 -d $PGDATA
[[email protected] data]$ cd ll
total 112
drwx------. 5 postgres postgres 4096 Feb 9 15:37 base --主数据目录。在此目录中,每个数据库都有其自己的目录,其中包含用于每张表和索引的文件
drwx------. 2 postgres postgres 4096 Feb 9 15:37 global --数据库中的系统表,在所有数据库中共享
drwx------. 2 postgres postgres 4096 Feb 9 15:37 pg_clog --事务状态文件
drwx------. 2 postgres postgres 4096 Feb 9 15:37 pg_commit_ts --包含事务提交时间戳数据的子目录
drwx------. 2 postgres postgres 4096 Feb 9 15:37 pg_dynshmem --包含动态共享内存信息(从9.4开始)
-rw-------. 1 postgres postgres 4468 Feb 9 15:37 pg_hba.conf --客户端认证控制文件
-rw-------. 1 postgres postgres 1636 Feb 9 15:37 pg_ident.conf
drwx------. 4 postgres postgres 4096 Feb 9 15:37 pg_logical --包含用于逻辑复制的状态数据的子目录
drwx------. 4 postgres postgres 4096 Feb 9 15:37 pg_multixact --行锁状态文件
drwx------. 2 postgres postgres 4096 Feb 9 15:37 pg_notify --包含listen和notify状态文件
drwx------. 2 postgres postgres 4096 Feb 9 15:37 pg_replslot --包含复制槽位(replication slots)的信息
drwx------. 2 postgres postgres 4096 Feb 9 15:37 pg_serial --包含已提交的序列化事务信息(从9.1开始)
drwx------. 2 postgres postgres 4096 Feb 9 15:37 pg_snapshots --包含输出的快照文件(从9.2开始)
drwx------. 2 postgres postgres 4096 Feb 9 15:37 pg_stat --包含服务活动统计以及持久文件(从9.3开始)
drwx------. 2 postgres postgres 4096 Feb 9 15:37 pg_stat_tmp --包含服务活动统计以及临时文件
drwx------. 2 postgres postgres 4096 Feb 9 15:37 pg_subtrans --子事务状态文件
drwx------. 2 postgres postgres 4096 Feb 9 15:37 pg_tblspc --连接到外部的表空间
drwx------. 2 postgres postgres 4096 Feb 9 15:37 pg_twophase --两阶段提交或prepared的事务状态
-rw-------. 1 postgres postgres 4 Feb 9 15:37 PG_VERSION --PostgreSQL主版本号文件
drwx------. 3 postgres postgres 4096 Feb 9 15:37 pg_xlog --事务日志WAL
-rw-------. 1 postgres postgres 88 Feb 9 15:37 postgresql.auto.conf --参数文件,只保留alter system命令修改的参数
-rw-------. 1 postgres postgres 22268 Feb 9 15:37 postgresql.conf --参数文件
[[email protected] data]$
数据文件布局
数据文件默认保存位置为base子目录。
OID
OID:对象标识符。PostgreSQL中所有的数据库对象都是由各自的对象标识符进行内部管理,它们是无符号的4字节整数。
数据库的OID存储在pg_database系统表中,查询:
select oid,datname from pg_database;
数据库中的表、索引、序列等对象的OID存储在pg_class系统表中:
select oid,relname,relkind from pg_class;
表空间
在PostgreSQL中最大的逻辑存储单位是表空间。
初始化数据库目录时会自动创建pg_default和pg_global两个表空间。
\db:查看表空间
pg_global表空间的物理文件位置在数据目录的global目录中,用来保存系统表。
pg_default表空间的物理文件位置在数据目录的base目录,是template0和template1的默认表空间。
表空间创建及使用
1.创建表空间使用路径
2.创建表空间
create tablespace tbs_name locatoin ‘path’;
3.建表时使用表空间
create table tbl_name (col datatype) tablespace tbs_name;
数据文件命名
在PostgreSQL中,每个表和索引都用一个文件存储,新创建的表文件以表的OID命名,对于大小超过1GB的表数据文件,切分存储。
查看表的数据文件:
select oid,relfilenode from pg_class where relname=‘tbl_name’;
查看表大小:
select pg_size_pretty(pg_relation_size(‘tbl’::regclass));
后缀为_fsm和_vm的这两个表文件的附属文件是空闲空间映射表文件和可见性映射表文件。
空闲空间映射文件用来映射文件中可用的空间。
可见性映射表文件跟踪哪些页面只包含已知对所有活动事务可见的元组,它也跟踪哪些页面只包含未被冻结的元组。
表文件内部结构
在PostgreSQL中,将保存在磁盘中的块称为page,而将内存中的块称为buffer,表和索引称为relation,行称为tuple。
数据的读写是以page为最小单位,每个page默认大小为8kb,在编译PostgreSQL时指定的blcksz大小决定了page的大小。
进程结构
PostgreSQL是一用户一进程的客户端/服务器的应用程序。数据库启动时会启动若干个进程,其中有postmaster(守护进程)、postgres(服务进程)、syslogger、checkpointer、bgwriter、walwriter等辅助进程。
守护进程
postmaster(守护进程)主要职责有:
- 数据库的启停
- 监听客户端连接
- 为每个客户端连接fork单独的postgres服务进程
- 当服务进程出错时进行修复
- 管理数据文件
- 管理与数据库运行相关的辅助进程
辅助进程
backgroud writer:bgwriter进程,每次唤醒后它会搜索共享缓冲池找到被修改的页,并将它们从共享缓冲池刷出。
autovacuum launcher:自动清理回收垃圾进程
WAL writer:定期将WAL缓冲区上的WAL数据写入磁盘。
statistics collector:统计信息收集进程。
logging collector:日志进程,将消息或错误信息写入日志。
archiver:WAL归档进程。
checkpointer:检查点进程。
内存结构
PostgreSQL的内存分为两大类
- 本地内存
- 共享内存
- 为辅助进程分配的内存等
本地内存
本地内存由每个后端服务进程(postgres)分配以供自己使用,当后端服务进程被fork时,每个后端进程为查询分配一个本地内存区域。
本地内存由三部分组成:
- work_mem:当使用order by或distinct操作对元组进行排序时会使用这部分内存。
- maintenance_work_mem:维护操作,例如VACUUM,REINDEX,CREATE INDEX等操作使用这部分内存。
- temp_buffers:临时表相关操作使用这部分内存
共享内存
共享内存在PostgreSQL服务器启动时分配,由所有后端进程共同使用。
共享内存主要由三部分组成:
- shared buffer pool:PostgreSQL将表和索引中的页面从持久存储装载到这里,并直接操作他们。
- WAL buffer:WAL文件持久化之前的缓冲区。
- CommitLog buffer:PostgreSQL在Commit Log中保存事务的状态,并将这些状态保留在共享内存缓冲区中,在整个事务处理过程中使用。