信号处理
本文档提供有关 KeyDB 如何响应不同 POSIX 信号(如 SIGTERM
、SIGSEGV
等)接收的信息。
#
SIGTERM 的处理SIGTERM
信号通知 KeyDB 优雅地关闭。当收到此信号时,服务器实际上并不会立即退出,而是会安排一个关闭过程,这与执行 SHUTDOWN
命令时的关闭过程非常相似。计划的关闭会尽快开始,具体来说,是在当前执行的命令(如果有的话)终止后,可能会有 0.1 秒或更短的额外延迟。
如果服务器被一个耗时过长的 Lua 脚本阻塞,且该脚本可以用 SCRIPT KILL
终止,则计划的关闭将在脚本被终止后或其自发终止后立即执行。
在这种情况下执行的关闭包括以下操作:
- 如果有一个后台子进程正在保存 RDB 文件或执行 AOF 重写,该子进程将被终止。
- 如果 AOF 已激活,KeyDB 会在 AOF 文件描述符上调用
fsync
系统调用,以将缓冲区刷新到磁盘。 - 如果 KeyDB 配置为使用 RDB 文件进行磁盘持久化,将执行一次同步(阻塞式)保存。由于保存是以同步方式执行的,因此不会使用额外的内存。
- 如果服务器以守护进程方式运行,pid 文件将被删除。
- 如果启用了 Unix 域套接字,它将被删除。
- 服务器以零退出码退出。
如果 RDB 文件无法保存,关闭将失败,服务器会继续运行以确保数据不丢失。除非收到新的 SIGTERM
信号或发出 SHUTDOWN
命令,否则不会再尝试关闭。
#
SIGSEGV、SIGBUS、SIGFPE 和 SIGILL 的处理以下信号被处理为 KeyDB 崩溃:
- SIGSEGV
- SIGBUS
- SIGFPE
- SIGILL
一旦捕获到这些信号之一,KeyDB 会中止任何当前操作并执行以下操作:
- 在日志文件中生成一份错误报告。这包括堆栈跟踪、寄存器转储以及有关客户端状态的信息。
- 执行快速内存测试,作为对崩溃系统可靠性的初步检查。
- 如果服务器以守护进程方式运行,pid 文件将被删除。
- 最后,服务器会注销其自身对收到的信号的处理程序,并再次向自身发送相同的信号,以确保执行默认操作,例如将核心转储到文件系统。
#
当子进程被终止时会发生什么当执行“仅追加文件”(AOF)重写的子进程被信号终止时,KeyDB 会将其视为一个错误,并丢弃(可能不完整或已损坏的)AOF 文件。重写将在稍后重新触发。
当执行 RDB 保存的子进程被终止时,KeyDB 会将此情况视为更严重的错误,因为缺少 AOF 文件重写的影响是 AOF 文件变大,而 RDB 文件创建失败的影响是缺乏持久性。
由于生成 RDB 文件的子进程被信号终止,或者当子进程以错误(非零退出码)退出时,KeyDB 会进入一种特殊的错误状态,不再接受任何写命令。
- KeyDB 将继续响应读命令。
- KeyDB 将对所有写命令回复一个
MISCONFIG
错误。
只有当能够成功创建 RDB 文件时,此错误状态才会被清除。
#
终止 RDB 文件而不触发错误条件然而,有时用户可能希望在不产生错误的情况下终止 RDB 保存子进程。这可以通过使用特殊信号 SIGUSR1
来实现,该信号的处理方式很特殊:它会像其他任何信号一样终止子进程,但父进程不会将此检测为严重错误,并将继续像往常一样处理写请求。