Windows I/Oの深層(第5回) ── NTFSの内部構造:MFTから理解するファイルシステム

· · Windows, NTFS, I/O, ファイルシステム, MFT, カーネル, .NET, 不具合調査

ここまでの4回で、I/O要求がどう流れ(第1〜3回)、キャッシュがどう受け止めるか(第4回)を見てきました。要求は最後にファイルシステムへ届きます。今回はその代表、NTFSの番です。

視点が変わります。これまでは「要求の流れ」という動的な話でした。今回はディスクの上にデータがどう置かれているかという静的な構造の話です。ダウンロードしたファイルに付く見えない「Zone.Identifier」の正体。小さいファイル1万個のコピーが、同じ合計サイズの1ファイルよりずっと遅い理由。「NTFSはジャーナリングだから安心」がどこまで本当か──全部この構造から説明できます。

連載「Windows I/Oの深層」の第5回です。

1. まず結論

  • NTFSの中心はMFT(マスターファイルテーブル)です。全ファイルがMFT内のレコードとして台帳管理され、ファイルに関するすべての情報は「MFTエントリの中」か「エントリが指すMFT外の領域」にあります(2章)。1
  • ファイルの実体は「属性の集合」です。小さいファイルはデータ本体ごとMFTレコード内に収まり(常駐)、大きいファイルはクラスター列への参照だけを持ちます(非常駐)。小ファイル大量処理の遅さはここから説明できます(2章)。1
  • データは複数持てます(複数データストリーム)。普段のデータは「名前のないストリーム」で、file.txt:名前 で追加のストリームを持てます。Zone.Identifier(Mark of the Web)の正体です(3章)。2
  • 名前も属性です。同じレコードに複数の名前を付けたものがハードリンク。8.3短縮名も「もう一つの名前」として同居しています(4章)。34
  • リパースポイントは「開いたら別の場所」の公式な仕掛けです。シンボリックリンク・ジャンクション・OneDrive のファイルオンデマンドは、みなこのタグ付きデータの応用です(5章)。56
  • ジャーナルは2つあります。$LogFileメタデータ整合性の回復用(壊れないための先行ログ)、USNジャーナル変更履歴の記録用(何が変わったかの台帳)。役割がまったく違います(6章)。78
  • 「サイズ」と「ディスク上のサイズ」は別物です。スパースファイルと圧縮が乖離を生みます。第2回で見た「圧縮ファイルは非同期にならない」の背景もここにあります(7章)。910

2. すべてはMFTのレコードである

2.1. ボリュームの台帳

NTFSボリュームをフォーマットすると、MFT(master file table)と、$ で始まる一連のメタデータファイルが作られます。MFTには、ボリューム上のすべてのファイルについて少なくとも1つのエントリがあり、MFT自身のエントリも含まれます1

NTFSボリュームレコードが位置を指す$MFT ── マスターファイルテーブル全ファイルのレコードの台帳(自分自身も載っている)ユーザーデータ領域(非常駐データの置き場所)$LogFile ── メタデータ操作のトランザクションログ(6章)$Bitmap ── クラスターの使用状況$Boot / $Secure / $UpCase などその他のメタデータファイル

図1: NTFSボリュームの構造。「ファイルシステム自身の管理情報もファイルとして持つ」のがNTFSの設計

ファイルに関する情報──サイズ、タイムスタンプ、アクセス許可、そしてデータの内容まで──は、MFTエントリの中に格納されるか、MFTエントリが位置を記述するMFT外の領域に格納されます1 ファイルを削除するとエントリは「空き」としてマークされ再利用されますが、MFT自体は縮みません。また、MFTを連続的に保つためにMFTゾーンという領域が予約されており、ボリュームが埋まってくるとMFTの断片化が始まる──という寿命の話まで、公式ドキュメントに書かれています。1

2.2. ファイル=属性の集合、常駐と非常駐

ファイルレコードの中身は属性のリストです。標準情報(タイムスタンプ等)、ファイル名、セキュリティ、そしてデータ。ここで大事な分岐があります。

MFTファイルレコード(1ファイルぶんの台帳)数百バイト程度までそれ以上標準情報属性タイムスタンプ・属性フラグファイル名属性(複数持てる ── 4章)データ属性データは小さいか常駐(resident)データ本体がレコード内に収まる読み出しはMFTアクセスだけで完結非常駐(non-resident)レコードには「クラスター列への参照」だけ実データはユーザーデータ領域に

