合 PG体系结构之内存结构
内存结构
PostgreSQL的内存体系结构可以分为两大类:
- Local memory area 本地内存区域——由每个后端进程分配供自己使用。
- Shared memory area 共享内存区域——由PostgreSQL服务器的所有进程使用。
共享内存区域由PostgreSQL服务器在启动时分配。这个区域也被划分为几个固定大小的子区域。
PostgreSQL启动后,会生成一块共享内存,用于做数据块的缓冲区,以便提高读写性能。WAL日志缓冲区和Clog缓冲区也存在共享内存中,除此之外还有全局信息比如进程、锁、全局统计等信息也保存在共享内存中。
其中最重要的组成部分是Shared Buffer和WAL Buffer。
√ Shared Buffer Pool
PostgreSQL将表和索引中的页面从持久存储加载到这里,并直接操作它们。Shared Buffer的目的是减少磁盘IO。为了达到这个目的,必须满足以下规则∶
当需要快速访问非常大的缓存时(10G、100G等)
如果有很多用户同时使用缓存,需要将内容尽量缩小
频繁访问的磁盘块必须长期放在缓存中
对应的设置参数为:shared_buffers
12345678910C:\Users\lhrxxt>psql -U postgres -plhr -h192.168.66.35 -p 15432Password for user postgres:psql (13.3)Type "help" for help.postgres=# show shared_buffers;shared_buffers----------------128MB(1 row)
√ WAL Buffer
WAL Buffer是用来临时存储数据库变化的缓存区域。存储在WAL Buffer中的内容会根据提前定义好的时间点参数要求写入到磁盘的WAL文件中。为了保证数据不因服务器故障而丢失,PostgreSQL支持WAL机制。WAL data(也称XLOG records)是PostgreSQL中的事务日志;WAL buffer是WAL数据写入持久存储之前的缓冲区域。
在备份和恢复的场景下,WAL Buffer和WAL文件是极其重要的。
√ CommitLOG
提交日志(CLOG)保存所有事务(如in_progress,committed,aborted)的状态,用于并发控制(CC)机制。
本地内存(Local memory area )
每个backend进程分配一个本地内存区域用于查询处理;每个区域又分为几个子区域,子区域的大小可以是固定的,也可以是可变的。非全局存储的数据都存在本地内存中。下表列出了主要的子区域。
表 Local memory area
子区域 | 描述 |
---|---|
work_mem | Executor使用此区域按顺序和不同的操作对元组进行排序,并使用merge-join和hash-join操作来连接表。内部排序操作和Hash表在使用临时操作文件之前使用的存储缓冲区。 |
maintenance_work_mem | 在某些维护操作,例如VACUUM(收集表和索引的统计信息,整理表和索引)、CREATE INDEX、ALTER TABLE ADD FOREIGN Key、Reindex等中都会使用这个区域。 |
temp_buffers | Executor使用此区域存储临时表。用于访问临时表的缓冲区。 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | postgres=# show autovacuum_work_mem; autovacuum_work_mem --------------------- -1 (1 row) postgres=# show maintenance_work_mem; maintenance_work_mem ---------------------- 64MB (1 row) postgres=# show work_mem; work_mem ---------- 4MB (1 row) postgres=# show temp_buffers; temp_buffers -------------- 8MB (1 row) |
除了上面提到的本地内存区域和共享内存区域,PostgreSQL还分配了如下几个区域:
用于各种访问控制机制的子区域,例如,信号量、轻量级锁、共享锁和排他锁等
用于各种后台进程的子区域,如checkpointer和autovacuum。
用于事务处理的子区域,比如保存点和两阶段提交。
等等。