ぱと隊長日誌

ブログ運用もエンジニアとしての生き方も模索中

RDB が ROLLBACK の処理コストを支払うタイミング

概要

Oracle Database で大量のデータを ROLLBACK するのには時間がかかります。これに対して PostgreSQL の ROLLBACK は一瞬で完了します。この差について検証と考察を行いました。そこで見えてきたのは ROLLBACK の処理コストを支払うタイミングの違いでした。

検証環境

WindowsHyper-V による仮想マシンを検証環境としました。

ホスト

プロセッサ Intel Core i5-6600 CPU @ 3.30GHz
メモリ 20.0 GB
OS Windows 10 Pro バージョン 1909

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で以下の操作を行います。

  1. テーブルを作成する。
  2. テーブルに大量データを INSERT する。
  3. INSERT を ROLLBACK する。
  4. 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の特性としてこのような違いがあることを意識し、設計することが肝要といえます。