図2: ファイルレコードは属性の集合。データが小さければレコード内に「常駐」する

この構造から、現場で出会う現象がいくつも説明できます。

  • 小ファイル1万個のコピーが遅い理由。1ファイルごとにMFTレコードの作成・名前の登録・セキュリティ設定というメタデータ操作が発生します。データ転送そのものより台帳仕事が支配的になるのです(そしてその1つ1つが、第6回で見るフィルターの検査対象にもなります)。
  • 断片化の正体。非常駐データは「クラスターの連続区間(ラン)の列」として記録されます。連続領域が取れないとランの数が増え、読み出しに必要なシークが増える──これが断片化です。ランの実際の並びは fsutil file layout で覗けます。
  • 「フォルダー」も特別ではない。ディレクトリは「ファイル名からMFTレコード番号への索引(インデックス)を持つファイル」です。台帳の上では、すべてが同じ仕組みの上に乗っています。

3. データは「ストリーム」の1つにすぎない

3.1. 1つのファイル、複数のバイト列

NTFSでは、1つのファイルが複数のデータストリームを持てます。普段 ReadFile/WriteFile で読み書きしているのは名前のない既定ストリームで、ファイル名:ストリーム名 という構文で代替データストリーム(ADS)を作れます。2

report.docx というファイル(1つのMFTレコード)既定ストリーム(無名)= 普段見ている中身:Zone.Identifier出所情報(Mark of the Web):任意の名前アプリ独自の付加情報

図3: 複数データストリーム。エクスプローラーのサイズ表示に出るのは既定ストリームだけ

いちばん身近なADSが Zone.Identifier です。ブラウザーでダウンロードしたファイルには、このストリームに出所(インターネット由来である等)が記録され、SmartScreenの「WindowsによってPCが保護されました」やOfficeの保護ビューの判定材料になります。この仕組みの表側は「Windowsで「Windows によって PC が保護されました」が出る理由」で扱いました──裏側の正体は、ただのNTFSストリームだったわけです。

3.2. 開発者が踏む落とし穴

  • 見えない。エクスプローラーのサイズにも dir の一覧にも出ません。dir /r かSysinternalsの streams で確認できます。11
  • 運べない。ADSはNTFSの機能なので、FATのUSBメモリやクラウドストレージ経由のコピーでは失われがちです。「ダウンロード警告がコピーしたら消えた」はこれです。
  • 自分のアプリでも開ける。CreateFile("data.txt:meta", ...) のようにパスにコロンを含めるだけで読み書きできます。2 便利ですが、前項の「運べない」性質ごと引き受けることになるため、業務データの本体を入れる場所ではありません。

4. 名前もまた属性である ── ハードリンクと8.3名

4.1. ハードリンク ── 同じレコードへの複数の名前

図2で「ファイル名属性は複数持てる」と書きました。同一ボリューム内で、複数のパスが単一のファイルを参照する──これがハードリンクです(CreateHardLink / mklink /H)。3

C:\backup\ のインデックスC:\app\ のインデックスconfig-link.json → レコード#1234config.json → レコード#1234MFTレコード#1234データ本体(またはランへの参照)リンク数: 2

図4: ハードリンク。ディレクトリの索引が同じMFTレコードを指しているだけで、どちらも「本物」

どの名前から変更しても同じファイルなので内容は即座に一致します。3 そして「削除」の意味が変わります──DeleteFile は「名前を1つ外す」であり、最後の名前が外れ、開いているハンドルが閉じ、さらにメモリマップのセクションなどカーネル内の参照もすべて消えたときに初めて実体が消えます。第1回で見たcleanup(最後のハンドル)とclose(最後の参照)の2段階が、削除の寿命にもそのまま効いているわけです。なお属性の表示には癖があり、あるリンク経由で属性を変えても他のリンクの見かけ上の表示が古いまま、といった挙動が公式に注記されています。3

4.2. 8.3名 ── もう一つの隠れた名前

