当我替换正在运行的PostgreSQL服务器使用的.so文件时,它会崩溃

KIM*_*KIM 3 c unix postgresql install mmap

我在CentOS 5.8上运行PostgreSQL 9.2.8.

构建我自己的contrib模块,我发现只是extension_name.so通过更改文件cp使服务器进程崩溃,但刷新extension_name.so文件make && make install正常工作.

这看起来很严重,因为服务器进程崩溃会导致意外重新启动集群.

这是完全一样的pg_stat_statements,并pg_buffers根据我自己的测试.

为什么会这样?谢谢.

Cra*_*ger 5

有什么不同?

make install通常使用install命令,删除然后重新创建文件.(这本身并不正确,只是大多数人的Makefile写作方式).

相比之下,cp只需将其覆盖到位.

为什么这有关系?

UNIX/Linux系统mmap在运行时将二进制文件存入内存.这意味着文件内容基本上直接是程序存储器的一部分.所以,当你覆盖,而在程序运行可执行的二进制文件的内容,事情可能去热潮中令人兴奋的方式.

相反,如果删除(取消链接)文件,它仍会映射为匿名文件.它仍然存在,直到它的最后一个句柄关闭,它只是没有文件名.然后使用相同的文件名创建新文件,但不影响现在无法访问的未链接文件的内容.所以没有任何崩溃 - 只要你没有多个程序实例,期望看到相同版本的共享库,至少.

怎么做对了?

如果您坚持要替换正在运行的可执行文件的二进制文件,则应该使用该install命令,或者rm /the/path && cp /new/file /the/path后跟任何必需的chownchmod.

演示显示差异

建立:

$ echo "whatevs" > blah
$ touch /tmp/blah
Run Code Online (Sandbox Code Playgroud)

使用install:

strace -e unlink,open,write install blah /tmp/blah
...
unlink("/tmp/blah")                     = 0
open("blah", O_RDONLY)                  = 3
open("/tmp/blah", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4
write(4, "whatevs\n", 8)                = 8
...
Run Code Online (Sandbox Code Playgroud)

vs cp:

$ strace -e unlink,open,write cp blah /tmp/blah
...
open("blah", O_RDONLY)                  = 3
open("/tmp/blah", O_WRONLY|O_TRUNC)     = 4
write(4, "whatevs\n", 8)                = 8
...
Run Code Online (Sandbox Code Playgroud)

请注意install unlink旧文件首先如何?至关重要的是.

另一个区别是install,如果文件有多个硬链接,则不会将其他链接的内容更改为相同的基础文件.cp将.