sql - 了解 postgreSQL 共享内存

标签 sql postgresql

我看过presentation还有一个关于共享缓冲区工作的问题。如幻灯片 16 所示,当服务器处理传入请求时,postmaster 进程调用 fork() 创建一个子进程来处理传入请求。这是那里的一张照片: enter image description here

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

enter image description here

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

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

最佳答案

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

一种是fork()(没有exec())使用的写时复制共享,子进程继承父进程的内存和状态。在这种情况下,当 child 或 parent 修改任何内容时,将分配修改后的内存页的新私有(private)副本。因此,子级看不到父级在 fork() 之后所做的更改,父级也看不到子级在 fork() 之后所做的更改。同龄 child 也看不到彼此的变化。就内存而言,它们都是孤立的,它们只是共享一个共同的祖先。

该内存显示在图表的Program (text)datastack 部分。

由于这种隔离,PostgreSQL 使用 POSIX 共享内存——或者,在旧版本中,系统 V 共享内存。这些是映射到地址范围的显式共享内存段。每个进程看到相同的内存,并且它不是写时复制。它是完全读/写共享的。

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

POSIX 共享内存用于锁定、shared_buffers 等进程间通信。不是从 fork()ing 继承的内存。

虽然来自fork 的内存通常是写时共享的,但这实际上是一个操作系统实现细节。操作系统可以选择根本不共享它,并在 fork 时为子进程立即复制父进程的整个地址空间。写时复制共享真正相关的唯一方法是查看 top

当 PostgreSQL 提到“共享内存”时,它总是在谈论映射到每个进程地址空间的 POSIX 或 System V 共享内存块。不是来自 fork() 的写时复制共享。

关于sql - 了解 postgreSQL 共享内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32930787/

相关文章:

php - 如何告诉 Paris/ORM 哪个表用于模型?

ruby-on-rails - postgres中的uuid ossp是什么

sql - PostgreSQL:案例:从两个不同的表中选择

sql - 如果唯一 ID,如何编写 SQL 查询来计算第一次出现后 7 天出现包含不同 ID 的行的实例?

mysql - 获取日期或 NOW() Sql 并转换为 int...然后执行 where

php - MySQL "LIKE"搜索不工作

sql - 更新 postgreSQL 首字母大写的列

sql - plpgsql 在返回查询之前对其进行操作

mysql - 如何在 SQL 中将 ID 替换为相应的值?

java - 部署 Vaadin 应用程序