Mengapa mematikan mesin saya setelah `rm` yang buruk menyimpan file saya?

31

Situasi klasik: Saya mengalami masalah rmdan segera menyadari bahwa saya telah menghapus file yang salah. (Tidak ada yang penting dan saya memiliki cadangan yang lumayan baru-baru ini, tetapi masih menjengkelkan.)

Mengetahui bahwa aktivitas disk selanjutnya adalah musuh saya jika saya ingin memulihkan file dengan extundeleteatau alat semacam itu, saya segera mematikan mesin secara fisik (yaitu, dengan tombol daya, bukan dengan haltatau perintah semacam itu). Ini adalah laptop tanpa menjalankan tugas penting atau apapun yang terbuka, jadi ini adalah operasi yang dapat diterima. (Omong-omong, saya belajar sejak saat itu bahwa hal pertama yang harus dilakukan dalam situasi seperti itu adalah memperkirakan dulu jika file yang hilang masih dapat dibuka oleh proses https://unix.stackexchange.com/a/101247 - jika ya, Anda harus memulihkannya dengan cara ini alih-alih mematikan mesin.)

Namun, begitu mesin dimatikan saya pikir untuk sementara waktu dan memutuskan file tidak sepadan dengan investasi waktu boot sistem live untuk forensik yang tepat. Jadi saya menyalakan mesin. Dan kemudian saya menemukan bahwa file saya masih duduk di disk: rmbelum disebarkan ke disk sebelum saya dimatikan. Saya melakukan sedikit tarian dan berterima kasih kepada dewa sysadmin atas pengampunan-Nya yang tak terduga.

Pertanyaan saya sekarang adalah untuk memahami bagaimana ini mungkin, dan apa penundaan khas sebelum rmbenar-benar disebarkan ke disk. Saya tahu bahwa disk IO tidak segera memerah tetapi itu duduk di memori untuk beberapa waktu, tetapi saya berpikir bahwa jurnal disk akan memastikan dengan cepat bahwa operasi yang tertunda tidak sepenuhnya hilang. https://unix.stackexchange.com/a/78766 tampaknya mengisyaratkan mekanisme terpisah untuk menyiram halaman kotor dan menyiram operasi jurnal tetapi tidak memberikan detail yang cukup tentang bagaimana jurnal akan terlibat untuk rm, dan penundaan yang diharapkan sebelum operasi memerah.

Beberapa perincian lebih lanjut: data berada di partisi ext4 di dalam volume LUKS, dan ketika mem-boot mesin cadangan saya melihat yang berikut ini di syslog:

Sep 24 10:24:58 gamma kernel: [   11.457007] EXT4-fs (dm-0): 1 orphan inode deleted
Sep 24 10:24:58 gamma kernel: [   11.458393] EXT4-fs (dm-0): recovery complete
Sep 24 10:24:58 gamma kernel: [   11.482475] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Opts: (null)

tapi saya tidak yakin itu terkait dengan rm.

Pertanyaan lain adalah apakah ada cara untuk memberitahu kernel untuk tidak melakukan operasi disk yang tertunda (melainkan, katakanlah, buang mereka di suatu tempat), daripada mematikan mesin. (Tentu saja, kedengarannya berbahaya untuk tidak melakukan operasi yang tertunda, tetapi inilah yang akan terjadi ketika mematikan mesin, dan beberapa kasus itu bisa menyelamatkan Anda.) Ini akan menjadi "lebih bersih", tentu saja, dan juga menarik untuk server jarak jauh mis. di mana powerdown fisik bukanlah pilihan yang mudah.

a3nm
sumber

Jawaban:

22

Sepertinya Anda memiliki pemahaman yang baik tentang apa yang terjadi.

Ya, karena Anda mematikan sistem sebelum perubahan dilakukan ke disk, mereka ada di sana saat Anda mem-boot up.

Sistem menyimpan semua cache sebelum membuangnya ke disk. Ada beberapa opsi yang mengontrol perilaku ini, semuanya terletak di /proc/sys/vm/dirty_* [ kernel doc ] . Kecuali jika flush secara eksplisit dilakukan oleh aplikasi melalui fsync() [ man 2 fsync ] , data akan dikomit ketika cukup lama, atau cache tulis sudah terisi.
Definisi "data" seperti yang digunakan di atas termasuk modifikasi pada entri direktori untuk menghapus file.

Nah, untuk jurnal, itulah salah satu kesalahpahaman umum tentang apa jurnal itu dibuat. Tujuan jurnal bukan untuk memastikan perubahan diputar ulang, atau bahwa data tidak hilang. Tujuan dari jurnal adalah untuk mencegah korupsi pada sistem file itu sendiri, bukan file di dalamnya. Jurnal ini hanya berisi informasi tentang perubahan yang dibuat, dan bukan (biasanya) data lengkap dari perubahan itu sendiri. Detail yang tepat tergantung pada sistem file, dan mode jurnal. Untuk ext3 / 4, lihat dataopsi pemasangan di man 8 mount.


Untuk menjawab pertanyaan tambahan Anda apakah ada cara untuk mencegah penulisan yang tertunda tanpa reboot:

Dari melakukan pembacaan cepat melalui kode sumber kernel, sepertinya Anda dapat menggunakan uperintah sysrq ajaib ([ wikipedia ], [ kernel doc ]) untuk melakukan operasi darurat read-only-read-only. Tampaknya ini akan segera mengirim ulang semua volume yang hanya dapat dibaca tanpa operasi sinkronisasi.

Untuk menggunakan ini, cukup tekan Alt+ SysRq+ u.

Patrick
sumber
1
Terima kasih atas jawaban ini! Saya masih sedikit bingung tentang jurnal: haruskah saya menganggapnya sebagai sesuatu yang hanya terlibat ketika perubahan dibilas ke disk, sehingga menulis cache adalah satu-satunya mekanisme yang relevan untuk memperkirakan waktu tenggang sebelum rmtulisan ditulis? Dengan kata lain, hal-hal yang dilakukan untuk jurnal hanya ketika menulis baru saja akan dilakukan? Atau gambar lebih kompleks dari itu? Sedangkan untuk alt-sysrq-u, ini adalah ide yang cukup rapi. Apakah Anda memiliki referensi untuk diberikan untuk klaim "Tampaknya"? (Tampaknya tidak mengikuti tautan yang Anda berikan.) Terima kasih! :)
a3nm
Juga, sysrq ajaib juga memiliki batasan bahwa Anda masih tidak dapat melakukannya pada mesin jarak jauh.
a3nm
3
@ a3nm Anda dapat menggunakan sysrq pada mesin jarak jauh. echo u > /proc/sysrq-trigger(Anda mungkin perlu mengaktifkannya terlebih dahulu).
Paulo Almeida
Jurnal tidak berurusan dengan konten file (secara default, dapat diubah sepenuhnya-jurnal), hanya dengan metadata sistem file, tetapi dalam hal ini bisa menghapus file , karena kita sedang berurusan dengan menghapus entri direktori. Dengan demikian jurnal harus memastikan bahwa file tersebut ada (dengan konten sebelumnya, dengan asumsi mereka tidak memiliki perubahan lain) atau tidak.
Ángel
@ a3nm Mengenai komentar jurnal Anda. Cache tulis berada di antara jurnal dan disk. Ketika Anda menulis ke sistem file, jurnal diperbarui, lalu sistem file, tetapi belum ada yang berkomitmen untuk disk.
Patrick
2

