mariadb-system-versioned-tables について
MariaDB の開発者やデータベース管理者向けに、システムバージョンテーブルの設定、履歴検索、管理方法を解説するスキルガイドです。バージョン差や注意点も扱います。
主な機能
- 01行変更履歴の自動記録
- 02時点または期間での検索
- 03列単位のバージョン管理
- 04パーティションによる履歴管理
- 05バックアップと構造変更の注意点
活用シーン
- 01データ変更の監査
- 02過去時点のデータ確認
- 03給与や価格の変化追跡
- 04本番データ変更の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mariadb/ skills --skill mariadb-system-versioned-tablesインストール後、Claude Code で/mariadb-system-versioned-tablesを入力して読み込まれたか確認します。
詳細
MariaDB のシステムバージョン管理テーブル
最終更新日:2026-06-04
システムバージョン管理テーブルは、すべての行変更の完全な履歴を自動的に記録します。トリガーも、アプリケーションロジックも、個別の監査テーブルも必要ありません。MariaDB はストレージエンジンに組み込まれた機能によって、過去の任意の時点のデータを追跡します。
この機能は、MySQL 互換データベースの中で MariaDB 独自のものです。MySQL には同等の機能がありません。
利用可能になったバージョン: MariaDB 10.3。トランザクション精度の履歴(InnoDB のみ):10.3。パーティションの自動作成:10.9。バックアップ用の
--dump-history:10.11。暗黙的なrow_start/row_endから明示的なものへの変換:11.7。ROW_END用の TIMESTAMP の範囲拡張(2106-02-07 UTC まで):64 ビットプラットフォーム上の 11.5。デフォルトのコンテキスト: ユーザーが別のバージョンを指定しない限り、MariaDB 11.8 LTS(2025 年 5 月 GA)を前提としてください。このスキル内のバージョンに関する記載は、各機能に必要な最小リリースです。
LLM が見落としがちなこと
| 状況 | 提案する内容 |
|---|---|
監査用の独自の created_at/updated_at/deleted_at 列 | WITH SYSTEM VERSIONING — MariaDB がすべての変更を自動的に追跡します |
SQL Server のテンポラル構文 — WITH (SYSTEM_VERSIONING = ON)、明示的な PERIOD FOR SYSTEM_TIME、名前付きの HISTORY_TABLE | MariaDB では CREATE TABLE ... WITH SYSTEM VERSIONING を使用します(括弧も = ON もなく、個別の履歴テーブルもありません)。既存のテーブルでは ALTER TABLE t ADD SYSTEM VERSIONING で有効にします |
| トリガーを使った個別の監査ログテーブル | システムバージョン管理テーブルで、このパターンを完全に置き換えられます |
| 先月のデータがどのような状態だったかを確認する | FOR SYSTEM_TIME AS OF '2026-01-01' — 独自のロジックは必要ありません |
バージョン管理テーブルへの TRUNCATE | 許可されません(エラー 4137)。代わりに DELETE HISTORY を使用します |
バージョン管理テーブルへの ALTER TABLE が失敗する | 先に system_versioning_alter_history = KEEP を設定します |
mysqldump に履歴行が含まれない | mariadb-dump --dump-history(10.11 以降)を使用します |
システムバージョン管理テーブルの作成
簡略構文(推奨):
CREATE TABLE employees (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
department VARCHAR(50),
salary DECIMAL(10,2)
) WITH SYSTEM VERSIONING;
MariaDB は非表示の ROW_START と ROW_END のタイムスタンプ列を自動的に追加します。すべての INSERT、UPDATE、DELETE によって履歴行が作成されます。
既存のテーブルにバージョン管理を追加する:
ALTER TABLE employees ADD SYSTEM VERSIONING;
バージョン管理を削除する(すべての履歴を削除):
ALTER TABLE employees DROP SYSTEM VERSIONING;
履歴データのクエリ
FOR SYSTEM_TIME 句はテーブル名の直後に置きます。
-- Data as it was at a specific point in time:
SELECT * FROM employees FOR SYSTEM_TIME AS OF '2026-01-01 00:00:00';
-- All rows that existed during a period (both boundaries included):
SELECT * FROM employees FOR SYSTEM_TIME BETWEEN '2025-01-01' AND '2026-01-01';
-- Half-open range (includes start, excludes end):
SELECT * FROM employees FOR SYSTEM_TIME FROM '2025-01-01' TO '2026-01-01';
-- Every version of every row, ever:
SELECT * FROM employees FOR SYSTEM_TIME ALL;
-- See the full history of one employee:
SELECT *, ROW_START, ROW_END FROM employees FOR SYSTEM_TIME ALL WHERE id = 42;
セッション内のすべてのクエリに暗黙的な AS OF を適用する:
SET system_versioning_asof = '2026-01-01 00:00:00';
-- Now all queries against versioned tables see that point in time
SELECT * FROM employees; -- returns 2026-01-01 snapshot
SET system_versioning_asof = DEFAULT; -- reset
トランザクション精度の履歴(InnoDB のみ)
タイムスタンプの代わりに、正確なトランザクション境界を追跡するには:
CREATE TABLE ledger (
id INT,
amount DECIMAL(10,2),
trx_start BIGINT UNSIGNED GENERATED ALWAYS AS ROW START,
trx_end BIGINT UNSIGNED GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME(trx_start, trx_end)
) WITH SYSTEM VERSIONING;
SELECT * FROM ledger FOR SYSTEM_TIME AS OF TRANSACTION 12345;
内部的に mysql.transaction_registry を使用します。PARTITION BY SYSTEM_TIME とは互換性がありません。
列単位の制御
特定の列をバージョン管理から除外します(カウンターのように頻繁に更新される列に便利です)。
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(100),
price DECIMAL(10,2),
view_count INT WITHOUT SYSTEM VERSIONING -- not tracked
) WITH SYSTEM VERSIONING;
または、バージョン管理されていないテーブルで、特定の列のみをバージョン管理します。
CREATE TABLE config (
key VARCHAR(50),
value TEXT WITH SYSTEM VERSIONING -- only this column tracked
);
履歴の増加を管理する
更新のたびに行が追加されます。更新頻度の高いテーブルでは、履歴が急速に増加します。現在のデータのパフォーマンスを維持するには、パーティショニングを使用します。
-- Separate current and historical partitions:
CREATE TABLE events (
id INT,
payload JSON
) WITH SYSTEM VERSIONING
PARTITION BY SYSTEM_TIME (
PARTITION p_hist HISTORY,
PARTITION p_cur CURRENT
);
-- Auto-rotate history by time interval (10.9+):
CREATE TABLE prices (
symbol VARCHAR(10),
price DECIMAL(10,4)
) WITH SYSTEM VERSIONING
PARTITION BY SYSTEM_TIME INTERVAL 1 MONTH AUTO (
PARTITION p_cur CURRENT
);
古い履歴を削除する:
-- Delete all history before a date:
DELETE HISTORY FROM employees BEFORE SYSTEM_TIME '2024-01-01';
-- Delete all history (requires DROP SYSTEM VERSIONING + re-add, or partition drop):
ALTER TABLE employees DROP PARTITION p_hist;
DELETE HISTORY 権限が必要です。バージョン管理テーブルでは TRUNCATE を使用できません。
バージョン管理テーブルへの ALTER TABLE
デフォルトでは、履歴の整合性を保護するため、バージョン管理テーブルへの ALTER TABLE はエラーになります。許可するには:
SET system_versioning_alter_history = KEEP;
ALTER TABLE employees ADD COLUMN manager_id INT;
SET system_versioning_alter_history = ERROR; -- restore default
KEEP を指定すると変更できますが、新しい列の履歴行の値は NULL になり、履歴は厳密には不完全になります。列の追加であれば、通常は問題ありません。
非表示の ROW_START/ROW_END を明示的な列に変換する(11.7 以降、MDEV-27293)— 非表示形式(PERIOD FOR SYSTEM_TIME 句なし)でテーブルのバージョン管理を開始した後でも、バージョン管理を解除せずに明示的な列へ昇格できます。最初は簡単な方法で始め、後からトランザクション精度の履歴や、ツール向けの明示的な名前が必要になった場合に便利です。
重要な注意点
- バージョン管理されたテーブルでは
TRUNCATEは禁止されています(エラー 4137)。代わりにDELETE HISTORYまたはパーティション管理を使用してください。 - レプリケーション:
ROW_ENDは暗黙的に主キーに追加されます。レプリカでは、ログの再生中に重複キーエラーが発生することがあります。対処法:レプリカでsecure_timestamp = YESを設定してください。 - バックアップ:
mysqldump/mariadb-dumpは、デフォルトでは履歴行をスキップします。履歴行を含めるには--dump-history(10.11+)を使用してください。復元時は、ローダーがROW_START/ROW_ENDに直接書き込めるよう、system_versioning_insert_history=ON(10.11+、MDEV-16546)を設定してください。セッションのタイムスタンプ変更を許可するようsecure_timestampを設定した状態で併用してください。 - テーブルの肥大化:パーティション分割を行わないと、履歴行は際限なく蓄積します。更新頻度の高いテーブルでは、最初からパーティション分割を計画してください。
- 将来のタイムスタンプを指定した
DELETE HISTORY:ROW_ENDの最大値を超えるタイムスタンプをBEFORE SYSTEM_TIMEに指定すると、現行の行まで誤って削除されることがあります(MDEV-25468)。ROW_ENDの最大値は、32ビットプラットフォームおよびMariaDB 11.5未満では2038-01-19です。64ビット環境のMariaDB 11.5以降では2106-02-07 06:28:15 UTCまで延長されています(MDEV-32188)。使用するプラットフォームの上限を十分に下回る値にしてください。 - 列名としての
SYSTEM:ALTER TABLEステートメントでパーサーエラーが発生します。バッククォートを使用してください:`SYSTEM`。
使用例
- 監査証跡 — アプリケーションコードを使わずに、誰が何をいつ変更したかを確認できます
- GDPR/PCI DSSへの準拠 — 任意の日付時点で個人データに何が含まれていたかを証明できます
- 特定時点への復旧 — バックアップ全体を復元せずに、行またはテーブルを以前の状態に戻せます
- 緩やかに変化するディメンション — 従業員の部署や給与の履歴、商品の価格履歴を追跡できます
- デバッグ — 本番データで何がいつ変更されたかを正確に確認できます
参考資料
- システムバージョン管理テーブル — MariaDB Docs
- システムバージョン管理テーブル — MariaDB Docs
- MariaDBのデータバージョン管理の使用例 — MariaDB Blog
- MariaDBデータベースで時間を巻き戻す — MariaDB Blog
ここで取り上げていないトピックについては、MariaDBの公式ドキュメント(mariadb.com/docs)を参照してください。