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

标签 c postgresql unix installation mmap

我在 CentOS 5.8 上运行 PostgreSQL 9.2.8。

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

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

根据我自己的测试,这与 pg_stat_statementspg_buffers 完全相同。

为什么会这样?谢谢。

最佳答案

有什么区别?

make install 通常使用 install 命令,该命令删除 然后重新创建 文件。 (这并非天生如此,大多数人的 Makefile 都是这样写的)。

相比之下,cp 只是就地覆盖它。

为什么重要?

UNIX/Linux 系统 mmap 二进制文件在运行时进入内存。这意味着文件内容本质上直接是程序内存的一部分。因此,当您在程序运行时覆盖可执行二进制文件的内容时,事情可能会以令人兴奋的方式繁荣

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

如何做对?

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

显示差异的演示

设置:

$ echo "whatevs" > blah
$ touch /tmp/blah

使用安装:

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
...

对比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
...

请注意如何先安装 取消链接旧文件?至关重要,那个。

另一个区别是,如果一个文件有多个硬链接(hard link),install 不会更改指向同一基础文件的其他链接的内容。 cp 会。

关于c - 当我替换正在运行的 PostgreSQL 服务器使用的 .so 文件时,它崩溃了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24358739/

相关文章:

c - 在 C 中将 const char 参数传递给 static char *argv[] 的语法

C++ 2 嵌套for循环转换为递归

PostgreSQL 根据日期设置表年龄

unix - 如何让磁盘配额满

c - 在 C 中使用 YACC 对 LISP 子集进行操作

c - OpenGL:从读取文件的 while 循环中调用 glutPostRedisplay()

postgresql - Npgsql 抛出错误 : wrong connection string. 无法连接到 postgreSQL [F#]

ruby-on-rails - Rails5/强参数/带有 'dynamic' 键的 json 列

c++ - 如何让我的 C++ 程序在 Unix 上编译?

linux - nohup 不能正常工作