Skip to content

CONCEPT Cited by 1 source

InnoDB parent-table rename pinning

Definition

InnoDB parent-table rename pinning is the PlanetScale-MySQL-fork behaviour — enabled by setting the server variable rename_table_preserve_foreign_key=1 — that makes RENAME TABLE parent TO parent_old keep each child table's FK definition pinned to the name parent instead of updating it to parent_old. It inverts the default InnoDB behaviour, where the child's FK follows the parent table to its new name by virtue of InnoDB tracking tables internally by memory address rather than by name.

The default behaviour this overrides

From the post:

"if you have a foreign key pair of a parent and a child, and you RENAME TABLE parent TO old_parent, the child's foreign key constraint follows the parent table onto its new name, old_parent. In the internal InnoDB implementation, the parent table retains its memory address, and, in a way, 'following the parent to its new name' really means nothing changes in the children's foreign key references, as they keep using the same pointers. It's mostly the external facing schema definition that changes to reflect a FOREIGN KEY (...) REFERENCED old_parent (...)." (Source: sources/2026-04-21-planetscale-the-challenges-of-supporting-foreign-key-constraints)

In vanilla InnoDB, the child's FK is a pointer that happens to have a rendered name; renaming the parent renames the pointer's target, and the child's FK definition follows.

Why this breaks shadow-table Online DDL on a parent

Shadow-table online-DDL on a parent table rebuilds parent elsewhere and atomically swaps it in via two RENAME TABLEs: parent → parent_old, parent_shadow → parent. With default InnoDB behaviour, the children's FKs would follow parent to parent_old, leaving the newly-installed production parent (formerly the shadow) with no children referencing it.

That breaks referential integrity for every child: queries against parent succeed, but FK enforcement acts on parent_old. Worse, dropping parent_old (cleanup step) would cascade-drop or fail against every child FK.

The patch

PlanetScale's MySQL fork ships commit bb777e3e, introducing the rename_table_preserve_foreign_key server variable. With =1, a RENAME TABLE pins each child's FK to the name rather than the table pointer: after the rename, the children still reference parent (by name), and since the shadow is now parent, everything lines up.

The default value preserves upstream behaviour; Vitess sets =1 during Online DDL cutover only on PlanetScale's MySQL fork.

Composition with internal operations tables

rename_table_preserve_foreign_key solves the parent-side rename problem. Its sibling primitive internal operations tables solves the child-side shadow-table problem: during backfill, the child's shadow table is FK-exempt so it doesn't interfere with the live parent. Together, the two primitives let shadow-table Online DDL work on FK-carrying tables of either role.

Scope

  • Fork-specific: upstream MySQL doesn't ship the server variable. PlanetScale Vitess deployments that run on PlanetScale's fork get the capability; deployments on vanilla MySQL don't.
  • Targeted: only active during Online DDL cutover, gated behind a session-level SET by Vitess.
  • Single-shard only, as with all of Vitess's FK support as of 2023-12-05.

Seen in

  • sources/2026-04-21-planetscale-the-challenges-of-supporting-foreign-key-constraints — canonical wiki home. Noach + Gupta describe both the motivation (parent rename breaks children by default) and the fork-level fix ("we introduce a new server variable, rename_table_preserve_foreign_key. When set to 1, a RENAME TABLE preserves the foreign key definition on the children by pinning it to the name of the table.") including the GitHub commit link.
Last updated · 550 distilled / 1,221 read