mcpField
M
mariadb-system-versioned-tables

mariadb-system-versioned-tables

github.com/mariadbデータ・データベース17117 回インストール2 週間前に更新
リポジトリ

mariadb-system-versioned-tables について

MariaDB の開発者やデータベース管理者向けに、システムバージョンテーブルの設定、履歴検索、管理方法を解説するスキルガイドです。バージョン差や注意点も扱います。

主な機能

  1. 01行変更履歴の自動記録
  2. 02時点または期間での検索
  3. 03列単位のバージョン管理
  4. 04パーティションによる履歴管理
  5. 05バックアップと構造変更の注意点

活用シーン

  1. 01データ変更の監査
  2. 02過去時点のデータ確認
  3. 03給与や価格の変化追跡
  4. 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_TABLEMariaDB では 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の公式ドキュメント(mariadb.com/docs)を参照してください。

コメント