本篇总结一下pg数据库相关的物理结构以及表,索引这些文件到底是什么样的。
如果你有安装好的pg数据库,当你执行ps -ef | grep postgres时,你会得到这样一个信息。
简单说一下下面的子进程
checkpointer(检查点进程):负责刷脏(将缓冲池的脏数据刷新到磁盘),清理过期得wal日志,会将检查点记录写入wal文件。默认300秒执行一次。
background writer(后台写入器):负责多次少量的将脏页写入硬盘,减少检查点进程一次性写入造成io的影响。默认200ms执行一次。
walwriter(wal日志写入器):将wal缓冲区的数据写入wal日志中,在wal段被写满或者归档日志写满时执行。
autovacuum launcher(自动清理守护进程):会向主进程请求创建创建vacuum进程,比如vacuum free(冻结表age),vacuum analyze(将被标记删除的元组标记为可用)。
archiver(归档日志):将被切换的walr日志收集到归档目录下。
stats collector(统计信息收集器):收集表和索引访问的统计信息,行级别的操作统计信息,像autovacuum 进程就是根据统计信息有没有达到阈值来判断是否需要执行。
logging collector(错误日志写入器):负责将错误消息写入日志文件。
看下红框的部分的bin目录,可以看到有各种工具initdb初始化数据库,pg_dump导入导出备份数据,pg_ctl启停数据库等等。
而这个postgres进程作用有很多比如:连接管理,进程管理,就是第一张图中的那些子进程,共享内存和进程间通信,错误处理和日志记录(pg_log)。
-D这个参数就是指向数据目录,/data/pg_data/。
该目录下有base文件夹有实际存放表和索引等对象的物理文件,pg_version数据库的版本号,pg_hba.conf连接访问管理,postgresql.conf参数管理文件,pg_wal流日志目录。我这没有pg_log目录因为没有开日志。
打个比方,pg_data目录像是一个仓库,postgres进程是仓库管理员。用户是一个从仓库取物品的用户,当用户从客户连接数据库发送sql时。
postgres就会从pg_hba文件验证这个用户有没有权限,有权限就会单独为这个用户开启一扇门(建立一个子进程)让这个用户进仓库拿取自己想要的物品。
有时可能需要别的工具来帮忙比如pg_dump,而仓库的物品就是表等对象,这个仓库有一规则就是postgresql.conf文件来进行限制。那些用户拿了什么物品都会记录到pg_log目录文件里。
pg数据库内部是通过隐藏字段oid来进行管理数据库对象
一般新建的表oid和relfilenode两个字段一样,但是当对表进行dml操作比如truncate后relfilenode字段的值就会改变。
/data/pg_data/base可以看到这个目录跟上面说的一样后面的16385就是test数据库的oid每个数据库都有独立的oid,后面的16422就是表的relfilenode文件也就是物理文件,16424是random_data表的id索引。在物理层面上跟表的物理文件一致。
不同的是索引文件默认就会占用8K的空间,8K就是pg数据库中一页(也可以叫区块)的大小。与之相比mysql一页大小是16K。如果了解过mysql的文件结构应该知道在mysql中有这样一个概念就是表空间>段>区>页>行的文件结构。
在pg中也有类似的概念,但不可以直接将mysql中的含义直接套用到pg中。
可以通过\db查看表空间,表空间可以任意新建在指定的文件系统下。建表时也可以通过关键字指定建在那个表空间下,也可以更改默认的表空间。
上图中的16422就是一个文件段,可以设置段大小一般为1G,如果超过1G就会16422.1 16422.2 16422.3这样的延申下去。
而在pg中可能应该这样分类:表空间>段(relfilenode字段的实际文件)>区块(页)>堆元组