了解postgreSQL共享内存

St.*_*rio 8 sql postgresql

我看过演示文稿,但仍然有一个关于共享缓冲区工作的问题.如幻灯片16所示,当服务器处理传入请求时,postmaster进程调用fork()以创建用于处理传入请求的子节点.这是一张照片: 在此输入图像描述

因此,除了它之外,我们拥有postmaster流程的完整副本pid.现在,如果子进程更新属于共享内存的某些数据(放入共享缓冲区,如幻灯片17所示),我们需要其他线程知道这些更改.图片:

在此输入图像描述

同步化过程是我不明白的.任何进程都拥有共享内存的副本,并且在复制时不知道另一个线程是否会将某些内容写入共享内存的副本.如果proc1通过调用创建后,稍后创建fork()另一个进程proc2并开始在共享内存的副本中写入内容,该怎么办?

问题:如何proc1知道如何处理被修改的共享内存部分proc2

Cra*_*ger 8

要理解的关键是使用了两种不同类型的内存共享.

一个是fork()(没有exec())使用的写时复制共享,其中子进程继承父进程的内存和状态.在这种情况下,当子或父修改任何内容时,将分配修改的内存页面的新私有副本.因此,孩子看不到父母做出的改变fork(),父母看不到孩子做出的改变fork().同龄儿童也看不到彼此的变化.就记忆而言,它们都是孤立的,它们只是共享一个共同的祖先.

这记忆是什么在所示的界面Program (text),data以及stack图的部分.

由于这个问题,PostgreSQL 使用POSIX共享内存 - 或者在旧版本中使用系统V共享内存.这些是显式共享的内存段,映射到一系列地址.每个进程都看到相同的内存,并且它不是写时复制.它完全读/写共享.

这是图中紫色"共享内存"部分所示的内容.

POSIX共享内存用于进程间通信,用于锁定,共享缓冲区等.不是内存继承自fork()ing.

虽然内存fork通常是共享写时复制,但这实际上是一个操作系统实现细节.操作系统可以选择不共享它,并立即复制父母的整个地址空间fork.写拷贝共享真正相关的唯一方法是查看top等.

当PostgreSQL引用"共享内存"时,它总是在谈论映射到每个进程的地址空间的POSIX或System V共享内存块.不是来自的写时共享fork().