歴史的互換性のため、NTFSは長いファイル名に対して REPORT~1.DOC のような8.3形式の短縮名を自動生成できます。これも「もう一つの名前」としてレコードに同居します。大量のファイルがあるフォルダーでは短縮名の生成・衝突回避がコストになるため、fsutil 8dot3name で生成の無効化や既存短縮名の除去ができます(レジストリパスを短縮名で記録している古いアプリがあると壊れるので、strip前の検査機能があるのも実務的なポイントです)。4

パスと名前をめぐる落とし穴(MAX_PATH、予約名、末尾ドット)は「MAX_PATHとWindowsのパス・ファイル名の落とし穴」で詳しく扱っています。第1回の名前解決(オブジェクトマネージャー)とこの章(ファイルシステム内の名前)を合わせると、Windowsの「名前」の全体像になります。

5. リパースポイント ── 「開いたら別の場所」の仕掛け

ファイルやディレクトリにはリパースポイントを付けられます。実体は「タグ+ユーザー定義データ」という属性です。ファイルシステムがリパースポイント付きのファイルを開くと、タグに応じて処理が乗っ取られます──タグを理解するフィルタードライバーが処理を引き受けるか、名前の付け替え系のタグならリンク先のパスで解決がやり直されます。5

NTFSI/OマネージャーアプリNTFSI/Oマネージャーアプリ対象にリパースポイント発見タグとデータを返すタグを理解するフィルターが処理を引き受ける(第6回)alt[シンボリックリンク/ジャンクション(名前の付け替-え)][フィルター管理のタグ(クラウドファイル等)]CreateFile("C:\data\link.txt")IRP_MJ_CREATE(第1回の世界)「本当の場所はこちら」リンク先のパスで解決をやり直す

図5: リパースポイントの解決。「開く」という操作に割り込む公式のフックになっている

この1つの仕掛けの上に、見慣れた機能が並んでいます。

  • シンボリックリンク(mklink)──リンク先パスを保持する標識。別ボリュームやUNCパスも指せます。6
  • ジャンクション/マウントポイント──ディレクトリを別のローカルボリュームの位置へつなぐ古参の仕組み。3
  • OneDriveのファイルオンデマンド──実データが手元にないファイルをリパースポイントで表現し、開かれた瞬間にフィルターがダウンロードして中身を差し出します。「エクスプローラーには見えるのに、開くと通信が走る」の正体です(フィルターの仕組み自体は第6回で)。

実務の注意はひとつ。「パスの先が本当にローカルのその場所とは限らない」ことです。再帰的にツリーを辿るツールがジャンクションでループする、サイズ集計が二重になる、バックアップがクラウドの実体化を大量に引き起こす──リパースポイントの存在を知らないコードは、これらを踏みます。FindFirstFile 系の属性 FILE_ATTRIBUTE_REPARSE_POINT の確認が対策の入口です。5

6. 2つのジャーナル ── $LogFileとUSN

「NTFSはジャーナリングファイルシステム」とよく言われますが、NTFSには役割の違う2つのジャーナルがあります。混同すると保証を読み違えます。

USNジャーナル ── 変更履歴(何が変わったかを知るため)ファイル/ディレクトリへの変更のたびに変更内容と名前を記録バックアップ・検索インデックス・同期ツールが「前回から何が変わったか」を全走査なしで把握$LogFile ── 先行ログ(壊れないため)メタデータ操作(レコード更新・名前変更等)を実行前にログへ記録システム障害後の次回起動時にログを再生して構造の整合性を回復

図6: 2つのジャーナル。$LogFileは「壊さない」ため、USNは「変更を知る」ため

  • $LogFile(トランザクションログ)は、メタデータ操作の先行ログです。システム障害が起きても、NTFSは次回起動時にこのログとチェックポイント情報からファイルシステムの整合性を自動回復します。7 ここで守られるのは構造です。第4回で見たとおり、キャッシュ上のダーティなデータ内容は電源断で失われうる──「ボリュームは壊れない。しかし最後の書き込みは消えうる」が正しい読み方です。
  • USNジャーナル(変更ジャーナル)は、ボリューム内のファイルやディレクトリに変更が起きるたびに、変更の内容と対象の名前を記録していく台帳です。8 バックアップやインデクサーが「前回から変わったものだけ」を全走査なしで拾うための仕組みで、障害後のインデックス再構築の回避にも使われます。8 実務では、FileSystemWatcher の取りこぼし(「FileSystemWatcher実務ガイド」)を補う突き合わせ台帳として fsutil usn readjournal を調査に使えることを覚えておくと役立ちます。

