我搜索了 Linux 重启过程的工作原理,到处都只找到了引导/启动过程。假设非法重新启动机器如何恢复我正在运行的进程/服务(例如,如果数据库正在运行并且我强制重新启动了机器)?
答案1
受控重启基本上是正常关机,但不是在最后关闭电源,而是应用硬件重置过程,以便固件接管并重新启动系统,本质上就像启动系统时一样。 (如果固件可以检测到系统未从“冷”状态启动,则可以选择缩短或省略某些测试。)
没有系统范围的机制来自动存储系统状态:如果您使用ifconfig
或ip
命令配置了网络接口,但没有编辑适当的配置文件以使配置持久化,该配置将会丢失在任何重新启动时。如果您手动启动了任何服务(例如service <something> start
或systemctl start <something>
),但未启用它们在启动时自动启动(例如chkconfig <something> on
或systemctl enable <something>
),则该服务将不是重启后自动启动。
一些系统管理工具NetworkManager
会自动更新配置文件以保留任何配置更改,除非您明确告诉它不要这样做;其他人则需要采取一项行动才能真正做出改变现在另一个做出改变永恒的。
某些桌面环境可能会尝试并维护用户会话的状态,以便当用户以受控方式注销且某些 GUI 程序仍在运行时,相同的 GUI 程序将在下次登录时自动启动。但不能保证这些程序本身会保持其内部状态:有些程序可能会这样做,有些则不会。 GUI 环境中基于文本的程序可能会将 GUI 注销视为相当于远程 SSH 用户突然失去网络连接:特别是,文本编辑器vi
通常会将任何未保存的数据保存在特殊的备份文件中,以便中断的工作没有丢失。
如果系统以强制方式关闭(例如按硬件重置按钮或拔掉电源线),则所有内容仅存储在 RAM 中将要迷路了。启动时文件系统检查将检测文件系统未正确安装:日志文件系统通常会自动执行日志恢复以保持文件系统元数据内部一致,但除非数据也被记录在日志中,否则您可能会发现某些数据实际上并未到达磁盘(这可能\000
在日志文件中显示为重复的字符串,因为最后分配但未写入的块中只有零字节)。数据库可能还需要在强制关闭后执行某种一致性恢复操作。
正常的、受控的关闭(或重新启动)涉及:
- 向属于用户登录会话的所有进程发送 HUP 信号,以便他们有机会在退出之前执行任何需要执行的操作(例如,保存任何未保存工作的备份)
- 以合理的顺序关闭系统服务,以便依赖于其他服务的服务先于它们所依赖的服务关闭。对于像大型数据库这样的东西,这本身就是一项相当大的任务。
- 如果用户的进程或系统服务没有及时关闭,则首先向它们发送正常的 TERM 信号,给它们多一点时间,最后向它们发送 KILL 信号,以便进程有机会完成或回滚它们可能拥有的任何未完成的任务。但最终,必须终止进程,以便可以关闭它们的所有文件,从而允许文件系统干净地卸载。
- 在剩余运行的进程数量减少到必要的最低限度后,以受控方式卸载任何基于网络的文件系统,确保在卸载之前完成所有缓存的写入操作。
- 关闭与访问网络文件系统相关的任何服务
- 完成对本地磁盘的所有缓存写入操作,然后卸载这些磁盘,但根文件系统除外,根文件系统通常只是切换到只读模式。 (现代文件系统可能会记录它们已在无错误状态下正确卸载的事实,并且在再次安装它们之前无需执行恢复操作。)
- 最后,内核被告知发送硬件信号以关闭电源或重置系统(视情况而定)
在正确配置的系统中,当您使用或命令时,所有这些都由 init 子系统(可能是systemd
经典的 SysVinit 或其他东西)负责。shutdown -h
shutdown -r
如果您使用reboot -f
,则意味着您有意跳过除上述最后一个关闭步骤之外的所有步骤。