Dari: https://www.kernel.org/doc/Documentation/filesystems/ext4.txt

commit = nrsec (*) Ext4 dapat diperintahkan untuk menyinkronkan semua datanya dan metadata setiap detik 'nrsec'. Nilai default adalah 5 detik. Ini berarti bahwa jika Anda kehilangan kekuatan Anda, Anda akan kehilangan sebanyak 5 detik kerja terbaru (sistem file Anda tidak akan rusak, terima kasih untuk penjurnalan). Nilai default ini (atau nilai rendah apa pun) akan merusak kinerja, tetapi bagus untuk keamanan data. Mengaturnya ke 0 akan memiliki efek yang sama dengan membiarkannya pada pengaturan default (5 detik). Menetapkannya ke nilai yang sangat besar akan meningkatkan kinerja.

Juga lihat di sini tentang cara membersihkannya: Bagaimana Anda mengosongkan buffer dan cache pada sistem Linux?

Dikutip dari tautan di atas:

CATATAN: bersihkan memori dari hal-hal yang tidak perlu (Kernerl 2.6.16 atau yang lebih baru). Selalu pastikan untuk menjalankan sinkronisasi terlebih dahulu untuk membersihkan hal-hal berguna ke disk !!!

To free pagecache:

$ echo 1 > /proc/sys/vm/drop_caches

To free dentries and inodes:

$ echo 2 > /proc/sys/vm/drop_caches

To free pagecache, dentries and inodes:

$ echo 3 > /proc/sys/vm/drop_caches
David
sumber
Terima kasih atas jawaban ini! Namun, saya tidak mengerti ini: adapun "sinkronisasi" yang disebutkan di sini commit=nrsec, apakah ini sesuatu yang akan terjadi setelah kernel memutuskan untuk menyiram perubahan dari memori ke disk? Atau apakah pengaturan commit=1menjamin bahwa semua perubahan akan memerah setelah 1 detik terlepas dari dirty_expire_centisecsdan dirty_writeback_centisecspengaturan?
a3nm
Kernel akan menyiram (menyinkronkan) setiap cache / buffer ke disk setiap 1 detik untuk commit=1. Sejauh yang saya mengerti, syncmemaksa segalanya terjadi terlepas dari Pengaturan Memori Virtual meskipun itu bisa terjadi lebih cepat.
David
Juga karena alasan kinerja, (dan umur panjang penyimpanan) yang berkomitmen untuk lebih rendah dari standar tidak disarankan.
David