高校倫理1440106 views
世界の国564520 views
Computer368106 views
高校生物551766 views
中学数学623755 views
英語613639 views
高校日本史190571 views
雑学1473612 views
小学理科719870 views
ヒストリア290598 views
Help
Tools
NewsSpreadsheetCalendarSlidesTier ListPen ToolIllustrationCrayonPixel ArtASCII ArtPerspectiveEndless StairsGraphMind MapER DiagramFamily TreeMemeCurved TextImage EditorMosaicRetro FilterPencil SketchOCR/HighlighterMakeup EditorFaviconVideo TrimmerScrolling VideoVideo TitleColor PickerColor ExtractorBonfireFireworksWater RippleWater SplashBreaking GlassWood GrainMarble TextureCSS ButtonIcon MakerBar ChartGrouped Bar ChartStacked Bar ChartPie ChartLine ChartArea ChartStacked Area ChartScatter Plot3D Bar Chart3D Pie ChartBar Chart RaceBubble ChartPopulation PyramidPictogramEarningsCandlestick ChartInvestment RiskMortgage SimulatorCalculatorMatrix CalculatorFunction GraphPolynomial ExpansionVenn DiagramField VisualizerRubik's Cube Group TheoryTraveling SalesmanVoronoi and DelaunayFractalColumn ArithmeticDraw Math FiguresArithmetic AnimationArithmetic Word ProblemsCounting with Tree DiagramsCube NetsCross SectionsMotion PathMechanicsWavesLight and LensesThermodynamicsHow Semiconductors WorkMolecular StructuresAtomic OrbitalsElectrochemical CellsChemical EquilibriumCrystal LatticesBuffer pHComplex IonsDNA Double HelixCell DivisionMembrane ChannelsNerve ImpulseRock ClassificationWeatherConstellationsSolar and Lunar Eclipses3D ModelingFloor PlanSeismic StructuresIntersection TurnMaglevCooking AnimationOrigamiLive Viewer CountGeoJSON MapRailway MapPopulation MapCrime MapLand Price MapSchool MapShrine and Castle MapHouse of Representatives MapWord MapSolitaireReversiHakoiri MusumeChessHamburgerRippleSlide Puzzle MakerNeon PinballNovel MakerJapanese Typing PracticePiano Score EditorMusic Theory

English

ファイルシステムのジャーナリングと Python の書き込み安全性

ファイルに書き込んでいる途中でシステムがクラッシュしたら、データはどうなるのか。ジャーナリングファイルシステムはこの問題に対処するが、Python プログラマも知っておくべき限界がある。

ジャーナリングとは

ジャーナリング(またはジャーナル)は、ファイルシステムの変更を「ログ」に先行記録する仕組みだ。

ジャーナリングなし

書き込み途中でクラッシュすると、ファイルシステムの整合性が壊れる可能性がある。起動時に fsck で全体をスキャンする必要がある

ジャーナリングあり

変更操作をまずジャーナルに記録し、その後で実際のデータを書き込む。クラッシュ後はジャーナルを再生するだけで復旧できる

ext4、XFS、NTFS、APFS など現代のファイルシステムはすべてジャーナリングを採用している。

ジャーナリングの 3 つのモード

ext4 を例にすると、3 つのジャーナリングモードがある。

journal モード

メタデータとファイルデータの両方をジャーナルに記録。最も安全だが最も遅い。

ordered モード(デフォルト)

メタデータのみジャーナルに記録。ただしメタデータを書く前にデータを書き込む順序を保証する。

writeback モード

メタデータのみジャーナルに記録。データとメタデータの順序は保証しない。最速だが危険。

# 現在のマウントオプションを確認
mount | grep "on / "
# /dev/sda1 on / type ext4 (rw,relatime,errors=remount-ro,data=ordered)

ジャーナリングが守るもの、守らないもの

ジャーナリングは「ファイルシステムの整合性」を守るが、「アプリケーションデータの整合性」は守らない。

ジャーナリングが守る

ファイルシステムの構造(ディレクトリ、inode など)の破損を防ぐ

ジャーナリングが守らない

書き込み途中のファイル内容。アプリケーションレベルでの対策が必要

つまり、ファイルに 1000 行書き込む途中でクラッシュした場合、500 行だけ書かれた中途半端なファイルが残る可能性がある。

Python での安全な書き込みパターン

アプリケーションレベルでデータを守るには、アトミックな書き込みパターンを使う。

import os
import tempfile

def atomic_write(filepath, content):
    """中途半端な状態を残さない書き込み"""
    dir_name = os.path.dirname(filepath)
    
    # 同じディレクトリに一時ファイルを作成
    fd, temp_path = tempfile.mkstemp(dir=dir_name)
    try:
        with os.fdopen(fd, 'w') as f:
            f.write(content)
            f.flush()
            os.fsync(f.fileno())  # ディスクへの書き込みを強制
        
        # アトミックにリネーム
        os.replace(temp_path, filepath)
    except:
        os.unlink(temp_path)
        raise

このパターンでは、書き込み途中でクラッシュしても、元のファイルは無傷のまま残る。

fsync() の重要性

write() を呼んでも、データはカーネルのバッファに留まっている可能性がある。ディスクに確実に書き込むには fsync() が必要だ。

write() → Python のバッファに書く

flush() → カーネルのバッファに書く

fsync() → ディスクに書く(これで永続化される)

with open("important.txt", "w") as f:
    f.write("critical data")
    f.flush()            # カーネルバッファまで
    os.fsync(f.fileno()) # ディスクまで書き込む

ジャーナリングファイルシステムでも、fsync() を呼ばない限りデータがディスクに到達する保証はない。

rename のアトミック性

同一ファイルシステム内での rename() / os.replace() は POSIX でアトミックと規定されている。

# この操作はアトミック
os.replace("temp_file.txt", "target_file.txt")

# クラッシュが起きても、以下のどちらかの状態になる:
# 1. リネーム前の状態(temp_file.txt が存在、target_file.txt は古いまま)
# 2. リネーム後の状態(temp_file.txt は削除、target_file.txt は新しい内容)
# 中途半端な状態にはならない

ただし、fsync() でデータをディスクに書き込んだ後に rename() しないと、rename 自体はアトミックでもデータが失われる可能性がある。

データベースとの比較

データベースは WAL(Write-Ahead Logging)という仕組みでより強い保証を提供する。

ファイルシステムのジャーナリング

ファイルシステム構造の整合性のみ保証

データベースの WAL

トランザクションレベルでのデータ整合性を保証。コミットされたデータは必ず永続化される

重要なデータを扱うなら、ファイルに直接書き込むよりも SQLite などのデータベースを使うほうが安全な場合が多い。

まとめ

ジャーナリングの役割

ファイルシステムの構造を守る。アプリケーションデータは守らない。

Python で安全に書き込むには

一時ファイルに書き込み → fsync() → アトミックに rename という手順を踏む。

ジャーナリングを過信せず、アプリケーション側でも適切な対策を取ることが重要だ。