7. スパースと圧縮 ── 「サイズ」が二つある話

NTFSでは、ファイルの論理的な長さ実際に割り当てられた領域が別々に管理されます。プロパティ画面の「サイズ」と「ディスク上のサイズ」です。乖離を生む代表が2つあります。

スパースファイルは、ゼロが続く範囲に実領域を割り当てず「穴」として管理します。9 論理サイズ42GBの仮想ディスクファイルが、ディスク上では500MBしか使っていない──が普通に起こります。穴を読めばゼロが返り、書けばそのぶんだけ割り当てられます。

ディスク上の割り当て(15MB+管理情報)論理的なファイル(サイズ: 1GB)ラン: R1の実体ラン: R2の実体データ 10MB穴(ゼロ) 500MBデータ 5MB穴(ゼロ) 残り

図7: スパースファイル。「穴」には割り当てが無く、論理サイズとディスク上のサイズが乖離する

NTFS圧縮は、データを圧縮ユニット単位で圧縮して格納します。10 透過的で便利ですが、コストも透過的ではありません──読み書きのたびに展開・再圧縮が走り、断片化も進みやすくなります。そして第2回5章で見たとおり、圧縮ファイルへのアクセスは非同期になりません(ファイルシステムが同期に変換します)。「非同期I/Oにしたのに速くならないファイルがある」ときに疑う場所の一つです。

割り当てベースの実サイズは GetCompressedFileSize で取得できます。「ファイルサイズの合計」と「ディスク使用量」が合わない調査では、スパース・圧縮・ADS(3章)・クラスター切り上げの4つを順に疑うのが定石です。

8. 自分の目で確かめる

今回も、手元のWindowsですべて観察できます(一部は管理者権限が必要です)。

:: 代替データストリームを見る
dir /r C:\Users\%USERNAME%\Downloads

:: ファイルのMFT上の配置(ラン)や属性を見る
fsutil file layout C:\path\to\file.dat

:: 8.3短縮名の生成設定と、既存の短縮名
fsutil 8dot3name query C:
dir /x

:: USNジャーナルの状態
fsutil usn queryjournal C:

:: リパースポイントの確認(リンク先とタグ)
dir /aL C:\Users\%USERNAME%
fsutil reparsepoint query "C:\Users\%USERNAME%\OneDrive"

Procmonでファイル操作を追うと、今回の登場人物が実名で流れていきます($LogFile への書き込み、ストリーム名付きのパス、リパース処理)。使い方は「Process Monitor(ProcMon)実践ガイド」を参照してください。

9. まとめ

  • NTFSの中心はMFT。全ファイルが台帳のレコードで、情報は「レコード内」か「レコードが指す外部領域」にあります。小さいデータは常駐、大きいデータはラン参照で、小ファイル大量処理の遅さや断片化はこの構造の帰結です。1
  • データストリームは複数持てます。Zone.Identifier(Mark of the Web)はただのADSで、dir /r で見え、NTFSの外へは運ばれません。211
  • 名前は属性で、複数持てます。ハードリンクは同じレコードへの同格の名前、8.3名は互換用のもう一つの名前。「削除=名前を外す」であり、実体の消滅は最後の名前・ハンドル・カーネル内参照(マップ済みセクション等)がすべて無くなったときです。34
  • リパースポイントは「開く」への公式フックで、シンボリックリンクもジャンクションもファイルオンデマンドもこの応用です。ツリーを辿るコードは FILE_ATTRIBUTE_REPARSE_POINT を意識する必要があります。56
  • ジャーナルは2つ。$LogFile は構造の整合性回復(壊れない)、USNは変更履歴(何が変わったか)。「ジャーナリングだからデータも安全」ではありません──データの耐久性は第4回の道具で作ります。78
  • 論理サイズと割り当ては別物。スパース・圧縮・ADS・クラスター切り上げが「サイズが合わない」の四大要因です。圧縮ファイルが非同期I/Oにならない件も含め、性能調査の引き出しになります。910

続きは最終回、第6回「フィルタードライバーとミニフィルター ── ProcmonとウイルススキャンがI/Oに割り込める理由」です。第1回から折に触れて登場してきた「間に挟まる者たち」──ウイルス対策、Procmon、OneDrive、暗号化──がどうI/Oに割り込んでいるのか。連載の総仕上げとして、デバイススタックの隙間に立つ住人たちの正体を明かします。

