JFS2 の Concurrent I/O について調べたことをメモ

Concurrent I/O = Direct I/O + 並行I/O -> raw I/O に匹敵パフォーマンス

ということらしいが、Concurrent I/O の 並行I/Oとは何か?
Concurrent I/O の並行I/Oでは inode の中身が変更される場合のみ直列化(ファイルの中身が変更される場合は並列化)され、書き込みの直列化が緩和されるようだ。データベースは固定長のファイルに書き込むことが多いので、並行化できるI/Oが多そう。

Concurrent I/O はデータベースなど自前で同時実行性制御を行う仕組みを持っているアプリケーション向けで、ファイルサーバのようなOS側で同時実行性制御を行わないと不整合が発生しうる場合は向いていないようだ。

ここから妄想の世界。話がそれるけど、Oracle Database でバッファキャッシュのサイズを厳密にチューニングしない場合は、ファイルシステムのキャッシュのメリットがある気がする。バッファキャッシュのサイズが不適切に小さい場合、バッファキャッシュにはキャッシュされていなくても、物理メモリに余裕があれば、OS のレイヤーでキャッシュしてくれる。RAWデバイスのメリットはシンプルな分ファイルシステムよりオーバーヘッドが少なく、CPUやメモリを節約できる点だと思う。その代わり、メモリについてはデータベースで使う分を厳密に見積らないと物理メモリが余っているのにデータベースで使われずもったいないことになると思う。


Direct I/O (DIO) により、ファイル・システム・レベルでのキャッシュをバイパスするためメモリー・パフォーマンスが向上します。これにより CPU オーバーヘッドが減少し、データベース・インスタンスがより多くのメモリーを使用可能になります。

さらに、Concurrent I/O (CIO) が利用される場合(AIX5.2 + JFS2が前提)DIO の利点の他に、書き込みアクセスのシリアライゼーションも緩和され、並行I/Oが可能になります。

以下の資料にはConcurrent I/O が使用された場合、raw I/Oに匹敵するパフォーマンスが得られることが示されています。

IBM DB2: RAWデバイスとファイルシステムの比較 - Japan
  • Improve Database Performance on File System Containers in DB2 Universal Database V8.2 using Concurrent I/O on AIX


P. 2

While Direct I/O has reduced the gap of performance tradeoffs between file systems and raw devices, some of the fundamental features of file systems, such as ensuring data integrity, still impact database performance. In 2003, IBM introduced a new file system feature called Concurrent I/O (CIO) for the Enhanced Journaling File System (JFS2) in AIX 5L version 5.2.10 maintenance update. This feature includes all the advantages of Direct I/O and also relieves the serialization of write accesses. Database performance achieved using CIO with JFS2 is comparable to that obtained by using raw I/O.


2.2.4 Concurrent I/O
Both buffered I/O and Direct I/O have the disadvantage of requiring a per-file write lock, or inode lock. This file system feature helps ensure data integrity and improve fault tolerance, but also poses performance bottlenecks for database applications. The details of inode locking are described below.


The inode lock imposes write serialization at the file level. Serializing write accesses ensures that data inconsistencies due to overlapping writes do not occur. Serializing reads with respect to writes ensures that the application does not read stale data.
Sophisticated database applications implement their own data serialization, usually at a finer level of granularity than the file. Such applications implement serialization mechanisms at the application level to ensure that data inconsistencies do not occur, and that stale data is not read. Consequently, they do not need the file system to implement this serialization for them. The inode lock actually hinders performance in such cases, by unnecessarily serializing non-competing data accesses.
Under Concurrent I/O, the inode lock is acquired in read-shared mode for both read and write accesses. However, in situations where the contents of the inode may change for reasons other than a change to the contents of the file (writes), the inode lock is acquired in write-exclusive mode. One such situation occurs when a file is extended or truncated.
Extending a file may require allocation of new disk blocks for the file, and consequently requires an update to the “table of contents” of the corresponding inode. In this case, the read-shared inode lock is upgraded to the write-exclusive mode for the duration of the extend operation. Similarly, when a file is truncated, allocated disk blocks might be freed and the inode’s table of contents needs to be updated. Upon completion of the extend or truncate operation, the inode lock reverts to read-shared mode. This is a very powerful feature, since it allows files using Concurrent I/O to grow or shrink in a manner that is transparent to the application, without having to close or reopen files after a resize.