
假設我有一個進行長時間計算的進程(例如它已經運行了幾天),它使用磁碟作為臨時存儲來存儲中間結果(例如安裝在/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
任何進行持續數天計算的程式都應該設計為定期向磁碟提交足夠的狀態。如果重新啟動進程意味著您失去一個小時的處理時間,那可能沒問題,但如果您損失的時間超過這個時間,我會稱該程式設計不當。
也就是說,可能還有其他情況,您確實希望使進程保持更長時間的活動狀態,並且能夠從其下方更換磁碟。對於這些情況,您應該考慮將檔案系統與實體媒體解耦。
可能的選項包括:
- 使用軟體突襲
- 使用其他虛擬區塊設備層(也許LVM適合)
- 使用檔案系統,它本身可以使用多個底層設備