了解postgreSQL共享内存

我已经看过 presentation并且仍然有一个关于共享缓冲区工作的问题.如幻灯片16所示,当服务器处理传入请求时,postmaster进程调用fork()来创建用于处理传入请求的子节点.这是一张照片:
@L_301_1@

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

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

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

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

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

该内存是图中程序(文本),数据和堆栈部分中显示内容.

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

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

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

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

当Postgresql引用“共享内存”时,它总是在谈论映射到每个进程的地址空间的POSIX或System V共享内存块.不是fork()的copy-on-write共享.

相关文章

来源:http://www.postgres.cn/docs/11/ 4.1.1. 标识符和关键词 SQL标识符和关键词必须以一个...
来源:http://www.postgres.cn/docs/11/ 8.1. 数字类型 数字类型由2、4或8字节的整数以及4或8...
来源:http://www.postgres.cn/docs/11/ 5.1. 表基础 SQL并不保证表中行的顺序。当一个表被读...
来源:http://www.postgres.cn/docs/11/ 6.4. 从修改的行中返回数据 有时在修改行的操作过程中...
来源:http://www.postgres.cn/docs/11/ 13.2.1. 读已提交隔离级别 读已提交是PostgreSQL中的...
来源:http://www.postgres.cn/docs/11/ 9.7. 模式匹配 PostgreSQL提供了三种独立的实现模式匹...