1 概述
PostgreSQL官方介绍称是最先进的开源关系型数据库,支持所有主流的平台,目前已经更新到了最新版本的12.0,在MySQL被Oracle收购后,PostgreSQL开源社区越来越活跃了,同时还有分布式集群的开源方案GreenPlum,目前也非常受欢迎。本篇文章讨论PostgreSQL内部的架构,内部的组件是如何工作的,这对一个DBA是非常重要的内容。
2 PostgreSQL架构
PostgreSQL的物理结构是非常简单的,主要是由共享内存、后台进程和数据文件组成的。大致的结构可以参考下面的图。 椭圆形的都是进程,方形的都是内存结构,圆柱形的是文件。
2.1 进程
在启动数据库后,Postmaster是第一个启动的进程,在启动过程中,会进行恢复操作(如果有事务未正常提交或者回滚的话),初始化共享内存,启动后台进程等一系列的操作。当客户进程有一个连接请求时,会创建相对应的后台进程处理。过程如下:
通过ps -ef|grep postgres
查询可以看到系统总有一个postmaster进程pid=17201,后面所有的后台进程都是postmaster的子进程
postgres 17201 1 0 Jan25 ? 00:06:21 /usr/pgsql-9.6/bin/postgres -D /data1/pgdata
postgres 17202 17201 0 Jan25 ? 00:00:10 postgres: logger process
postgres 17204 17201 0 Jan25 ? 00:01:01 postgres: checkpointer process
postgres 17205 17201 0 Jan25 ? 00:01:39 postgres: writer process
postgres 17206 17201 0 Jan25 ? 00:03:37 postgres: wal writer process
postgres 17207 17201 0 Jan25 ? 00:05:11 postgres: autovacuum launcher process
postgres 17208 17201 0 Jan25 ? 00:00:45 postgres: archiver process
postgres 17209 17201 0 Jan25 ? 00:09:20 postgres: stats collector process
postgres 40377 17201 0 Jan25 ? 00:01:38 postgres: wal sender process replica 10.xxx.xx.115(35258) streaming 1/CD5498D0
下表详细介绍一下各个进程。
进程 | 详细描述 |
postmaster | 整个数据库实例的总控进程,负责启动和关闭该数据库实例。 |
logger process | 将数据库的日志写入到日志文件中 |
checkpointer process | 当检查点发生时,脏缓存(指的是相对于原数据而言被修改过的)写入到文件中 |
writer process | 周期性将脏缓存写入到文件中 |
wal writer process | Write Ahead Log(预写式日志) |
autovacuum launcher process | 如果autovacuum开启时,这个是一个周期性回收膨胀表标记为已删除数据的一个进程 |
archiver process | 当开启归档模式,周期性将WAL日志写入到指定的目录 |
stats collector process | 做数据的统计收集工作。主要用于查询优化时的代价估算,包括一个表和索引进行了多少次的插入、更新、删除操作,磁盘块读写的次数、行的读次数。pg_statistic中存储了该进程收集的各类信息。 |
wal sender process replica | 在开启流复制的主备模式时,该进程周期性将WAL文件发送到另一台服务器作为数据同步备份。 |
2.2 内存结构
共享内存一般指的是内存中专门为数据库缓存和事务日志缓存分配的区域,而最重要的组件就是共享缓存和WAL缓存。
共享缓存的主要目的是减少磁盘的IO,比如一些经常访问的数据块尽可能长的时间保存在共享缓存中,除此之外还有一些诸如进程、锁、统计信息也是在缓存中。
WAL缓存区是一块临时存储数据变更的临时区域,存储在该缓存区的内容会被周期性写入到WAL文件中,该区域对于数据库的备份和恢复都是非常重要的。
2.3 数据库结构
这里面说的结构是逻辑结构,不讨论物理结构。以下是一些理解数据库结构非常重要的内容。
关于数据库:
- PostgreSQL是由多个数据库组成的,也可以称为数据库群。
- 当执行了init(),系统会默认创建3个库:template0,template1,postgres。
- template0和template1是为用户数据库创建的模板库,初始化后,这两个库是一模一样的。
- template1可以被定制修改,用户创建新的数据库都是克隆该数据库的。
关于表空间:
- 在初始化后,默认创建了两个表空间pg_default和pg_global。
- 如果在创建表时候没有指定表空间,则默认是pg_default。
- 数据库群中表的管理默认都是在pg_global中。
- pg_default表空间的物理位置在$PGDATA\base。
- pg_global表空间的物理位置在$PGDATA\global。
关于表:
- 每张表包含三个文件。
- 一个文件用于存储数据,文件名是表的OID。
- 一个文件用于管理表的空余空间,文件名是OID_fsm。
- 一个文件用于管理表块的可见性,文件名是OID_vm。
- 索引没有_vm文件。
3 总结
总体来说,PostgreSQL的架构还是比较容易掌握的。上面总结的也是非常基础的内容,这个对于日常维护还是使用都是非常重要的。