関連記事

関連する相談領域

合同会社小村ソフトでは、ファイルサイズやコピー性能の不可解な挙動、リンク・ストリーム絡みの不具合など、NTFSの仕組みに根ざしたWindows業務アプリの設計・調査を扱っています。

参考リンク

  1. Microsoft Learn, Master File Table. NTFSボリューム上のすべてのファイルについてMFTに少なくとも1つのエントリがあり、MFT自身のエントリも含まれること、ファイルのサイズ・タイムスタンプ・アクセス許可・データ内容を含むすべての情報がMFTエントリ内かMFTエントリが位置を記述するMFT外の領域に格納されること、ファイル削除時にエントリが空きとしてマークされ再利用されるがMFTのサイズは縮まないこと、MFTを連続に保つためのMFTゾーンが予約されること、割り当ての進行によりMFTの断片化が起こることについて。  2 3 4 5 6

  2. Microsoft Learn, File Streams. NTFSのファイルデータが1つ以上のストリームとして格納されること、既定の(名前のない)データストリームと名前付きの代替データストリームがあること、「ファイル名:ストリーム名」の形式でストリームを指定してCreateFileで開けることについて。  2 3 4

  3. Microsoft Learn, fsutil 8dot3name. NTFSが長いファイル名に対して8.3形式の短縮名を生成できること、fsutil 8dot3nameで短縮名生成の有効/無効の照会と設定、既存の短縮名の除去(strip)、除去した場合に影響を受けるレジストリ参照の走査ができることについて。  2 3

  4. Microsoft Learn, Reparse points. リパースポイントがユーザー定義データとそのデータ形式を一意に識別するリパースタグの集まりであること、リパースポイント付きファイルのオープン時にファイルシステムがタグに対応する処理(タグを解釈するファイルシステムフィルターによる処理)を試みること、NTFSのファイルシステムリンクやリモートストレージ(階層記憶)の実装に使われていること、FILE_ATTRIBUTE_REPARSE_POINT属性で存在を確認できることについて。  2 3 4

  5. Microsoft Learn, NTFS overview. NTFSがログファイルとチェックポイント情報を使い、システム障害が起きた場合に次回起動時にトランザクションログを再生してファイルシステムの整合性を自動的に回復すること、不良セクターの動的な再マップや、バックグラウンドで軽微な破損を修復するself-healing NTFSを備えることについて。  2 3

  6. Microsoft Learn, Change Journals. ボリューム内のファイルやディレクトリに変更が加えられるたびに、そのボリュームのUSN変更ジャーナルに変更の内容と対象ファイル/ディレクトリの名前が記録されること、ボリュームごとにジャーナルが維持されること、障害後のファイルシステムインデックスの回復に使え、ボリューム全体の再インデックスを回避できることについて。  2 3 4

  7. Microsoft Learn, Sparse Files. スパースファイルにおいて、ゼロで構成される大きな範囲に物理的なディスク領域を割り当てず、データを含む部分にのみ領域を割り当てること、割り当てのない範囲を読むとゼロが返ることについて。  2 3

  8. Microsoft Learn, File Compression and Decompression. NTFSのファイル圧縮が透過的に行われ、圧縮単位ごとにデータが圧縮・格納されること、GetCompressedFileSizeで圧縮(実割り当て)後のサイズを取得できること、圧縮ファイルの読み書きに展開・再圧縮のコストが伴うことについて。  2 3

  9. Microsoft Learn, Streams - Sysinternals. Sysinternalsのstreamsユーティリティが、NTFSファイルの代替データストリームを列挙・削除できることについて。  2

同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。

Windows I/Oの深層(第6回・最終回) ── フィルタードライバーとミニフィルター:ProcmonとウイルススキャンがI/Oに割り込める理由

Windowsのフィルタードライバーとミニフィルターを図解で解説する連載の最終回です。フィルターマネージャーとアルティチュード、pre/postコールバック、Procmonやウイルス対策が全I/Oを検査できる仕組み、「あの環境だけ遅い」の調査手順まで整理します。

このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。

この記事は次のサービスページにつながります。近い入口からご覧ください。

