Skip to content

docs(rfc): RFC-005 revision 2 after max-effort review - #266

Open
askdba wants to merge 3 commits into
mainfrom
docs/rfc-005-v2
Open

askdba wants to merge 3 commits into
mainfrom
docs/rfc-005-v2

Conversation

@askdba

@askdba askdba commented Nov 3, 2026

Copy link
Copy Markdown
Owner

Summary

Rewrites RFC-005 (docs/RFC-005-INNODB-INDEX-STORAGE.md, merged as revision 1 in #218) after a max-effort review found design flaws in it. Design decisions confirmed by the maintainer before writing:

  • GTID mode is required for every storage=innodb index.
  • The writer role comes from a writer_uuid compare-and-set, with an explicit takeover after async promotion.
  • Phase 1 is standalone: nothing replicates.

The RFC's new §11 maps each problem to its fix. In short:

Problem in revision 1 Revision 2
Checkpoints at binlog rotation, written to the binlog: a large checkpoint triggers the next one forever Timer-only checkpoints for storage=innodb; standalone writes use sql_log_bin=0
Index rows replicated before roles existed: replicas collide and stop replication Standalone Phase 1; replication is opt-in in Phase 2b
Promotion compared binlog file names across servers: a promoted replica skips every event GTID sets for resume and skip; GTID mode required
Fencing by GTID UUID breaks on Group Replication; role taken from read_only writer_uuid compare-and-set on every write; GR claims automatically; MYVECTOR_INDEX_TAKEOVER for async
Timer checkpoints mid-transaction; idle indexes stop advancing Transaction-boundary rule; idle indexes update ckpt_gtids
Followers could mix checkpoints, wait forever, or freeze under filters Polling, chunk-count check, required commit order, filter check
Generations reset after drop; weak name key; TIMESTAMP Tombstones, binary 776-byte names with surrogate key, DATETIME(6)
Stored header and links data reached memory unchecked Shared structural validation and header CRC
Global binlog_row_image=MINIMAL suggested (breaks online updates) Session-only, with a warning
Migration relied on save (dirty nodes only) MYVECTOR_INDEX_MIGRATE, real full save, crash-rule table
Uninstall blocked; install SQL not re-runnable Short-lived command-service sessions; CREATE ... IF NOT EXISTS under sql_log_bin=0
Write volume ignored vector updates Corrected numbers and a sizing section (redo, purge, binlog)

Also new:

Notes for reviewers

  • This is a design doc only. It changes no code, so no build or tests were run.
  • Every code citation was re-checked against main at 7a42512.
  • Size and volume figures are calculations, not measurements. Phase 3 measures them.
  • Taken from MySQL knowledge rather than tested here:
    • the default of replica_preserve_commit_order (ON since 8.0.27)
    • tagged GTIDs (8.3 and later)
    • MYSQL_RPL_GTID support in mysql_binlog_open()
    • GR stamping transactions with the group name
    • the redo-log default (100 MB)

🤖 Generated with Claude Code

https://claude.ai/code/session_0137WC8aYwwneCuPXq4i7yTq

Rewrites RFC-005 to fix the design flaws a max-effort review found in
revision 1:

- storage=innodb checkpoints run on a timer at transaction boundaries,
  never at binlog rotation (rotation-triggered checkpoints that write to
  the binlog looped forever)
- Phase 1 is standalone: index writes use sql_log_bin=0, so replicas
  keep their own rows and nothing collides; replicating index rows is
  opt-in in Phase 2b
- GTID mode is required; resume, restore and promotion use GTID sets,
  never binlog file names compared across servers
- writer_uuid compare-and-set on every write, GR primary claims
  automatically, async promotion uses MYVECTOR_INDEX_TAKEOVER
- followers poll index_meta, check chunk counts, require commit order
  and refuse filtered myvector tables
- tombstones keep generations rising, binary 776-byte index names,
  DATETIME(6), structural validation of stored data, crash-safe
  migration procedure, short-lived command-service sessions
- corrected write-volume numbers (vector updates) and a sizing section
- Phase 0 prerequisite: #265

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137WC8aYwwneCuPXq4i7yTq
@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 52 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b5bdcca4-909e-4eb6-8ca4-78849ebacd56
Commits

Reviewing files that changed from the base of the PR and between 7a42512 and bbee3ed.

Files selected for processing: 1
  • docs/RFC-005-INNODB-INDEX-STORAGE.md
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-03T05:28:40.900512Z 4a93b7c PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4a93b7c29c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/RFC-005-INNODB-INDEX-STORAGE.md Outdated
**version `s`**, then commits `index_meta.ckpt_seq = s` last:
**Copy, then write.** The checkpoint holds the online-update queue paused (as today,
§3) only while it copies the dirty chunks and the header into a buffer, which is a
memory copy. Then it lets updates continue and writes from the buffer. Online updates

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve updates that arrive during checkpoint writes

When online updates resume after the buffer copy but before the SQL writes finish, they can add changes to the same dirty sets. The spec clears those sets only after publication (§4.4, line 382), so those post-copy changes can be cleared without being persisted; a later checkpoint may then advance ckpt_gtids past them, losing them after a restart. Keep post-copy dirtiness separate and publish the GTID boundary corresponding to the buffered snapshot.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid, fixed in fbc66e9. §4.4 Copy, then write now does three things while the queue is paused at a transaction boundary: copies the dirty chunks and header, records the applied GTID set at that instant as ckpt_gtids, and swaps the dirty sets (takes the current ones, starts empty ones). Updates during the SQL writes land in the new sets for the next checkpoint. The published ckpt_gtids therefore matches the published chunks exactly. A failed checkpoint merges its taken sets back. Test 9 now covers both cases.

Comment on lines +573 to +576
operator runs `CALL mysql.MYVECTOR_INDEX_TAKEOVER();` on the new primary. It sets
`writer_uuid` to this server for every index and switches the server to writer.
There is no automatic takeover: two servers that both believe they were promoted
must not both claim.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fence the old primary before async takeover

If an async primary remains running but becomes unreachable during failover, takeover changes writer_uuid only on the promoted replica until replication conveys that change. The old primary still has its own UUID in its local metadata, so both servers can pass the per-server compare-and-set and checkpoint divergent indexes. Require external fencing of the old primary before takeover, or use a mechanism that actually prevents both copies from authorizing writes.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid, addressed in fbc66e9. With async replication there's no consensus, so nothing inside the database can stop a partitioned old primary from passing its own local compare-and-set; the same partition lets it accept user writes too. §4.10 now requires the operator to fence the old primary before takeover (super_read_only, stop it, or isolate it), as async failover already needs, and the procedure's docs and output say so. It also says what happens if an unfenced primary rejoins: the replicated takeover changes its writer_uuid and it becomes a follower, and its divergent checkpoints are errant transactions. Group Replication avoids this through certification. Test 20 now fences first.

Comment thread docs/RFC-005-INNODB-INDEX-STORAGE.md Outdated
- Nothing about the index enters the binlog, so a primary's rows never reach a
replica, and nothing can collide or stop a replication applier.
- A backup taken on any server includes that server's index.
- `writer_uuid` is always the local `server_uuid`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Rebind the writer UUID when restoring to a new server

When a standalone backup or copied datadir is loaded under a new server_uuid (a scenario explicitly supported in §4.7), its persisted writer_uuid still names the source server. Checkpoints require writer_uuid = @@server_uuid (§4.4), so they will fail their compare-and-set and stop advancing the durable index. Rebind the UUID during standalone restore or startup before allowing writes.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid, fixed in fbc66e9. In standalone mode, a server that loads an index whose writer_uuid isn't its own (after a restore, copied datadir or clone) rebinds it to @@server_uuid with sql_log_bin = 0 and logs it (§4.8, referenced from §4.7). Replicated mode never rebinds automatically, since that's what takeover is for. Test 3 now checks that checkpoints continue after a copied-datadir start.

…ore takeover, standalone writer rebind

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137WC8aYwwneCuPXq4i7yTq
@askdba

askdba commented Nov 3, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

…dex checkpoints, mixed-backend stream question

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137WC8aYwwneCuPXq4i7yTq
@askdba

askdba commented Nov 3, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 24 minutes.

@askdba

askdba commented Nov 3, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 58 minutes.

@askdba

askdba commented Nov 3, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 52 minutes.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant