varolan dosyayı atomik olarak yeni sürümle değiştirilecek şekilde yeniden yaz


18

Bazı Unices'te, varolan bir dosyayı yazmak için açmak için bir yol olduğu, çekirdeğin eski sürümü (okuma için erişen diğer işlemler için) kullanmasını isteyen bir bayrakla "yeni "sürüm tamamen yazıldı (fd kapatıldı); bu noktadan sonra dosya yeni sürüm olarak göründü.

Başka bir deyişle, diğer süreçler ya eski sürümü ya da yeni sürümü hiç tam olarak yazılmadı.

Bilgili biri beni referans gösterebilir mi?


Ne gibi Sesler Plan 9 yapabilir, ama hayır.
Gilles 'SO- kötü olmayı kes

2
OpenVMS'de Dosyalar-11 gibi geliyor : "Mevcut sürümün üzerine yazmak yerine her dosya kaydedildiğinde, aynı ada sahip ancak artırılmış bir sürüm numarası olan yeni bir dosya oluşturulur."
Mat

Neden sordun? Bu işlevselliğe mi ihtiyacınız var, yoksa sadece merak mıydı?
Nils

1
Bu işlevselliğe sahip olmaktan memnuniyet duyarım ve var olduğu bir yerde okumayı hatırladım. Yani hem ihtiyaç hem de merakın bir karışımı.
eudoxos

Tüm Unix sistemleri buna başka bir şekilde izin verir - aynı dizinde yeni dosya oluşturun, değiştirilen içeriklerle doldurun ve atomik yeniden adlandırma yapın. Bu, küçük değişiklikler için ama çalışmak için çok daha pahalıdır.
Net

Yanıtlar:


14

Açıkladığınız şey, bir dosyanın üzerine yazmak için tam olarak temel bir yeniden adlandırma gibidir.

Bir dosyayı diğerinin üzerine yeniden adlandırdığınızda / taşıdığınızda, eski dosyanın bağlantısı kaldırılır. Yani dosya hala var, ama artık dosya sistemi ağacında değil. Böylece, eski uygulamalar dosyayı açık tuttukları sürece erişmeye devam edecektir. Tüm uygulamalar eski dosyayı kapattıktan sonra, diskte ayrılmamış.

renameSistem çağrısı atomik bir işlemdir. Bunu yapmak için farklı bir ad altında yeni bir dosya oluşturacak ve daha sonra renamegeçici dosyayı değiştirmek istediğiniz dosya olarak yeniden adlandırmak için çağrı yapacaksınız. İşlem atomik olduğu için, dosyanın eksik olduğu bir dönem kesinlikle yoktur. Anında eski dosyadan yeni dosyaya gider.
Ancak geçici dosyanın ve değiştirilen dosyanın aynı bağlama noktasında bulunması gerektiğini unutmayın.


Bunu yalnızca programınız özellikle işlevsellik göz önünde bulundurularak yazıldıysa kullanabilirsiniz. Ancak bu durumda, bir işletim sistemi özelliğiydi, bu nedenle düzenli programlara bile bu atombilimsel anlambilim otomatik olarak verildi.
eudoxos

1
@eudoxos yorumunuz bir anlam ifade etmiyor. renameTakas şeyler yapmak için programların özel olarak yazılması gerektiğini söylüyorsunuz . Bahsettiğiniz gibi bir 'işletim sistemi özelliği' olsa bile, programın bundan yararlanmak için hala yazılması gerekir. Fark ne?
Patrick

openSistem çağrısına (muhtemelen desteklenmeyen) bir bayrak iletirseniz veya açıkladığınız şeyi elle yapmak zorunda kalırsanız bir fark vardır.
eudoxos

Bir çökme durumunda eski veya tam olarak yazılan yeni sürümü korumak için yeni dosyayı diske fsync veya benzeri ile senkronize etmeniz gerektiğini unutmayın
textshell

