[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-mariadb-mariadb-system-versioned-tables":3,"mdc-ep0u73-key":37,"related-repo-mariadb-mariadb-system-versioned-tables":1626,"related-org-mariadb-mariadb-system-versioned-tables":1710},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":26,"repoUrl":27,"updatedAt":28,"license":29,"forks":30,"topics":31,"repo":32,"sourceUrl":35,"mdContent":36},"mariadb-system-versioned-tables","implement MariaDB system-versioned tables","Best practices for MariaDB system-versioned (temporal) tables — automatic row history built into the database. Use when tracking data changes over time, implementing audit trails, meeting GDPR or compliance requirements, doing point-in-time queries, or when the user asks about row history, data versioning, temporal tables, or querying past data states in MariaDB. This feature is unique to MariaDB among MySQL-compatible databases.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},"mariadb","MariaDB","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fmariadb.png",[12,16,19,22,23],{"name":13,"slug":14,"type":15},"GDPR","gdpr","tag",{"name":17,"slug":18,"type":15},"Compliance","compliance",{"name":20,"slug":21,"type":15},"Audit","audit",{"name":9,"slug":8,"type":15},{"name":24,"slug":25,"type":15},"Database","database",9,"https:\u002F\u002Fgithub.com\u002FMariaDB\u002Fskills","2026-07-13T06:14:16.779878",null,2,[],{"repoUrl":27,"stars":26,"forks":30,"topics":33,"description":34},[],"MariaDB skills for Claude Code and AI agents - because it is not MySQL","https:\u002F\u002Fgithub.com\u002FMariaDB\u002Fskills\u002Ftree\u002FHEAD\u002Fmariadb-system-versioned-tables","---\nname: mariadb-system-versioned-tables\ndescription: \"Best practices for MariaDB system-versioned (temporal) tables — automatic row history built into the database. Use when tracking data changes over time, implementing audit trails, meeting GDPR or compliance requirements, doing point-in-time queries, or when the user asks about row history, data versioning, temporal tables, or querying past data states in MariaDB. This feature is unique to MariaDB among MySQL-compatible databases.\"\n---\n\n# MariaDB System-Versioned Tables\n\n*Last updated: 2026-06-04*\n\nSystem-versioned tables automatically record the full history of every row change — no triggers, no application logic, no separate audit tables. MariaDB tracks what the data looked like at any point in the past, built directly into the storage engine.\n\nThis feature is unique to MariaDB among MySQL-compatible databases. MySQL has no equivalent.\n\n> **Available since:** MariaDB 10.3. Transaction-precise history (InnoDB only): 10.3. Auto-partition creation: 10.9. `--dump-history` for backups: 10.11. Implicit-to-explicit `row_start`\u002F`row_end` conversion: 11.7. Extended TIMESTAMP range (to 2106-02-07 UTC) for `ROW_END`: 11.5 on 64-bit platforms.\n>\n> **Default context:** Assume MariaDB **11.8 LTS** (GA May 2025) unless the user states another version. Version notes in this skill are minimum releases for each capability.\n\n## What LLMs Often Miss\n\n| Situation | What to suggest |\n|---|---|\n| Custom `created_at`\u002F`updated_at`\u002F`deleted_at` columns for audit | `WITH SYSTEM VERSIONING` — MariaDB tracks all changes automatically |\n| SQL Server temporal syntax — `WITH (SYSTEM_VERSIONING = ON)`, explicit `PERIOD FOR SYSTEM_TIME` and a named `HISTORY_TABLE` | MariaDB uses `CREATE TABLE ... WITH SYSTEM VERSIONING` (no parentheses, no `= ON`, no separate history table); enable it on an existing table with `ALTER TABLE t ADD SYSTEM VERSIONING` |\n| Separate audit log table with triggers | System-versioned tables replace this pattern entirely |\n| Asking how data looked last month | `FOR SYSTEM_TIME AS OF '2026-01-01'` — no custom logic needed |\n| `TRUNCATE` on a versioned table | Not allowed (error 4137) — use `DELETE HISTORY` instead |\n| `ALTER TABLE` on a versioned table failing | Set `system_versioning_alter_history = KEEP` first |\n| `mysqldump` missing historical rows | Use `mariadb-dump --dump-history` (10.11+) |\n\n## Creating a System-Versioned Table\n\n**Simplified syntax (recommended):**\n```sql\nCREATE TABLE employees (\n    id INT AUTO_INCREMENT PRIMARY KEY,\n    name VARCHAR(100) NOT NULL,\n    department VARCHAR(50),\n    salary DECIMAL(10,2)\n) WITH SYSTEM VERSIONING;\n```\n\nMariaDB automatically adds hidden `ROW_START` and `ROW_END` timestamp columns. Every `INSERT`, `UPDATE`, and `DELETE` creates a history row.\n\n**Add versioning to an existing table:**\n```sql\nALTER TABLE employees ADD SYSTEM VERSIONING;\n```\n\n**Remove versioning (deletes all history):**\n```sql\nALTER TABLE employees DROP SYSTEM VERSIONING;\n```\n\n## Querying Historical Data\n\nThe `FOR SYSTEM_TIME` clause goes directly after the table name:\n\n```sql\n-- Data as it was at a specific point in time:\nSELECT * FROM employees FOR SYSTEM_TIME AS OF '2026-01-01 00:00:00';\n\n-- All rows that existed during a period (both boundaries included):\nSELECT * FROM employees FOR SYSTEM_TIME BETWEEN '2025-01-01' AND '2026-01-01';\n\n-- Half-open range (includes start, excludes end):\nSELECT * FROM employees FOR SYSTEM_TIME FROM '2025-01-01' TO '2026-01-01';\n\n-- Every version of every row, ever:\nSELECT * FROM employees FOR SYSTEM_TIME ALL;\n\n-- See the full history of one employee:\nSELECT *, ROW_START, ROW_END FROM employees FOR SYSTEM_TIME ALL WHERE id = 42;\n```\n\n**Apply an implicit AS OF to all queries in a session:**\n```sql\nSET system_versioning_asof = '2026-01-01 00:00:00';\n-- Now all queries against versioned tables see that point in time\nSELECT * FROM employees; -- returns 2026-01-01 snapshot\nSET system_versioning_asof = DEFAULT; -- reset\n```\n\n## Transaction-Precise History (InnoDB Only)\n\nFor exact transaction-boundary tracking instead of timestamps:\n\n```sql\nCREATE TABLE ledger (\n    id INT,\n    amount DECIMAL(10,2),\n    trx_start BIGINT UNSIGNED GENERATED ALWAYS AS ROW START,\n    trx_end   BIGINT UNSIGNED GENERATED ALWAYS AS ROW END,\n    PERIOD FOR SYSTEM_TIME(trx_start, trx_end)\n) WITH SYSTEM VERSIONING;\n\nSELECT * FROM ledger FOR SYSTEM_TIME AS OF TRANSACTION 12345;\n```\n\nUses `mysql.transaction_registry` internally. Not compatible with `PARTITION BY SYSTEM_TIME`.\n\n## Column-Level Control\n\nExclude specific columns from versioning (useful for frequently-updated columns like counters):\n\n```sql\nCREATE TABLE products (\n    id INT PRIMARY KEY,\n    name VARCHAR(100),\n    price DECIMAL(10,2),\n    view_count INT WITHOUT SYSTEM VERSIONING  -- not tracked\n) WITH SYSTEM VERSIONING;\n```\n\nOr version only specific columns in a non-versioned table:\n```sql\nCREATE TABLE config (\n    key VARCHAR(50),\n    value TEXT WITH SYSTEM VERSIONING  -- only this column tracked\n);\n```\n\n## Managing History Growth\n\nEvery update adds a row. For high-update tables, history grows fast. Use partitioning to keep current data performant:\n\n```sql\n-- Separate current and historical partitions:\nCREATE TABLE events (\n    id INT,\n    payload JSON\n) WITH SYSTEM VERSIONING\n  PARTITION BY SYSTEM_TIME (\n    PARTITION p_hist HISTORY,\n    PARTITION p_cur  CURRENT\n  );\n\n-- Auto-rotate history by time interval (10.9+):\nCREATE TABLE prices (\n    symbol VARCHAR(10),\n    price DECIMAL(10,4)\n) WITH SYSTEM VERSIONING\n  PARTITION BY SYSTEM_TIME INTERVAL 1 MONTH AUTO (\n    PARTITION p_cur CURRENT\n  );\n```\n\n**Delete old history:**\n```sql\n-- Delete all history before a date:\nDELETE HISTORY FROM employees BEFORE SYSTEM_TIME '2024-01-01';\n\n-- Delete all history (requires DROP SYSTEM VERSIONING + re-add, or partition drop):\nALTER TABLE employees DROP PARTITION p_hist;\n```\n\nRequires `DELETE HISTORY` privilege. `TRUNCATE` is not allowed on versioned tables.\n\n## ALTER TABLE on Versioned Tables\n\nBy default, `ALTER TABLE` on a versioned table raises an error to protect history integrity. To allow it:\n\n```sql\nSET system_versioning_alter_history = KEEP;\nALTER TABLE employees ADD COLUMN manager_id INT;\nSET system_versioning_alter_history = ERROR; -- restore default\n```\n\n`KEEP` allows the alter but historical rows for the new column will have `NULL` values — the history is technically incomplete. This is usually acceptable for adding columns.\n\n**Convert hidden `ROW_START`\u002F`ROW_END` to explicit columns** (11.7+, MDEV-27293) — once a table is versioned with the hidden form (no `PERIOD FOR SYSTEM_TIME` clause), you can promote them to explicit columns later without dropping versioning. Useful if you initially started simple and later want transaction-precise history or explicit naming for tooling.\n\n## Key Gotchas\n\n- **`TRUNCATE` is prohibited** on versioned tables (error 4137). Use `DELETE HISTORY` or partition management instead.\n- **Replication**: `ROW_END` is implicitly added to the Primary Key. On replicas, this can cause duplicate key errors during log replay. Fix: set `secure_timestamp = YES` on the replica.\n- **Backups**: `mysqldump` \u002F `mariadb-dump` skips historical rows by default. Use `--dump-history` (10.11+) to include them. On restore, set `system_versioning_insert_history=ON` (10.11+, MDEV-16546) so the loader is allowed to write directly into `ROW_START`\u002F`ROW_END`; combine with `secure_timestamp` set to allow session timestamp changes.\n- **Table growth**: without partitioning, history rows accumulate indefinitely. Plan partitioning from the start for high-update tables.\n- **DELETE HISTORY with future timestamps**: using `BEFORE SYSTEM_TIME` with a timestamp beyond `ROW_END` max can accidentally delete active rows (MDEV-25468). The `ROW_END` max is `2038-01-19` on 32-bit platforms and on MariaDB before 11.5; on MariaDB 11.5+ on 64-bit it's extended to `2106-02-07 06:28:15 UTC` (MDEV-32188). Stay well below your platform's max.\n- **`SYSTEM` as a column name**: causes parser errors in `ALTER TABLE` statements. Use backticks: `` `SYSTEM` ``.\n\n## Use Cases\n\n- **Audit trails** — who changed what and when, without application code\n- **GDPR \u002F PCI DSS compliance** — prove what personal data contained at any date\n- **Point-in-time recovery** — restore a row or table to a previous state without a full backup restore\n- **Slowly-changing dimensions** — track employee department\u002Fsalary history, product price history\n- **Debugging** — see exactly what changed and when in production data\n\n## Sources\n\n- [System-Versioned Tables — MariaDB Docs](https:\u002F\u002Fmariadb.com\u002Fdocs\u002Fserver\u002Freference\u002Fsql-structure\u002Ftemporal-tables\u002Fsystem-versioned-tables)\n- [System-Versioned Tables — MariaDB Docs](https:\u002F\u002Fmariadb.com\u002Fdocs\u002Fserver\u002Freference\u002Fsql-structure\u002Ftemporal-tables\u002Fsystem-versioned-tables)\n- [Use Cases for MariaDB Data Versioning — MariaDB Blog](https:\u002F\u002Fmariadb.com\u002Fresources\u002Fblog\u002Fuse-cases-for-mariadb-data-versioning\u002F)\n- [Rewinding Time in MariaDB Databases — MariaDB Blog](https:\u002F\u002Fmariadb.com\u002Fresources\u002Fblog\u002Frewinding-time-in-mariadb-databases-system-versioning-and-application-time\u002F)\n\n*For topics not covered here, see the official MariaDB documentation at [mariadb.com\u002Fdocs](https:\u002F\u002Fmariadb.com\u002Fdocs).*\n",{"data":38,"body":39},{"name":4,"description":6},{"type":40,"children":41},"root",[42,50,60,65,70,135,142,381,387,395,461,505,513,527,535,549,555,568,692,700,739,745,750,827,848,854,859,913,918,957,963,968,1119,1127,1173,1192,1198,1210,1241,1260,1290,1296,1496,1502,1555,1561,1604,1620],{"type":43,"tag":44,"props":45,"children":46},"element","h1",{"id":4},[47],{"type":48,"value":49},"text","MariaDB System-Versioned Tables",{"type":43,"tag":51,"props":52,"children":53},"p",{},[54],{"type":43,"tag":55,"props":56,"children":57},"em",{},[58],{"type":48,"value":59},"Last updated: 2026-06-04",{"type":43,"tag":51,"props":61,"children":62},{},[63],{"type":48,"value":64},"System-versioned tables automatically record the full history of every row change — no triggers, no application logic, no separate audit tables. MariaDB tracks what the data looked like at any point in the past, built directly into the storage engine.",{"type":43,"tag":51,"props":66,"children":67},{},[68],{"type":48,"value":69},"This feature is unique to MariaDB among MySQL-compatible databases. MySQL has no equivalent.",{"type":43,"tag":71,"props":72,"children":73},"blockquote",{},[74,118],{"type":43,"tag":51,"props":75,"children":76},{},[77,83,85,92,94,100,102,108,110,116],{"type":43,"tag":78,"props":79,"children":80},"strong",{},[81],{"type":48,"value":82},"Available since:",{"type":48,"value":84}," MariaDB 10.3. Transaction-precise history (InnoDB only): 10.3. Auto-partition creation: 10.9. ",{"type":43,"tag":86,"props":87,"children":89},"code",{"className":88},[],[90],{"type":48,"value":91},"--dump-history",{"type":48,"value":93}," for backups: 10.11. Implicit-to-explicit ",{"type":43,"tag":86,"props":95,"children":97},{"className":96},[],[98],{"type":48,"value":99},"row_start",{"type":48,"value":101},"\u002F",{"type":43,"tag":86,"props":103,"children":105},{"className":104},[],[106],{"type":48,"value":107},"row_end",{"type":48,"value":109}," conversion: 11.7. Extended TIMESTAMP range (to 2106-02-07 UTC) for ",{"type":43,"tag":86,"props":111,"children":113},{"className":112},[],[114],{"type":48,"value":115},"ROW_END",{"type":48,"value":117},": 11.5 on 64-bit platforms.",{"type":43,"tag":51,"props":119,"children":120},{},[121,126,128,133],{"type":43,"tag":78,"props":122,"children":123},{},[124],{"type":48,"value":125},"Default context:",{"type":48,"value":127}," Assume MariaDB ",{"type":43,"tag":78,"props":129,"children":130},{},[131],{"type":48,"value":132},"11.8 LTS",{"type":48,"value":134}," (GA May 2025) unless the user states another version. Version notes in this skill are minimum releases for each capability.",{"type":43,"tag":136,"props":137,"children":139},"h2",{"id":138},"what-llms-often-miss",[140],{"type":48,"value":141},"What LLMs Often Miss",{"type":43,"tag":143,"props":144,"children":145},"table",{},[146,165],{"type":43,"tag":147,"props":148,"children":149},"thead",{},[150],{"type":43,"tag":151,"props":152,"children":153},"tr",{},[154,160],{"type":43,"tag":155,"props":156,"children":157},"th",{},[158],{"type":48,"value":159},"Situation",{"type":43,"tag":155,"props":161,"children":162},{},[163],{"type":48,"value":164},"What to suggest",{"type":43,"tag":166,"props":167,"children":168},"tbody",{},[169,211,268,281,300,327,354],{"type":43,"tag":151,"props":170,"children":171},{},[172,200],{"type":43,"tag":173,"props":174,"children":175},"td",{},[176,178,184,185,191,192,198],{"type":48,"value":177},"Custom ",{"type":43,"tag":86,"props":179,"children":181},{"className":180},[],[182],{"type":48,"value":183},"created_at",{"type":48,"value":101},{"type":43,"tag":86,"props":186,"children":188},{"className":187},[],[189],{"type":48,"value":190},"updated_at",{"type":48,"value":101},{"type":43,"tag":86,"props":193,"children":195},{"className":194},[],[196],{"type":48,"value":197},"deleted_at",{"type":48,"value":199}," columns for audit",{"type":43,"tag":173,"props":201,"children":202},{},[203,209],{"type":43,"tag":86,"props":204,"children":206},{"className":205},[],[207],{"type":48,"value":208},"WITH SYSTEM VERSIONING",{"type":48,"value":210}," — MariaDB tracks all changes automatically",{"type":43,"tag":151,"props":212,"children":213},{},[214,241],{"type":43,"tag":173,"props":215,"children":216},{},[217,219,225,227,233,235],{"type":48,"value":218},"SQL Server temporal syntax — ",{"type":43,"tag":86,"props":220,"children":222},{"className":221},[],[223],{"type":48,"value":224},"WITH (SYSTEM_VERSIONING = ON)",{"type":48,"value":226},", explicit ",{"type":43,"tag":86,"props":228,"children":230},{"className":229},[],[231],{"type":48,"value":232},"PERIOD FOR SYSTEM_TIME",{"type":48,"value":234}," and a named ",{"type":43,"tag":86,"props":236,"children":238},{"className":237},[],[239],{"type":48,"value":240},"HISTORY_TABLE",{"type":43,"tag":173,"props":242,"children":243},{},[244,246,252,254,260,262],{"type":48,"value":245},"MariaDB uses ",{"type":43,"tag":86,"props":247,"children":249},{"className":248},[],[250],{"type":48,"value":251},"CREATE TABLE ... WITH SYSTEM VERSIONING",{"type":48,"value":253}," (no parentheses, no ",{"type":43,"tag":86,"props":255,"children":257},{"className":256},[],[258],{"type":48,"value":259},"= ON",{"type":48,"value":261},", no separate history table); enable it on an existing table with ",{"type":43,"tag":86,"props":263,"children":265},{"className":264},[],[266],{"type":48,"value":267},"ALTER TABLE t ADD SYSTEM VERSIONING",{"type":43,"tag":151,"props":269,"children":270},{},[271,276],{"type":43,"tag":173,"props":272,"children":273},{},[274],{"type":48,"value":275},"Separate audit log table with triggers",{"type":43,"tag":173,"props":277,"children":278},{},[279],{"type":48,"value":280},"System-versioned tables replace this pattern entirely",{"type":43,"tag":151,"props":282,"children":283},{},[284,289],{"type":43,"tag":173,"props":285,"children":286},{},[287],{"type":48,"value":288},"Asking how data looked last month",{"type":43,"tag":173,"props":290,"children":291},{},[292,298],{"type":43,"tag":86,"props":293,"children":295},{"className":294},[],[296],{"type":48,"value":297},"FOR SYSTEM_TIME AS OF '2026-01-01'",{"type":48,"value":299}," — no custom logic needed",{"type":43,"tag":151,"props":301,"children":302},{},[303,314],{"type":43,"tag":173,"props":304,"children":305},{},[306,312],{"type":43,"tag":86,"props":307,"children":309},{"className":308},[],[310],{"type":48,"value":311},"TRUNCATE",{"type":48,"value":313}," on a versioned table",{"type":43,"tag":173,"props":315,"children":316},{},[317,319,325],{"type":48,"value":318},"Not allowed (error 4137) — use ",{"type":43,"tag":86,"props":320,"children":322},{"className":321},[],[323],{"type":48,"value":324},"DELETE HISTORY",{"type":48,"value":326}," instead",{"type":43,"tag":151,"props":328,"children":329},{},[330,341],{"type":43,"tag":173,"props":331,"children":332},{},[333,339],{"type":43,"tag":86,"props":334,"children":336},{"className":335},[],[337],{"type":48,"value":338},"ALTER TABLE",{"type":48,"value":340}," on a versioned table failing",{"type":43,"tag":173,"props":342,"children":343},{},[344,346,352],{"type":48,"value":345},"Set ",{"type":43,"tag":86,"props":347,"children":349},{"className":348},[],[350],{"type":48,"value":351},"system_versioning_alter_history = KEEP",{"type":48,"value":353}," first",{"type":43,"tag":151,"props":355,"children":356},{},[357,368],{"type":43,"tag":173,"props":358,"children":359},{},[360,366],{"type":43,"tag":86,"props":361,"children":363},{"className":362},[],[364],{"type":48,"value":365},"mysqldump",{"type":48,"value":367}," missing historical rows",{"type":43,"tag":173,"props":369,"children":370},{},[371,373,379],{"type":48,"value":372},"Use ",{"type":43,"tag":86,"props":374,"children":376},{"className":375},[],[377],{"type":48,"value":378},"mariadb-dump --dump-history",{"type":48,"value":380}," (10.11+)",{"type":43,"tag":136,"props":382,"children":384},{"id":383},"creating-a-system-versioned-table",[385],{"type":48,"value":386},"Creating a System-Versioned Table",{"type":43,"tag":51,"props":388,"children":389},{},[390],{"type":43,"tag":78,"props":391,"children":392},{},[393],{"type":48,"value":394},"Simplified syntax (recommended):",{"type":43,"tag":396,"props":397,"children":402},"pre",{"className":398,"code":399,"language":400,"meta":401,"style":401},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","CREATE TABLE employees (\n    id INT AUTO_INCREMENT PRIMARY KEY,\n    name VARCHAR(100) NOT NULL,\n    department VARCHAR(50),\n    salary DECIMAL(10,2)\n) WITH SYSTEM VERSIONING;\n","sql","",[403],{"type":43,"tag":86,"props":404,"children":405},{"__ignoreMap":401},[406,417,425,434,443,452],{"type":43,"tag":407,"props":408,"children":411},"span",{"class":409,"line":410},"line",1,[412],{"type":43,"tag":407,"props":413,"children":414},{},[415],{"type":48,"value":416},"CREATE TABLE employees (\n",{"type":43,"tag":407,"props":418,"children":419},{"class":409,"line":30},[420],{"type":43,"tag":407,"props":421,"children":422},{},[423],{"type":48,"value":424},"    id INT AUTO_INCREMENT PRIMARY KEY,\n",{"type":43,"tag":407,"props":426,"children":428},{"class":409,"line":427},3,[429],{"type":43,"tag":407,"props":430,"children":431},{},[432],{"type":48,"value":433},"    name VARCHAR(100) NOT NULL,\n",{"type":43,"tag":407,"props":435,"children":437},{"class":409,"line":436},4,[438],{"type":43,"tag":407,"props":439,"children":440},{},[441],{"type":48,"value":442},"    department VARCHAR(50),\n",{"type":43,"tag":407,"props":444,"children":446},{"class":409,"line":445},5,[447],{"type":43,"tag":407,"props":448,"children":449},{},[450],{"type":48,"value":451},"    salary DECIMAL(10,2)\n",{"type":43,"tag":407,"props":453,"children":455},{"class":409,"line":454},6,[456],{"type":43,"tag":407,"props":457,"children":458},{},[459],{"type":48,"value":460},") WITH SYSTEM VERSIONING;\n",{"type":43,"tag":51,"props":462,"children":463},{},[464,466,472,474,479,481,487,489,495,497,503],{"type":48,"value":465},"MariaDB automatically adds hidden ",{"type":43,"tag":86,"props":467,"children":469},{"className":468},[],[470],{"type":48,"value":471},"ROW_START",{"type":48,"value":473}," and ",{"type":43,"tag":86,"props":475,"children":477},{"className":476},[],[478],{"type":48,"value":115},{"type":48,"value":480}," timestamp columns. Every ",{"type":43,"tag":86,"props":482,"children":484},{"className":483},[],[485],{"type":48,"value":486},"INSERT",{"type":48,"value":488},", ",{"type":43,"tag":86,"props":490,"children":492},{"className":491},[],[493],{"type":48,"value":494},"UPDATE",{"type":48,"value":496},", and ",{"type":43,"tag":86,"props":498,"children":500},{"className":499},[],[501],{"type":48,"value":502},"DELETE",{"type":48,"value":504}," creates a history row.",{"type":43,"tag":51,"props":506,"children":507},{},[508],{"type":43,"tag":78,"props":509,"children":510},{},[511],{"type":48,"value":512},"Add versioning to an existing table:",{"type":43,"tag":396,"props":514,"children":516},{"className":398,"code":515,"language":400,"meta":401,"style":401},"ALTER TABLE employees ADD SYSTEM VERSIONING;\n",[517],{"type":43,"tag":86,"props":518,"children":519},{"__ignoreMap":401},[520],{"type":43,"tag":407,"props":521,"children":522},{"class":409,"line":410},[523],{"type":43,"tag":407,"props":524,"children":525},{},[526],{"type":48,"value":515},{"type":43,"tag":51,"props":528,"children":529},{},[530],{"type":43,"tag":78,"props":531,"children":532},{},[533],{"type":48,"value":534},"Remove versioning (deletes all history):",{"type":43,"tag":396,"props":536,"children":538},{"className":398,"code":537,"language":400,"meta":401,"style":401},"ALTER TABLE employees DROP SYSTEM VERSIONING;\n",[539],{"type":43,"tag":86,"props":540,"children":541},{"__ignoreMap":401},[542],{"type":43,"tag":407,"props":543,"children":544},{"class":409,"line":410},[545],{"type":43,"tag":407,"props":546,"children":547},{},[548],{"type":48,"value":537},{"type":43,"tag":136,"props":550,"children":552},{"id":551},"querying-historical-data",[553],{"type":48,"value":554},"Querying Historical Data",{"type":43,"tag":51,"props":556,"children":557},{},[558,560,566],{"type":48,"value":559},"The ",{"type":43,"tag":86,"props":561,"children":563},{"className":562},[],[564],{"type":48,"value":565},"FOR SYSTEM_TIME",{"type":48,"value":567}," clause goes directly after the table name:",{"type":43,"tag":396,"props":569,"children":571},{"className":398,"code":570,"language":400,"meta":401,"style":401},"-- Data as it was at a specific point in time:\nSELECT * FROM employees FOR SYSTEM_TIME AS OF '2026-01-01 00:00:00';\n\n-- All rows that existed during a period (both boundaries included):\nSELECT * FROM employees FOR SYSTEM_TIME BETWEEN '2025-01-01' AND '2026-01-01';\n\n-- Half-open range (includes start, excludes end):\nSELECT * FROM employees FOR SYSTEM_TIME FROM '2025-01-01' TO '2026-01-01';\n\n-- Every version of every row, ever:\nSELECT * FROM employees FOR SYSTEM_TIME ALL;\n\n-- See the full history of one employee:\nSELECT *, ROW_START, ROW_END FROM employees FOR SYSTEM_TIME ALL WHERE id = 42;\n",[572],{"type":43,"tag":86,"props":573,"children":574},{"__ignoreMap":401},[575,583,591,600,608,616,623,632,641,648,657,666,674,683],{"type":43,"tag":407,"props":576,"children":577},{"class":409,"line":410},[578],{"type":43,"tag":407,"props":579,"children":580},{},[581],{"type":48,"value":582},"-- Data as it was at a specific point in time:\n",{"type":43,"tag":407,"props":584,"children":585},{"class":409,"line":30},[586],{"type":43,"tag":407,"props":587,"children":588},{},[589],{"type":48,"value":590},"SELECT * FROM employees FOR SYSTEM_TIME AS OF '2026-01-01 00:00:00';\n",{"type":43,"tag":407,"props":592,"children":593},{"class":409,"line":427},[594],{"type":43,"tag":407,"props":595,"children":597},{"emptyLinePlaceholder":596},true,[598],{"type":48,"value":599},"\n",{"type":43,"tag":407,"props":601,"children":602},{"class":409,"line":436},[603],{"type":43,"tag":407,"props":604,"children":605},{},[606],{"type":48,"value":607},"-- All rows that existed during a period (both boundaries included):\n",{"type":43,"tag":407,"props":609,"children":610},{"class":409,"line":445},[611],{"type":43,"tag":407,"props":612,"children":613},{},[614],{"type":48,"value":615},"SELECT * FROM employees FOR SYSTEM_TIME BETWEEN '2025-01-01' AND '2026-01-01';\n",{"type":43,"tag":407,"props":617,"children":618},{"class":409,"line":454},[619],{"type":43,"tag":407,"props":620,"children":621},{"emptyLinePlaceholder":596},[622],{"type":48,"value":599},{"type":43,"tag":407,"props":624,"children":626},{"class":409,"line":625},7,[627],{"type":43,"tag":407,"props":628,"children":629},{},[630],{"type":48,"value":631},"-- Half-open range (includes start, excludes end):\n",{"type":43,"tag":407,"props":633,"children":635},{"class":409,"line":634},8,[636],{"type":43,"tag":407,"props":637,"children":638},{},[639],{"type":48,"value":640},"SELECT * FROM employees FOR SYSTEM_TIME FROM '2025-01-01' TO '2026-01-01';\n",{"type":43,"tag":407,"props":642,"children":643},{"class":409,"line":26},[644],{"type":43,"tag":407,"props":645,"children":646},{"emptyLinePlaceholder":596},[647],{"type":48,"value":599},{"type":43,"tag":407,"props":649,"children":651},{"class":409,"line":650},10,[652],{"type":43,"tag":407,"props":653,"children":654},{},[655],{"type":48,"value":656},"-- Every version of every row, ever:\n",{"type":43,"tag":407,"props":658,"children":660},{"class":409,"line":659},11,[661],{"type":43,"tag":407,"props":662,"children":663},{},[664],{"type":48,"value":665},"SELECT * FROM employees FOR SYSTEM_TIME ALL;\n",{"type":43,"tag":407,"props":667,"children":669},{"class":409,"line":668},12,[670],{"type":43,"tag":407,"props":671,"children":672},{"emptyLinePlaceholder":596},[673],{"type":48,"value":599},{"type":43,"tag":407,"props":675,"children":677},{"class":409,"line":676},13,[678],{"type":43,"tag":407,"props":679,"children":680},{},[681],{"type":48,"value":682},"-- See the full history of one employee:\n",{"type":43,"tag":407,"props":684,"children":686},{"class":409,"line":685},14,[687],{"type":43,"tag":407,"props":688,"children":689},{},[690],{"type":48,"value":691},"SELECT *, ROW_START, ROW_END FROM employees FOR SYSTEM_TIME ALL WHERE id = 42;\n",{"type":43,"tag":51,"props":693,"children":694},{},[695],{"type":43,"tag":78,"props":696,"children":697},{},[698],{"type":48,"value":699},"Apply an implicit AS OF to all queries in a session:",{"type":43,"tag":396,"props":701,"children":703},{"className":398,"code":702,"language":400,"meta":401,"style":401},"SET system_versioning_asof = '2026-01-01 00:00:00';\n-- Now all queries against versioned tables see that point in time\nSELECT * FROM employees; -- returns 2026-01-01 snapshot\nSET system_versioning_asof = DEFAULT; -- reset\n",[704],{"type":43,"tag":86,"props":705,"children":706},{"__ignoreMap":401},[707,715,723,731],{"type":43,"tag":407,"props":708,"children":709},{"class":409,"line":410},[710],{"type":43,"tag":407,"props":711,"children":712},{},[713],{"type":48,"value":714},"SET system_versioning_asof = '2026-01-01 00:00:00';\n",{"type":43,"tag":407,"props":716,"children":717},{"class":409,"line":30},[718],{"type":43,"tag":407,"props":719,"children":720},{},[721],{"type":48,"value":722},"-- Now all queries against versioned tables see that point in time\n",{"type":43,"tag":407,"props":724,"children":725},{"class":409,"line":427},[726],{"type":43,"tag":407,"props":727,"children":728},{},[729],{"type":48,"value":730},"SELECT * FROM employees; -- returns 2026-01-01 snapshot\n",{"type":43,"tag":407,"props":732,"children":733},{"class":409,"line":436},[734],{"type":43,"tag":407,"props":735,"children":736},{},[737],{"type":48,"value":738},"SET system_versioning_asof = DEFAULT; -- reset\n",{"type":43,"tag":136,"props":740,"children":742},{"id":741},"transaction-precise-history-innodb-only",[743],{"type":48,"value":744},"Transaction-Precise History (InnoDB Only)",{"type":43,"tag":51,"props":746,"children":747},{},[748],{"type":48,"value":749},"For exact transaction-boundary tracking instead of timestamps:",{"type":43,"tag":396,"props":751,"children":753},{"className":398,"code":752,"language":400,"meta":401,"style":401},"CREATE TABLE ledger (\n    id INT,\n    amount DECIMAL(10,2),\n    trx_start BIGINT UNSIGNED GENERATED ALWAYS AS ROW START,\n    trx_end   BIGINT UNSIGNED GENERATED ALWAYS AS ROW END,\n    PERIOD FOR SYSTEM_TIME(trx_start, trx_end)\n) WITH SYSTEM VERSIONING;\n\nSELECT * FROM ledger FOR SYSTEM_TIME AS OF TRANSACTION 12345;\n",[754],{"type":43,"tag":86,"props":755,"children":756},{"__ignoreMap":401},[757,765,773,781,789,797,805,812,819],{"type":43,"tag":407,"props":758,"children":759},{"class":409,"line":410},[760],{"type":43,"tag":407,"props":761,"children":762},{},[763],{"type":48,"value":764},"CREATE TABLE ledger (\n",{"type":43,"tag":407,"props":766,"children":767},{"class":409,"line":30},[768],{"type":43,"tag":407,"props":769,"children":770},{},[771],{"type":48,"value":772},"    id INT,\n",{"type":43,"tag":407,"props":774,"children":775},{"class":409,"line":427},[776],{"type":43,"tag":407,"props":777,"children":778},{},[779],{"type":48,"value":780},"    amount DECIMAL(10,2),\n",{"type":43,"tag":407,"props":782,"children":783},{"class":409,"line":436},[784],{"type":43,"tag":407,"props":785,"children":786},{},[787],{"type":48,"value":788},"    trx_start BIGINT UNSIGNED GENERATED ALWAYS AS ROW START,\n",{"type":43,"tag":407,"props":790,"children":791},{"class":409,"line":445},[792],{"type":43,"tag":407,"props":793,"children":794},{},[795],{"type":48,"value":796},"    trx_end   BIGINT UNSIGNED GENERATED ALWAYS AS ROW END,\n",{"type":43,"tag":407,"props":798,"children":799},{"class":409,"line":454},[800],{"type":43,"tag":407,"props":801,"children":802},{},[803],{"type":48,"value":804},"    PERIOD FOR SYSTEM_TIME(trx_start, trx_end)\n",{"type":43,"tag":407,"props":806,"children":807},{"class":409,"line":625},[808],{"type":43,"tag":407,"props":809,"children":810},{},[811],{"type":48,"value":460},{"type":43,"tag":407,"props":813,"children":814},{"class":409,"line":634},[815],{"type":43,"tag":407,"props":816,"children":817},{"emptyLinePlaceholder":596},[818],{"type":48,"value":599},{"type":43,"tag":407,"props":820,"children":821},{"class":409,"line":26},[822],{"type":43,"tag":407,"props":823,"children":824},{},[825],{"type":48,"value":826},"SELECT * FROM ledger FOR SYSTEM_TIME AS OF TRANSACTION 12345;\n",{"type":43,"tag":51,"props":828,"children":829},{},[830,832,838,840,846],{"type":48,"value":831},"Uses ",{"type":43,"tag":86,"props":833,"children":835},{"className":834},[],[836],{"type":48,"value":837},"mysql.transaction_registry",{"type":48,"value":839}," internally. Not compatible with ",{"type":43,"tag":86,"props":841,"children":843},{"className":842},[],[844],{"type":48,"value":845},"PARTITION BY SYSTEM_TIME",{"type":48,"value":847},".",{"type":43,"tag":136,"props":849,"children":851},{"id":850},"column-level-control",[852],{"type":48,"value":853},"Column-Level Control",{"type":43,"tag":51,"props":855,"children":856},{},[857],{"type":48,"value":858},"Exclude specific columns from versioning (useful for frequently-updated columns like counters):",{"type":43,"tag":396,"props":860,"children":862},{"className":398,"code":861,"language":400,"meta":401,"style":401},"CREATE TABLE products (\n    id INT PRIMARY KEY,\n    name VARCHAR(100),\n    price DECIMAL(10,2),\n    view_count INT WITHOUT SYSTEM VERSIONING  -- not tracked\n) WITH SYSTEM VERSIONING;\n",[863],{"type":43,"tag":86,"props":864,"children":865},{"__ignoreMap":401},[866,874,882,890,898,906],{"type":43,"tag":407,"props":867,"children":868},{"class":409,"line":410},[869],{"type":43,"tag":407,"props":870,"children":871},{},[872],{"type":48,"value":873},"CREATE TABLE products (\n",{"type":43,"tag":407,"props":875,"children":876},{"class":409,"line":30},[877],{"type":43,"tag":407,"props":878,"children":879},{},[880],{"type":48,"value":881},"    id INT PRIMARY KEY,\n",{"type":43,"tag":407,"props":883,"children":884},{"class":409,"line":427},[885],{"type":43,"tag":407,"props":886,"children":887},{},[888],{"type":48,"value":889},"    name VARCHAR(100),\n",{"type":43,"tag":407,"props":891,"children":892},{"class":409,"line":436},[893],{"type":43,"tag":407,"props":894,"children":895},{},[896],{"type":48,"value":897},"    price DECIMAL(10,2),\n",{"type":43,"tag":407,"props":899,"children":900},{"class":409,"line":445},[901],{"type":43,"tag":407,"props":902,"children":903},{},[904],{"type":48,"value":905},"    view_count INT WITHOUT SYSTEM VERSIONING  -- not tracked\n",{"type":43,"tag":407,"props":907,"children":908},{"class":409,"line":454},[909],{"type":43,"tag":407,"props":910,"children":911},{},[912],{"type":48,"value":460},{"type":43,"tag":51,"props":914,"children":915},{},[916],{"type":48,"value":917},"Or version only specific columns in a non-versioned table:",{"type":43,"tag":396,"props":919,"children":921},{"className":398,"code":920,"language":400,"meta":401,"style":401},"CREATE TABLE config (\n    key VARCHAR(50),\n    value TEXT WITH SYSTEM VERSIONING  -- only this column tracked\n);\n",[922],{"type":43,"tag":86,"props":923,"children":924},{"__ignoreMap":401},[925,933,941,949],{"type":43,"tag":407,"props":926,"children":927},{"class":409,"line":410},[928],{"type":43,"tag":407,"props":929,"children":930},{},[931],{"type":48,"value":932},"CREATE TABLE config (\n",{"type":43,"tag":407,"props":934,"children":935},{"class":409,"line":30},[936],{"type":43,"tag":407,"props":937,"children":938},{},[939],{"type":48,"value":940},"    key VARCHAR(50),\n",{"type":43,"tag":407,"props":942,"children":943},{"class":409,"line":427},[944],{"type":43,"tag":407,"props":945,"children":946},{},[947],{"type":48,"value":948},"    value TEXT WITH SYSTEM VERSIONING  -- only this column tracked\n",{"type":43,"tag":407,"props":950,"children":951},{"class":409,"line":436},[952],{"type":43,"tag":407,"props":953,"children":954},{},[955],{"type":48,"value":956},");\n",{"type":43,"tag":136,"props":958,"children":960},{"id":959},"managing-history-growth",[961],{"type":48,"value":962},"Managing History Growth",{"type":43,"tag":51,"props":964,"children":965},{},[966],{"type":48,"value":967},"Every update adds a row. For high-update tables, history grows fast. Use partitioning to keep current data performant:",{"type":43,"tag":396,"props":969,"children":971},{"className":398,"code":970,"language":400,"meta":401,"style":401},"-- Separate current and historical partitions:\nCREATE TABLE events (\n    id INT,\n    payload JSON\n) WITH SYSTEM VERSIONING\n  PARTITION BY SYSTEM_TIME (\n    PARTITION p_hist HISTORY,\n    PARTITION p_cur  CURRENT\n  );\n\n-- Auto-rotate history by time interval (10.9+):\nCREATE TABLE prices (\n    symbol VARCHAR(10),\n    price DECIMAL(10,4)\n) WITH SYSTEM VERSIONING\n  PARTITION BY SYSTEM_TIME INTERVAL 1 MONTH AUTO (\n    PARTITION p_cur CURRENT\n  );\n",[972],{"type":43,"tag":86,"props":973,"children":974},{"__ignoreMap":401},[975,983,991,998,1006,1014,1022,1030,1038,1046,1053,1061,1069,1077,1085,1093,1102,1111],{"type":43,"tag":407,"props":976,"children":977},{"class":409,"line":410},[978],{"type":43,"tag":407,"props":979,"children":980},{},[981],{"type":48,"value":982},"-- Separate current and historical partitions:\n",{"type":43,"tag":407,"props":984,"children":985},{"class":409,"line":30},[986],{"type":43,"tag":407,"props":987,"children":988},{},[989],{"type":48,"value":990},"CREATE TABLE events (\n",{"type":43,"tag":407,"props":992,"children":993},{"class":409,"line":427},[994],{"type":43,"tag":407,"props":995,"children":996},{},[997],{"type":48,"value":772},{"type":43,"tag":407,"props":999,"children":1000},{"class":409,"line":436},[1001],{"type":43,"tag":407,"props":1002,"children":1003},{},[1004],{"type":48,"value":1005},"    payload JSON\n",{"type":43,"tag":407,"props":1007,"children":1008},{"class":409,"line":445},[1009],{"type":43,"tag":407,"props":1010,"children":1011},{},[1012],{"type":48,"value":1013},") WITH SYSTEM VERSIONING\n",{"type":43,"tag":407,"props":1015,"children":1016},{"class":409,"line":454},[1017],{"type":43,"tag":407,"props":1018,"children":1019},{},[1020],{"type":48,"value":1021},"  PARTITION BY SYSTEM_TIME (\n",{"type":43,"tag":407,"props":1023,"children":1024},{"class":409,"line":625},[1025],{"type":43,"tag":407,"props":1026,"children":1027},{},[1028],{"type":48,"value":1029},"    PARTITION p_hist HISTORY,\n",{"type":43,"tag":407,"props":1031,"children":1032},{"class":409,"line":634},[1033],{"type":43,"tag":407,"props":1034,"children":1035},{},[1036],{"type":48,"value":1037},"    PARTITION p_cur  CURRENT\n",{"type":43,"tag":407,"props":1039,"children":1040},{"class":409,"line":26},[1041],{"type":43,"tag":407,"props":1042,"children":1043},{},[1044],{"type":48,"value":1045},"  );\n",{"type":43,"tag":407,"props":1047,"children":1048},{"class":409,"line":650},[1049],{"type":43,"tag":407,"props":1050,"children":1051},{"emptyLinePlaceholder":596},[1052],{"type":48,"value":599},{"type":43,"tag":407,"props":1054,"children":1055},{"class":409,"line":659},[1056],{"type":43,"tag":407,"props":1057,"children":1058},{},[1059],{"type":48,"value":1060},"-- Auto-rotate history by time interval (10.9+):\n",{"type":43,"tag":407,"props":1062,"children":1063},{"class":409,"line":668},[1064],{"type":43,"tag":407,"props":1065,"children":1066},{},[1067],{"type":48,"value":1068},"CREATE TABLE prices (\n",{"type":43,"tag":407,"props":1070,"children":1071},{"class":409,"line":676},[1072],{"type":43,"tag":407,"props":1073,"children":1074},{},[1075],{"type":48,"value":1076},"    symbol VARCHAR(10),\n",{"type":43,"tag":407,"props":1078,"children":1079},{"class":409,"line":685},[1080],{"type":43,"tag":407,"props":1081,"children":1082},{},[1083],{"type":48,"value":1084},"    price DECIMAL(10,4)\n",{"type":43,"tag":407,"props":1086,"children":1088},{"class":409,"line":1087},15,[1089],{"type":43,"tag":407,"props":1090,"children":1091},{},[1092],{"type":48,"value":1013},{"type":43,"tag":407,"props":1094,"children":1096},{"class":409,"line":1095},16,[1097],{"type":43,"tag":407,"props":1098,"children":1099},{},[1100],{"type":48,"value":1101},"  PARTITION BY SYSTEM_TIME INTERVAL 1 MONTH AUTO (\n",{"type":43,"tag":407,"props":1103,"children":1105},{"class":409,"line":1104},17,[1106],{"type":43,"tag":407,"props":1107,"children":1108},{},[1109],{"type":48,"value":1110},"    PARTITION p_cur CURRENT\n",{"type":43,"tag":407,"props":1112,"children":1114},{"class":409,"line":1113},18,[1115],{"type":43,"tag":407,"props":1116,"children":1117},{},[1118],{"type":48,"value":1045},{"type":43,"tag":51,"props":1120,"children":1121},{},[1122],{"type":43,"tag":78,"props":1123,"children":1124},{},[1125],{"type":48,"value":1126},"Delete old history:",{"type":43,"tag":396,"props":1128,"children":1130},{"className":398,"code":1129,"language":400,"meta":401,"style":401},"-- Delete all history before a date:\nDELETE HISTORY FROM employees BEFORE SYSTEM_TIME '2024-01-01';\n\n-- Delete all history (requires DROP SYSTEM VERSIONING + re-add, or partition drop):\nALTER TABLE employees DROP PARTITION p_hist;\n",[1131],{"type":43,"tag":86,"props":1132,"children":1133},{"__ignoreMap":401},[1134,1142,1150,1157,1165],{"type":43,"tag":407,"props":1135,"children":1136},{"class":409,"line":410},[1137],{"type":43,"tag":407,"props":1138,"children":1139},{},[1140],{"type":48,"value":1141},"-- Delete all history before a date:\n",{"type":43,"tag":407,"props":1143,"children":1144},{"class":409,"line":30},[1145],{"type":43,"tag":407,"props":1146,"children":1147},{},[1148],{"type":48,"value":1149},"DELETE HISTORY FROM employees BEFORE SYSTEM_TIME '2024-01-01';\n",{"type":43,"tag":407,"props":1151,"children":1152},{"class":409,"line":427},[1153],{"type":43,"tag":407,"props":1154,"children":1155},{"emptyLinePlaceholder":596},[1156],{"type":48,"value":599},{"type":43,"tag":407,"props":1158,"children":1159},{"class":409,"line":436},[1160],{"type":43,"tag":407,"props":1161,"children":1162},{},[1163],{"type":48,"value":1164},"-- Delete all history (requires DROP SYSTEM VERSIONING + re-add, or partition drop):\n",{"type":43,"tag":407,"props":1166,"children":1167},{"class":409,"line":445},[1168],{"type":43,"tag":407,"props":1169,"children":1170},{},[1171],{"type":48,"value":1172},"ALTER TABLE employees DROP PARTITION p_hist;\n",{"type":43,"tag":51,"props":1174,"children":1175},{},[1176,1178,1183,1185,1190],{"type":48,"value":1177},"Requires ",{"type":43,"tag":86,"props":1179,"children":1181},{"className":1180},[],[1182],{"type":48,"value":324},{"type":48,"value":1184}," privilege. ",{"type":43,"tag":86,"props":1186,"children":1188},{"className":1187},[],[1189],{"type":48,"value":311},{"type":48,"value":1191}," is not allowed on versioned tables.",{"type":43,"tag":136,"props":1193,"children":1195},{"id":1194},"alter-table-on-versioned-tables",[1196],{"type":48,"value":1197},"ALTER TABLE on Versioned Tables",{"type":43,"tag":51,"props":1199,"children":1200},{},[1201,1203,1208],{"type":48,"value":1202},"By default, ",{"type":43,"tag":86,"props":1204,"children":1206},{"className":1205},[],[1207],{"type":48,"value":338},{"type":48,"value":1209}," on a versioned table raises an error to protect history integrity. To allow it:",{"type":43,"tag":396,"props":1211,"children":1213},{"className":398,"code":1212,"language":400,"meta":401,"style":401},"SET system_versioning_alter_history = KEEP;\nALTER TABLE employees ADD COLUMN manager_id INT;\nSET system_versioning_alter_history = ERROR; -- restore default\n",[1214],{"type":43,"tag":86,"props":1215,"children":1216},{"__ignoreMap":401},[1217,1225,1233],{"type":43,"tag":407,"props":1218,"children":1219},{"class":409,"line":410},[1220],{"type":43,"tag":407,"props":1221,"children":1222},{},[1223],{"type":48,"value":1224},"SET system_versioning_alter_history = KEEP;\n",{"type":43,"tag":407,"props":1226,"children":1227},{"class":409,"line":30},[1228],{"type":43,"tag":407,"props":1229,"children":1230},{},[1231],{"type":48,"value":1232},"ALTER TABLE employees ADD COLUMN manager_id INT;\n",{"type":43,"tag":407,"props":1234,"children":1235},{"class":409,"line":427},[1236],{"type":43,"tag":407,"props":1237,"children":1238},{},[1239],{"type":48,"value":1240},"SET system_versioning_alter_history = ERROR; -- restore default\n",{"type":43,"tag":51,"props":1242,"children":1243},{},[1244,1250,1252,1258],{"type":43,"tag":86,"props":1245,"children":1247},{"className":1246},[],[1248],{"type":48,"value":1249},"KEEP",{"type":48,"value":1251}," allows the alter but historical rows for the new column will have ",{"type":43,"tag":86,"props":1253,"children":1255},{"className":1254},[],[1256],{"type":48,"value":1257},"NULL",{"type":48,"value":1259}," values — the history is technically incomplete. This is usually acceptable for adding columns.",{"type":43,"tag":51,"props":1261,"children":1262},{},[1263,1281,1283,1288],{"type":43,"tag":78,"props":1264,"children":1265},{},[1266,1268,1273,1274,1279],{"type":48,"value":1267},"Convert hidden ",{"type":43,"tag":86,"props":1269,"children":1271},{"className":1270},[],[1272],{"type":48,"value":471},{"type":48,"value":101},{"type":43,"tag":86,"props":1275,"children":1277},{"className":1276},[],[1278],{"type":48,"value":115},{"type":48,"value":1280}," to explicit columns",{"type":48,"value":1282}," (11.7+, MDEV-27293) — once a table is versioned with the hidden form (no ",{"type":43,"tag":86,"props":1284,"children":1286},{"className":1285},[],[1287],{"type":48,"value":232},{"type":48,"value":1289}," clause), you can promote them to explicit columns later without dropping versioning. Useful if you initially started simple and later want transaction-precise history or explicit naming for tooling.",{"type":43,"tag":136,"props":1291,"children":1293},{"id":1292},"key-gotchas",[1294],{"type":48,"value":1295},"Key Gotchas",{"type":43,"tag":1297,"props":1298,"children":1299},"ul",{},[1300,1323,1348,1408,1418,1466],{"type":43,"tag":1301,"props":1302,"children":1303},"li",{},[1304,1314,1316,1321],{"type":43,"tag":78,"props":1305,"children":1306},{},[1307,1312],{"type":43,"tag":86,"props":1308,"children":1310},{"className":1309},[],[1311],{"type":48,"value":311},{"type":48,"value":1313}," is prohibited",{"type":48,"value":1315}," on versioned tables (error 4137). Use ",{"type":43,"tag":86,"props":1317,"children":1319},{"className":1318},[],[1320],{"type":48,"value":324},{"type":48,"value":1322}," or partition management instead.",{"type":43,"tag":1301,"props":1324,"children":1325},{},[1326,1331,1333,1338,1340,1346],{"type":43,"tag":78,"props":1327,"children":1328},{},[1329],{"type":48,"value":1330},"Replication",{"type":48,"value":1332},": ",{"type":43,"tag":86,"props":1334,"children":1336},{"className":1335},[],[1337],{"type":48,"value":115},{"type":48,"value":1339}," is implicitly added to the Primary Key. On replicas, this can cause duplicate key errors during log replay. Fix: set ",{"type":43,"tag":86,"props":1341,"children":1343},{"className":1342},[],[1344],{"type":48,"value":1345},"secure_timestamp = YES",{"type":48,"value":1347}," on the replica.",{"type":43,"tag":1301,"props":1349,"children":1350},{},[1351,1356,1357,1362,1364,1370,1372,1377,1379,1385,1387,1392,1393,1398,1400,1406],{"type":43,"tag":78,"props":1352,"children":1353},{},[1354],{"type":48,"value":1355},"Backups",{"type":48,"value":1332},{"type":43,"tag":86,"props":1358,"children":1360},{"className":1359},[],[1361],{"type":48,"value":365},{"type":48,"value":1363}," \u002F ",{"type":43,"tag":86,"props":1365,"children":1367},{"className":1366},[],[1368],{"type":48,"value":1369},"mariadb-dump",{"type":48,"value":1371}," skips historical rows by default. Use ",{"type":43,"tag":86,"props":1373,"children":1375},{"className":1374},[],[1376],{"type":48,"value":91},{"type":48,"value":1378}," (10.11+) to include them. On restore, set ",{"type":43,"tag":86,"props":1380,"children":1382},{"className":1381},[],[1383],{"type":48,"value":1384},"system_versioning_insert_history=ON",{"type":48,"value":1386}," (10.11+, MDEV-16546) so the loader is allowed to write directly into ",{"type":43,"tag":86,"props":1388,"children":1390},{"className":1389},[],[1391],{"type":48,"value":471},{"type":48,"value":101},{"type":43,"tag":86,"props":1394,"children":1396},{"className":1395},[],[1397],{"type":48,"value":115},{"type":48,"value":1399},"; combine with ",{"type":43,"tag":86,"props":1401,"children":1403},{"className":1402},[],[1404],{"type":48,"value":1405},"secure_timestamp",{"type":48,"value":1407}," set to allow session timestamp changes.",{"type":43,"tag":1301,"props":1409,"children":1410},{},[1411,1416],{"type":43,"tag":78,"props":1412,"children":1413},{},[1414],{"type":48,"value":1415},"Table growth",{"type":48,"value":1417},": without partitioning, history rows accumulate indefinitely. Plan partitioning from the start for high-update tables.",{"type":43,"tag":1301,"props":1419,"children":1420},{},[1421,1426,1428,1434,1436,1441,1443,1448,1450,1456,1458,1464],{"type":43,"tag":78,"props":1422,"children":1423},{},[1424],{"type":48,"value":1425},"DELETE HISTORY with future timestamps",{"type":48,"value":1427},": using ",{"type":43,"tag":86,"props":1429,"children":1431},{"className":1430},[],[1432],{"type":48,"value":1433},"BEFORE SYSTEM_TIME",{"type":48,"value":1435}," with a timestamp beyond ",{"type":43,"tag":86,"props":1437,"children":1439},{"className":1438},[],[1440],{"type":48,"value":115},{"type":48,"value":1442}," max can accidentally delete active rows (MDEV-25468). The ",{"type":43,"tag":86,"props":1444,"children":1446},{"className":1445},[],[1447],{"type":48,"value":115},{"type":48,"value":1449}," max is ",{"type":43,"tag":86,"props":1451,"children":1453},{"className":1452},[],[1454],{"type":48,"value":1455},"2038-01-19",{"type":48,"value":1457}," on 32-bit platforms and on MariaDB before 11.5; on MariaDB 11.5+ on 64-bit it's extended to ",{"type":43,"tag":86,"props":1459,"children":1461},{"className":1460},[],[1462],{"type":48,"value":1463},"2106-02-07 06:28:15 UTC",{"type":48,"value":1465}," (MDEV-32188). Stay well below your platform's max.",{"type":43,"tag":1301,"props":1467,"children":1468},{},[1469,1480,1482,1487,1489,1495],{"type":43,"tag":78,"props":1470,"children":1471},{},[1472,1478],{"type":43,"tag":86,"props":1473,"children":1475},{"className":1474},[],[1476],{"type":48,"value":1477},"SYSTEM",{"type":48,"value":1479}," as a column name",{"type":48,"value":1481},": causes parser errors in ",{"type":43,"tag":86,"props":1483,"children":1485},{"className":1484},[],[1486],{"type":48,"value":338},{"type":48,"value":1488}," statements. Use backticks: ",{"type":43,"tag":86,"props":1490,"children":1492},{"className":1491},[],[1493],{"type":48,"value":1494},"`SYSTEM`",{"type":48,"value":847},{"type":43,"tag":136,"props":1497,"children":1499},{"id":1498},"use-cases",[1500],{"type":48,"value":1501},"Use Cases",{"type":43,"tag":1297,"props":1503,"children":1504},{},[1505,1515,1525,1535,1545],{"type":43,"tag":1301,"props":1506,"children":1507},{},[1508,1513],{"type":43,"tag":78,"props":1509,"children":1510},{},[1511],{"type":48,"value":1512},"Audit trails",{"type":48,"value":1514}," — who changed what and when, without application code",{"type":43,"tag":1301,"props":1516,"children":1517},{},[1518,1523],{"type":43,"tag":78,"props":1519,"children":1520},{},[1521],{"type":48,"value":1522},"GDPR \u002F PCI DSS compliance",{"type":48,"value":1524}," — prove what personal data contained at any date",{"type":43,"tag":1301,"props":1526,"children":1527},{},[1528,1533],{"type":43,"tag":78,"props":1529,"children":1530},{},[1531],{"type":48,"value":1532},"Point-in-time recovery",{"type":48,"value":1534}," — restore a row or table to a previous state without a full backup restore",{"type":43,"tag":1301,"props":1536,"children":1537},{},[1538,1543],{"type":43,"tag":78,"props":1539,"children":1540},{},[1541],{"type":48,"value":1542},"Slowly-changing dimensions",{"type":48,"value":1544}," — track employee department\u002Fsalary history, product price history",{"type":43,"tag":1301,"props":1546,"children":1547},{},[1548,1553],{"type":43,"tag":78,"props":1549,"children":1550},{},[1551],{"type":48,"value":1552},"Debugging",{"type":48,"value":1554}," — see exactly what changed and when in production data",{"type":43,"tag":136,"props":1556,"children":1558},{"id":1557},"sources",[1559],{"type":48,"value":1560},"Sources",{"type":43,"tag":1297,"props":1562,"children":1563},{},[1564,1576,1584,1594],{"type":43,"tag":1301,"props":1565,"children":1566},{},[1567],{"type":43,"tag":1568,"props":1569,"children":1573},"a",{"href":1570,"rel":1571},"https:\u002F\u002Fmariadb.com\u002Fdocs\u002Fserver\u002Freference\u002Fsql-structure\u002Ftemporal-tables\u002Fsystem-versioned-tables",[1572],"nofollow",[1574],{"type":48,"value":1575},"System-Versioned Tables — MariaDB Docs",{"type":43,"tag":1301,"props":1577,"children":1578},{},[1579],{"type":43,"tag":1568,"props":1580,"children":1582},{"href":1570,"rel":1581},[1572],[1583],{"type":48,"value":1575},{"type":43,"tag":1301,"props":1585,"children":1586},{},[1587],{"type":43,"tag":1568,"props":1588,"children":1591},{"href":1589,"rel":1590},"https:\u002F\u002Fmariadb.com\u002Fresources\u002Fblog\u002Fuse-cases-for-mariadb-data-versioning\u002F",[1572],[1592],{"type":48,"value":1593},"Use Cases for MariaDB Data Versioning — MariaDB Blog",{"type":43,"tag":1301,"props":1595,"children":1596},{},[1597],{"type":43,"tag":1568,"props":1598,"children":1601},{"href":1599,"rel":1600},"https:\u002F\u002Fmariadb.com\u002Fresources\u002Fblog\u002Frewinding-time-in-mariadb-databases-system-versioning-and-application-time\u002F",[1572],[1602],{"type":48,"value":1603},"Rewinding Time in MariaDB Databases — MariaDB Blog",{"type":43,"tag":51,"props":1605,"children":1606},{},[1607],{"type":43,"tag":55,"props":1608,"children":1609},{},[1610,1612,1619],{"type":48,"value":1611},"For topics not covered here, see the official MariaDB documentation at ",{"type":43,"tag":1568,"props":1613,"children":1616},{"href":1614,"rel":1615},"https:\u002F\u002Fmariadb.com\u002Fdocs",[1572],[1617],{"type":48,"value":1618},"mariadb.com\u002Fdocs",{"type":48,"value":847},{"type":43,"tag":1621,"props":1622,"children":1623},"style",{},[1624],{"type":48,"value":1625},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1627,"total":634},[1628,1642,1654,1665,1677,1685,1697],{"slug":1629,"name":1629,"fn":1630,"description":1631,"org":1632,"tags":1633,"stars":26,"repoUrl":27,"updatedAt":1641},"mariadb-features","optimize and manage MariaDB databases","MariaDB-specific features and capabilities that go beyond standard MySQL. Use when evaluating MariaDB, optimizing an existing MariaDB application, reviewing code or schema for MariaDB improvements, asking what MariaDB can do that other databases cannot, or migrating from Oracle to MariaDB. Also use when the user asks what could be improved in how a codebase uses MariaDB, or asks about MariaDB advantages over MySQL or PostgreSQL.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1634,1635,1636,1639],{"name":24,"slug":25,"type":15},{"name":9,"slug":8,"type":15},{"name":1637,"slug":1638,"type":15},"Performance","performance",{"name":1640,"slug":400,"type":15},"SQL","2026-07-16T06:01:55.988338",{"slug":1643,"name":1643,"fn":1644,"description":1645,"org":1646,"tags":1647,"stars":26,"repoUrl":27,"updatedAt":1653},"mariadb-mcp","connect AI agents to MariaDB","How to connect AI agents to MariaDB using the Model Context Protocol (MCP). Use when setting up MCP with MariaDB, connecting Claude Code, Cursor, or other AI tools to a MariaDB database, enabling natural language database queries, or building AI applications that need live database access. The MariaDB MCP Server lets agents query schemas, run read-only SQL, and perform semantic search against MariaDB.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1648,1649,1650],{"name":24,"slug":25,"type":15},{"name":9,"slug":8,"type":15},{"name":1651,"slug":1652,"type":15},"MCP","mcp","2026-07-13T06:14:00.682655",{"slug":1655,"name":1655,"fn":1656,"description":1657,"org":1658,"tags":1659,"stars":26,"repoUrl":27,"updatedAt":1664},"mariadb-query-optimization","optimize MariaDB database queries","Best practices for query optimization in MariaDB — indexing strategies, EXPLAIN analysis, pagination, histogram statistics, and MariaDB-specific optimizer settings. Use when diagnosing slow queries, designing indexes, reviewing schema or query performance, or when queries involve large tables, pagination, GROUP BY, or ORDER BY. Also use when the user asks about MariaDB query performance, EXPLAIN output, or optimizer behavior.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1660,1661,1662,1663],{"name":24,"slug":25,"type":15},{"name":9,"slug":8,"type":15},{"name":1637,"slug":1638,"type":15},{"name":1640,"slug":400,"type":15},"2026-07-13T06:14:12.656074",{"slug":1666,"name":1666,"fn":1667,"description":1668,"org":1669,"tags":1670,"stars":26,"repoUrl":27,"updatedAt":1676},"mariadb-replication-and-ha","configure MariaDB replication and high availability","Best practices for MariaDB replication and high availability — Galera Cluster, GTID replication, semi-synchronous replication, parallel replication, and application patterns for HA environments. Use when setting up replication, designing applications for HA, working with Galera Cluster, asking about MariaDB GTID, handling replication lag in application code, or choosing between replication topologies. IMPORTANT — MariaDB GTID format is incompatible with MySQL GTID, and Galera Cluster needs no server plugin to load but does require the separate galera wsrep provider library (galera-4).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1671,1674,1675],{"name":1672,"slug":1673,"type":15},"Architecture","architecture",{"name":24,"slug":25,"type":15},{"name":9,"slug":8,"type":15},"2026-07-13T06:14:13.989369",{"slug":4,"name":4,"fn":5,"description":6,"org":1678,"tags":1679,"stars":26,"repoUrl":27,"updatedAt":28},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1680,1681,1682,1683,1684],{"name":20,"slug":21,"type":15},{"name":17,"slug":18,"type":15},{"name":24,"slug":25,"type":15},{"name":13,"slug":14,"type":15},{"name":9,"slug":8,"type":15},{"slug":1686,"name":1686,"fn":1687,"description":1688,"org":1689,"tags":1690,"stars":26,"repoUrl":27,"updatedAt":1696},"mariadb-vector","build semantic search with MariaDB vectors","Best practices for using vectors and AI with MariaDB. Use when writing SQL involving VECTOR columns, building RAG or semantic search with MariaDB, choosing embedding models, designing vector indexes, or integrating MariaDB with AI frameworks like LangChain, LlamaIndex, or Spring AI. Also use when the user mentions MariaDB and any of: vectors, embeddings, similarity search, nearest neighbor, AI, RAG, or LLM. IMPORTANT — MariaDB has native built-in vector support since version 11.7; it is NOT a plugin or extension (unlike pgvector for PostgreSQL). Do not recommend installing any extension.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1691,1692,1693],{"name":24,"slug":25,"type":15},{"name":9,"slug":8,"type":15},{"name":1694,"slug":1695,"type":15},"Migration","migration","2026-07-13T06:14:01.939479",{"slug":1698,"name":1698,"fn":1699,"description":1700,"org":1701,"tags":1702,"stars":26,"repoUrl":27,"updatedAt":1709},"mysql-to-mariadb","migrate applications from MySQL to MariaDB","Compatibility guide for developers moving from MySQL to MariaDB, and for developers with MySQL experience working with MariaDB. Use when migrating a MySQL application to MariaDB, when MySQL syntax or habits cause unexpected behavior in MariaDB, when asking about MySQL\u002FMariaDB compatibility, or when adapting code written for MySQL to run on MariaDB. IMPORTANT — MariaDB diverges significantly from MySQL 8.0 and is not a simple drop-in replacement for modern MySQL. Authentication plugins, JSON handling, GTID replication, and several SQL features differ in important ways.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1703,1704,1705,1706],{"name":24,"slug":25,"type":15},{"name":9,"slug":8,"type":15},{"name":1694,"slug":1695,"type":15},{"name":1707,"slug":1708,"type":15},"MySQL","mysql","2026-07-13T06:14:08.675338",{"items":1711,"total":634},[1712,1719,1725,1732,1738,1746,1752,1759],{"slug":1629,"name":1629,"fn":1630,"description":1631,"org":1713,"tags":1714,"stars":26,"repoUrl":27,"updatedAt":1641},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1715,1716,1717,1718],{"name":24,"slug":25,"type":15},{"name":9,"slug":8,"type":15},{"name":1637,"slug":1638,"type":15},{"name":1640,"slug":400,"type":15},{"slug":1643,"name":1643,"fn":1644,"description":1645,"org":1720,"tags":1721,"stars":26,"repoUrl":27,"updatedAt":1653},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1722,1723,1724],{"name":24,"slug":25,"type":15},{"name":9,"slug":8,"type":15},{"name":1651,"slug":1652,"type":15},{"slug":1655,"name":1655,"fn":1656,"description":1657,"org":1726,"tags":1727,"stars":26,"repoUrl":27,"updatedAt":1664},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1728,1729,1730,1731],{"name":24,"slug":25,"type":15},{"name":9,"slug":8,"type":15},{"name":1637,"slug":1638,"type":15},{"name":1640,"slug":400,"type":15},{"slug":1666,"name":1666,"fn":1667,"description":1668,"org":1733,"tags":1734,"stars":26,"repoUrl":27,"updatedAt":1676},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1735,1736,1737],{"name":1672,"slug":1673,"type":15},{"name":24,"slug":25,"type":15},{"name":9,"slug":8,"type":15},{"slug":4,"name":4,"fn":5,"description":6,"org":1739,"tags":1740,"stars":26,"repoUrl":27,"updatedAt":28},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1741,1742,1743,1744,1745],{"name":20,"slug":21,"type":15},{"name":17,"slug":18,"type":15},{"name":24,"slug":25,"type":15},{"name":13,"slug":14,"type":15},{"name":9,"slug":8,"type":15},{"slug":1686,"name":1686,"fn":1687,"description":1688,"org":1747,"tags":1748,"stars":26,"repoUrl":27,"updatedAt":1696},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1749,1750,1751],{"name":24,"slug":25,"type":15},{"name":9,"slug":8,"type":15},{"name":1694,"slug":1695,"type":15},{"slug":1698,"name":1698,"fn":1699,"description":1700,"org":1753,"tags":1754,"stars":26,"repoUrl":27,"updatedAt":1709},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1755,1756,1757,1758],{"name":24,"slug":25,"type":15},{"name":9,"slug":8,"type":15},{"name":1694,"slug":1695,"type":15},{"name":1707,"slug":1708,"type":15},{"slug":1760,"name":1760,"fn":1761,"description":1762,"org":1763,"tags":1764,"stars":26,"repoUrl":27,"updatedAt":1768},"oracle-to-mariadb","migrate Oracle databases to MariaDB","Compatibility guide for developers migrating from Oracle Database to MariaDB. Use when migrating Oracle schemas, PL\u002FSQL procedures, or applications to MariaDB, when Oracle syntax causes unexpected behavior in MariaDB, or when evaluating MariaDB as an Oracle replacement. MariaDB is the only open source database with native PL\u002FSQL compatibility — MariaDB's sql_mode=ORACLE enables migration of approximately 80% of Oracle code without rewrites.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1765,1766,1767],{"name":24,"slug":25,"type":15},{"name":9,"slug":8,"type":15},{"name":1694,"slug":1695,"type":15},"2026-07-13T06:14:11.069809"]