よくある質問

この記事のテーマについて、相談時によくある質問をまとめています。

MFT(マスターファイルテーブル)とは何ですか?
NTFSボリュームの心臓部にあたるデータ構造で、ボリューム上のすべてのファイルについて少なくとも1つのエントリ(ファイルレコード)を持つ台帳です。MFT自身のエントリも含まれます。ファイルのサイズ、タイムスタンプ、アクセス許可、そしてデータ本体に至るまで、ファイルに関するすべての情報は、MFTエントリの中か、MFTエントリが指し示すMFT外の領域に格納されます。小さなファイルならデータ本体ごとMFTエントリ内に収まり(常駐)、大きなファイルはデータの置き場所(クラスターの並び)への参照だけがエントリに記録されます(非常駐)。ファイルを削除するとエントリは空きとしてマークされ再利用されますが、MFT自体のサイズは縮みません。
ファイルに付いている「Zone.Identifier」という見えないデータは何ですか?
NTFSの複数データストリーム(代替データストリーム)の一つです。NTFSでは1つのファイルが複数のバイト列(ストリーム)を持て、普段読み書きしているのは名前のない既定ストリームです。「file.txt:Zone.Identifier」のようにコロン区切りで指定する追加ストリームに、Windowsはファイルの出所(インターネットからダウンロードした等)を記録します。これがいわゆる「Mark of the Web」で、SmartScreenの警告やOfficeの保護ビューの判定材料になります。代替ストリームはエクスプローラーのサイズ表示に現れず、dir /rコマンドやSysinternalsのstreamsツールで確認できます。NTFS以外のファイルシステム(FATなど)へコピーすると保持されない点にも注意が必要です。
ハードリンクとシンボリックリンクは何が違いますか?
ハードリンクは「同じファイル実体(同じMFTレコード)を指す、同格の名前がもう一つ増える」ことです。同一ボリューム内でしか作れず、どの名前からアクセスしても同じファイルで、1つの名前を削除しても他の名前が残っていればファイルは消えません。シンボリックリンクは「別のパスへ案内する標識」で、リパースポイントとして実装されます。リンク先のパス文字列を保持しているだけなので、別ボリュームやリモートも指せますが、リンク先が消えれば行き止まりになります。実務では、ハードリンクは実体の共有(削除の意味が変わる)、シンボリックリンクはパスの付け替え(移設やリダイレクト)と使い分けるのが基本です。
NTFSはジャーナリングファイルシステムだから、電源断でもデータは消えないのですか?
守られる範囲を正確に理解する必要があります。NTFSのトランザクションログ($LogFile)が守るのは、ファイルシステムの構造(メタデータ)の整合性です。システム障害が起きても、次回起動時にログを使って整合性を自動回復し、「ボリュームが壊れて読めない」事態を防ぎます。しかし、書き込み途中だったファイルのデータ内容そのものが復元されるわけではありません。連載第4回で見たとおり、キャッシュ上のダーティなデータは電源断で失われます。つまり「ボリュームは壊れないが、最後の書き込み内容は消えうる」が正しい理解で、データ自体の耐久性が必要ならFlushFileBuffersやWRITE_THROUGH、あるいはアプリ側の書き込み設計(一時ファイル+リネーム等)で作り込む必要があります。
ファイルの「サイズ」と「ディスク上のサイズ」が違うのはなぜですか?
NTFSでは、ファイルの論理的な長さと、実際に割り当てられたディスク領域が別々に管理されているからです。通常のファイルでもクラスター単位(既定4KB)で切り上げて割り当てるため差が出ますが、大きく乖離するのはスパースファイルと圧縮ファイルです。スパースファイルでは、ゼロが続く範囲に実領域を割り当てず「穴」として管理するため、論理サイズ数GBでもディスク上は数MBということが起こります。圧縮ファイルでは圧縮後のサイズだけが割り当てられます。逆に「ディスク上のサイズ」の方が大きく見える場合は、クラスター切り上げや代替データストリームが原因のことがあります。

著者プロフィール

記事の著者プロフィールページです。

小村 豪

合同会社小村ソフト 代表

Windows ソフト開発、技術相談、不具合調査を中心に、既存資産が残る案件や原因が見えにくい障害調査に強みがあります。

ブログ一覧に戻る