@textshell senkronizasyonu olmadan hala atomisite olsun .... sadece dayanıklılık değil ... doğru mu? Bu durumda goo.gl/qfQQfy'daki argümanı anlamıyorum . Benim durumumda aşırı yük altında bir sistemim var ve dosya sistemi yıkımlarından kaçınmak istiyorum ve dosyanın bir çökme içinde hayatta olup olmadığını umurumda değil.
wcochran

6

As Patrick yazıyor zaman bitmiş yeniden adlandırma atomik olarak üzerine yazarak eski dosya adına yeni sürümü, Bunu yapmak için her zamanki gibi ayrı bir dosyaya yeni sürümü yazmaktır ve. Bu ikinci işleme, yeniden adlandırma üzerine yazma adı verilir .

Şimdi, bazı referanslar:


man 3p renamebana bunun renameatomik olduğunu söylüyor ve sanırım bu tüm Linux dosya sistemleri için geçerli. Bağladığınız ilk makaleyi okuduğumda, hala Btrfs yeniden adlandırma işlemlerinin atomik olduğunu düşünüyorum.
hagello

1

Bu bana Flush Allocate'i hatırlatıyor . Bir dosya sistemi bu özelliği kullandığında, verileri doğrudan diske yazmak yerine, diskin boş alan sayacından yazılacak verinin boyutunu çıkarır ve bir senkronizasyon sistemi çağrısı yapılana veya çekirdek karar verene kadar verileri bellekte tutar kirli tamponları temizlemek için.

Bu durumda, dosya bir işlem tarafından değiştiriliyor ve başka bir işlem tarafından açılıyorsa, ikinci işlem dosyanın değiştirilmemiş ( veya isterseniz "eski" sürümünü "görür" ).

Tabii ki, yukarıdaki teorik ve çeşitli faktörlere bağlıdır ve biraz tahmin edilemez söyleyebilirim -çünkü kernel kirli sayfaları ne zaman temizleyeceğini tam olarak bilmiyorsunuz. Örneğin Linux'ta ( Linux Çekirdeğini Anlama bölümünde 15.3 bölümünde de okuyabileceğiniz gibi ), kirli sayfalar aşağıdaki koşullar altında diske yazılır:

  • Sayfa önbelleği çok dolu oluyor ve daha fazla sayfa gerekiyor ya da kirli sayfa sayısı çok fazla oluyor.

  • Bir sayfa kirli kaldığı için çok fazla zaman geçti.

  • Bir işlem, bir blok aygıtında veya belirli bir dosyada bekleyen tüm değişikliklerin temizlenmesini ister; bunu bir sync (), fsync () veya fdatasync () sistem çağrısını çağırarak yapar.

Bu özelliğin HFS +, XFS, Reiser4, ZFS, Btrfs ve ext4 dosya sistemlerinde uygulandığı bilinmektedir.


2
Açıkladığınız, POSIX (dosya) sistemlerinde kullanıcı alanından görünmez olması (ve böylece belirttiğiniz şeyi yapmaması) gereken bir dosya sistemi tekniğidir (bkz. Write : "Dosya verilerinin bir okuması () kanıtlanabilirse (herhangi bir yolla) verilerin yazılmasından () sonra gerçekleşmesi için , aramalar farklı işlemler tarafından yapılmış olsa bile bu write () yöntemini yansıtmalıdır . "). Diğer süreçler olacak değil (POSIX) eski verileri bakın.
Mat

Düzeltme için teşekkürler. Sanırım bu dosya sistemi tekniğiyle ilgili anlayışım yanlıştı.
dkaragasidis

Doğru, bu başka bir şeye benziyor. RMS ile yapılan bir röportajda bu özellikten bahsettiğini belirsiz bir şekilde hatırlıyorum, belki de akademinin dışında yaşamamış bazı eski bir gizemli sistemdi ... Yine de teşekkürler.
eudoxos
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.