RDB が ROLLBACK の処理コストを支払うタイミング
概要
Oracle Database で大量のデータを ROLLBACK するのには時間がかかります。これに対して PostgreSQL の ROLLBACK は一瞬で完了します。この差について検証と考察を行いました。そこで見えてきたのは ROLLBACK の処理コストを支払うタイミングの違いでした。
検証環境
Windows の Hyper-V による仮想マシンを検証環境としました。
Oracle Database
プロセッサ | 4個の仮想プロセッサ |
メモリ | 8.0GB |
OS | Oracle Linux Server release 7.8 |
DB | Oracle Database 19c EE 19.3 |
PostgreSQL
プロセッサ | 4個の仮想プロセッサ |
メモリ | 8.0GB |
OS | CentOS 8.1.1911 |
DB | PostgreSQL 12.1 |
検証方法
各DBで以下の操作を行います。
- テーブルを作成する。
- テーブルに大量データを INSERT する。
- INSERT を ROLLBACK する。
- (PostgreSQLのみ)テーブルに VACUUM を実行する。
各操作 (INSERT, ROLLBACK, VACUUM) の処理時間を測定します。
Oracle Database
CREATE TABLE tab1(c1 INTEGER); ALTER SYSTEM FLUSH BUFFER_CACHE; SET TIMING ON INSERT INTO tab1 SELECT rownum FROM (SELECT level FROM dual CONNECT BY level <= 10000), (SELECT level FROM dual CONNECT BY level <= 10000); ROLLBACK;
PostgreSQL
CREATE TABLE tab1(c1 INTEGER); BEGIN; \timing INSERT INTO tab1 SELECT generate_series(1, 100000000); ROLLBACK; VACUUM tab1;
検証結果・考察
操作 | Oracle Database | PostgreSQL |
INSERT | 09:28.942 | 04:22.612 |
ROLLBACK | 01:07.629 | 00:00.240 |
VACUUM | --- | 15:36.632 |
各DBは環境やクエリが異なっており、チューニングも行っていません。よって、処理時間を絶対的に比較するのは適切ではありません。
ここでは、各DBがどの操作に相対的な観点で時間がかかっていたかを確認します。
Oracle Database
Oracle Database では ROLLBACK に時間がかかっています。このことはドキュメントにも明記されています。
ロールバックの持続時間は、変更されたデータ量の関数になります。
トランザクション
また、Oracle Database が ROLLBACK で行う内部処理についてもドキュメントに記載があります。
データベースでは、UNDOセグメントからデータを読み取り、操作を逆順にして、適用されたとおりにUNDOエントリをマークします。したがって、トランザクションで行が挿入されると、ロールバックによって削除されます。
トランザクション
つまり、INSERT に対する ROLLBACK は DELETE を行っているのに相当するといえます。このことからも ROLLBACK に処理時間がかかる理由を説明できます。
PostgreSQL
PostgreSQL では ROLLBACK が一瞬で完了しています。PostgreSQL では ROLLBACK してもトランザクションの状態を Abort に更新するのみであり、テーブルファイルには更新処理の結果を残したままとするためです。これは PostgreSQL がストレージアーキテクチャとして採用した「追記型アーキテクチャ」に由来しています。
PostgreSQL のトランザクションと可視性については下記の記事を参照ください。
PostgreSQL のトランザクション & MVCC & スナップショットの仕組み
実際の挙動については以前の記事で調査結果をまとめています。
PostgreSQL は更新処理を ROLLBACK してもテーブルファイルに追記される - ぱと隊長日誌
追記型アーキテクチャにおいて、テーブルファイル内の不要なデータは VACUUM を実行するまで削除されません。そして、検証結果からは ROLLBACK によって大量に残った不要データを削除するための VACUUM に時間を要したことが分かります。
まとめ
ROLLBACK を各DBで比較すると次のように言えます。
- Oracle Database は ROLLBACK の処理コストを即座に支払う。
- PostgreSQL は ROLLBACK の処理コストを後払いにする。
各DBの特性としてこのような違いがあることを意識し、設計することが肝要といえます。