Skip to content

Native: let a MySQL node wait out another node's bootstrap - #567

Merged
rmcdaniel merged 4 commits into
mainfrom
rust-325-mysql-bootstrap-race
Oct 21, 2026
Merged

rmcdaniel merged 4 commits into
mainfrom
rust-325-mysql-bootstrap-race

Conversation

@rmcdaniel

Copy link
Copy Markdown
Member

Part of #325. A native node starting on an empty MySQL or MariaDB database no longer refuses while another node is still bootstrapping it.

Found by

A multi-node smoke run (#549) started three native nodes together on an empty MySQL database. One node exited with 409 unsupported_rust_schema.

Cause

  • MySQL commits DDL on its own.
  • One node created dw_server_schema. Before it recorded its rust-initializing marker, another node's read-only preflight ran. That preflight runs before the bootstrap lock, saw an empty marker table and refused.
  • A node killed in the same window left a database that no node could start on.
  • PostgreSQL bootstraps inside one locked transaction and SQLite inside one file transaction, so neither has this window.

Change

  • Preflight now accepts an empty marker table when it is the only table, and the node then waits for the bootstrap lock.
  • Under the lock, a missing marker is recorded before the migration runs. This also recovers a node killed between creating the table and recording the marker.

Checks

  • The real-kill qualification gains a marker-table phase. It kills a bootstrapping child right after the child creates the marker table, while it holds the bootstrap lock.
  • A concurrent start must still be waiting one second later, and must then finish once the child is gone.
  • Without the preflight change, the concurrent start refused at once.
  • All 15 ignored MySQL qualification tests pass locally on MySQL 8.0 and MariaDB 10.11, on this branch merged with main after Fingerprint a stopped PHP source database for backup proof #523.

🤖 Generated with Claude Code

durable-workflow-ops and others added 3 commits October 20, 2026 19:53
MySQL commits DDL on its own, so between one node creating dw_server_schema
and recording its rust-initializing marker, a second node's read-only
preflight saw an empty marker table and refused with
unsupported_rust_schema. A node killed in that window left a database no
node could start on. Found when three nodes started together in the
multi-node harness.

Preflight now accepts an empty marker table when it is the only table, so
the node waits for the bootstrap lock; under the lock a missing marker is
recorded before the migration runs. The kill qualification gains a
marker-table phase in which a concurrent start must wait for the lock and
then complete.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…to rust-325-mysql-bootstrap-race

# Conflicts:
#	docs/rust-server-port.md
…rap-race

# Conflicts:
#	docs/rust-server-port.md
@rmcdaniel
rmcdaniel enabled auto-merge October 21, 2026 03:29
…rap-race

# Conflicts:
#	docs/rust-server-port.md
@rmcdaniel

Copy link
Copy Markdown
Member Author

Merged main after #566 (755a68d). The port-log conflict was resolved by keeping both entries. Cancelled the superseded run 39538868737 for the previous head.

@sonarqubecloud

Copy link
Copy Markdown

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.

2 participants