假设我有一个进行长时间计算的进程(例如,它已经运行了好几天),它使用磁盘作为临时存储来存储中间结果(例如,安装在/mnt
并且我想替换/dev/sda1
为/dev/sdb1
)。我怎样才能用另一个磁盘替换那个磁盘而不终止该进程并且不会对其造成太大干扰?
这是一个一般性问题,我没有考虑过具体程序。假设我们运行的是最新版本的 Linux。
答案1
如果进程正在使用某个目录来创建和删除临时文件,您可以尝试使用kill -STOP $pid
命令停止它,并查看 /proc/$pid/fd 中打开的文件描述符。
如果没有打开,您可以安全地更改安装位置,复制其文件并继续使用kill -CONT $pid
。
如果仍有一些打开的文件或进程未关闭文件,您可以尝试使用 GDB 迁移文件描述符。我手动尝试过,成功了,但我找到了一些可以为您完成此操作的脚本:http://ingvar.blog.redpill-linpro.com/2010/07/10/changing-a-process-file-descriptor-on-the-fly/
如果进程正在通过网络进行通信,请小心,当您停止它时,连接可能会超时,因此您需要尽快执行此操作(可能先在虚拟进程上测试命令序列并将其作为批处理运行)
虽然我认为这会起作用,但我宁愿不推荐您可以在生产环境中执行此操作。
编辑:您还可以在 /proc/$pid/fd 中看到打开的网络套接字,因此您可以确定进程是否正在使用网络。
答案2
这完全取决于您的进程在使用临时存储时的行为。
如果您的进程在 上打开了一个文件/mnt
,那么您无法替换该设备,否则进程很可能会以某种未定义的方式失败,即使您设法强制卸载该设备也是如此。进程通常不希望打开文件的设备消失。
如果您的进程打开、写入,然后关闭 上的文件/mnt
,您可能能够停止它、卸载并重新安装/mnt
,然后重新启动它。这取决于您是否能够在进程不使用 时停止它/mnt
。因此,您可以
$ kill -STOP pid
$ lsof -p pid | grep /mnt
... then, if it has nothing open on /mnt ...
$ sudo umount /mnt
$ sudo mount /dev/sdb1 /mnt
$ kill -CONT pid
即使你停止没有打开任何文件的进程/mnt
,这也不一定有效,因为你可能中断了一些依赖于/mnt
不变的逻辑;比如
- 检查是否
/mnt/wibble
存在 - 是的!让我们准备打开并阅读它
- ...进程停止,并且不同的设备被安装在
/mnt
... - ...进程重新启动...
- 哦不!
/mnt/wibble
打不开! - 死得很惨
答案3
任何进行数天计算的程序都应设计为定期将足够的状态提交到磁盘。如果重新启动该过程意味着您损失了一个小时的处理时间,那可能没问题,但如果您损失的时间不止一个小时,我会说这个程序设计得很差。
话虽如此,但可能还有其他情况,您确实希望让进程保持更长时间,并能够从其下方替换磁盘。对于这些情况,您应该考虑将文件系统与物理介质分离。
可能的选择包括:
- 使用软件 raid
- 使用其他虚拟块设备层(也许 LVM 合适)
- 使用文件系统,其本身可以使用多个底层设备