Skip to content

Move Tables: 1.2 skip-tables and run overall move tables flow except cutover (#8206)#1705

Merged
zacharysierakowski merged 50 commits into
feature-move-tablesfrom
zacharysierakowski/move-tables-1.2
Jun 11, 2026
Merged

Move Tables: 1.2 skip-tables and run overall move tables flow except cutover (#8206)#1705
zacharysierakowski merged 50 commits into
feature-move-tablesfrom
zacharysierakowski/move-tables-1.2

Conversation

@zacharysierakowski

@zacharysierakowski zacharysierakowski commented Jun 11, 2026

Copy link
Copy Markdown

closes https://github.com/github/database-infrastructure/issues/8206

Building on the work from @chriskirkland and @womoruyi over in #1700, this PR just takes the code from that branch and patches up the git history so there aren't conflicts against the feature branch for the move-tables effort.

I also took some time to clean up some lingering logging from the demo. And applied some changes to fix up some leftover TODO(chriskirkland)s 🙂

For full PR description, i'm deferring to #1700 because there's already a ton of context there!

danieljoos and others added 30 commits May 15, 2026 14:36
- Replace WriteChangelog bypass TODO with intentional comment explaining
  the single-chokepoint design decision
- Remove demo hack code: simulateMoveTablesCutover(), TmpCutoverFilename
  field, --target-cutover-filename flag, and file-based cutover polling loop
- Downgrade per-chunk/per-event debug logging from Info to Debugf
- Fix pre-existing test call-sites for changed function signatures (nil args)
- Add tests for all #8206 acceptance criteria:
  - No ghost or changelog table created in move-tables mode
  - WriteChangelog is a no-op in move-tables mode
  - No changelog listener registered on the streamer
  - Heartbeat goroutine not started
  - finalCleanup skips drop operations
- Replace WriteChangelog bypass TODO with intentional comment explaining
  the single-chokepoint design decision
- Remove demo hack code: simulateMoveTablesCutover(), TmpCutoverFilename
  field, --target-cutover-filename flag, and file-based cutover polling loop
- Downgrade per-chunk/per-event debug logging from Info to Debugf
- Fix pre-existing test call-sites for changed function signatures (nil args)
- Fix test teardown to drop changelog table between tests
- Add tests for all #8206 acceptance criteria:
  - No ghost or changelog table created in move-tables mode
  - WriteChangelog is a no-op in move-tables mode
  - No changelog listener registered on the streamer
  - Heartbeat goroutine not started
  - finalCleanup skips drop operations
- Fix TearDownTest assertion ordering: otherDB drop was missing NoError
  check after _ghc drop line was inserted
- Revert Migrate() log strings to 'ghost table' — the 'target table'
  wording was a regression affecting standard (non-move-tables) users
- Fix ApplyIterationMoveTableCopyQueries test to pass suite.db instead
  of nil to avoid potential panic on sourceDB.Query()
Explain why TestFinalCleanup, TestInitiateStreaming, and TestNoHeartbeat
tests verify the guard predicate rather than calling the full function,
and which other tests provide the behavioral proof.
- Remove unused simulateMoveTablesCutover() function (missed in demo hack cleanup)
- Fix errorlint: use %w instead of %v in fmt.Errorf (3 sites)
- Fix ineffassign: suppress unused err from CREATE DATABASE IF NOT EXISTS
- Fix rowserrcheck: check sqlRows.Err() after scan loop in ApplyIterationMoveTableCopyQueries
- Fix whitespace: remove trailing newline after ApplierConnectionConfig assignment
- Remove contradictory TODO above WriteChangelog bypass (the comment
  now explains the bypass is intentional, so the TODO was misleading)
- Fix typo: #82066 → #8206 in test comment
- Update WriteChangelog doc comment to reflect empty-string return in
  move-tables mode
- Improve test comments: fix flawed reasoning in TestFinalCleanup,
  clarify TestStreaming tautology, add test-infrastructure note to
  TestHeartbeat

@danieljoos danieljoos left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice 🚀

Comment thread go/logic/applier.go Outdated
@zacharysierakowski zacharysierakowski changed the base branch from move-tables/applier-dml-events to feature-move-tables June 11, 2026 13:12
@danieljoos danieljoos added the feature-move-tables PRs that are associated with the new move-tables feature label Jun 11, 2026
@zacharysierakowski zacharysierakowski changed the title move tables 1.2 1.2 skip-tables (#8206) Jun 11, 2026
@zacharysierakowski zacharysierakowski changed the title 1.2 skip-tables (#8206) Move Tables: 1.2 skip-tables and run overall move tables flow except cutover (#8206) Jun 11, 2026
@zacharysierakowski zacharysierakowski marked this pull request as ready for review June 11, 2026 14:22
Copilot AI review requested due to automatic review settings June 11, 2026 14:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR continues productionizing --move-tables mode by wiring the “skip ghost/changelog/heartbeat” behavior into the main migrator/applier flow, adding local docker-based move-tables helper scripts, and updating tests to reflect the new move-tables control paths.

Changes:

  • Add GetTargetDatabaseName() / GetTargetTableName() helpers and thread move-tables-aware naming/connection handling through migrator, inspector, and applier flows.
  • Disable changelog listener/heartbeat (and other ghost/changelog behaviors) in move-tables mode, and adjust row-copy to read from an explicit source DB when moving across clusters.
  • Add local script/move-tables/* and localtests/docker-compose-move-tables.yml scaffolding plus related tests.
Show a summary per file
File Description
go/logic/applier.go Move-tables target DB/table handling, changelog no-op, target-table creation, and row-copy API changes.
go/logic/migrator.go Integrates move-tables streaming/copy flow and gates throttling/heartbeat/changelog usage.
go/logic/inspect.go Makes “original table name” move-tables-aware and factors unique-key selection.
go/base/context.go Adds target DB/table helpers; derives move-tables connection config and applies TLS to it.
go/cmd/gh-ost/main.go Initializes move-tables connection config and reorders connection config setup.
go/logic/applier_test.go Adds/adjusts tests for move-tables skip behavior and new method signatures.
go/logic/migrator_test.go Updates tests to pass the new ReadMigrationRangeValues(nil) signature.
go/base/context_test.go Tests move-tables credential derivation and TLS application.
script/move-tables/* Adds local setup/teardown helpers and mysql client wrappers for move-tables topology.
localtests/docker-compose-move-tables.yml Adds a 2-cluster docker-compose topology for local move-tables runs.
localtests/move-tables/create.sql Seeds a sample table/data set for local move-tables testing.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comments suppressed due to low confidence (2)

go/logic/applier.go:180

  • InitDBConnections initializes moveTablesTargetDB twice: the two consecutive if apl.moveTablesConnectionConfig != nil { ... } blocks are identical. This duplicates DB creation/validation work and can leak extra connections if the first succeeds and the second fails later in the function.
	if apl.moveTablesConnectionConfig != nil {
		moveTablesURI := apl.moveTablesConnectionConfig.GetDBUri(apl.migrationContext.GetTargetDatabaseName()) + "&multiStatements=true"
		if apl.moveTablesTargetDB, _, err = mysql.GetDB(apl.migrationContext.Uuid, moveTablesURI); err != nil {
			return err
		}
		if _, err := base.ValidateConnection(apl.moveTablesTargetDB, apl.moveTablesConnectionConfig, apl.migrationContext, apl.name); err != nil {
			return err
		}
	}
	if apl.moveTablesConnectionConfig != nil {
		moveTablesURI := apl.moveTablesConnectionConfig.GetDBUri(apl.migrationContext.GetTargetDatabaseName()) + "&multiStatements=true"
		if apl.moveTablesTargetDB, _, err = mysql.GetDB(apl.migrationContext.Uuid, moveTablesURI); err != nil {
			return err
		}
		if _, err := base.ValidateConnection(apl.moveTablesTargetDB, apl.moveTablesConnectionConfig, apl.migrationContext, apl.name); err != nil {
			return err
		}
	}

go/logic/applier.go:206

  • AcquireMigrationLock connects using GetDBUri(migrationContext.DatabaseName). In move-tables mode, the applier connection points at the target cluster, and DatabaseName may not exist there when --target-database differs, causing lock acquisition to fail before the migration can run. Using GetTargetDatabaseName() here keeps the lock connection consistent with the applier DB selection.
func (apl *Applier) AcquireMigrationLock(ctx context.Context) error {
	lockName := buildMigrationLockName(apl.migrationContext.DatabaseName, apl.originalTableName())

	// Use a dedicated *sql.DB so the pinned connection does not consume a
	// slot in apl.db's small pool (mysql.MaxDBPoolConnections).
	lockURI := apl.connectionConfig.GetDBUri(apl.migrationContext.DatabaseName)
	lockDB, err := gosql.Open("mysql", lockURI)
	if err != nil {
  • Files reviewed: 17/17 changed files
  • Comments generated: 9

Comment thread go/logic/applier.go
Comment thread go/logic/migrator.go
Comment thread go/logic/applier.go
Comment thread script/move-tables/setup Outdated
Comment thread script/move-tables/teardown Outdated
Comment thread script/move-tables/README.md Outdated
Comment thread script/move-tables/README.md
Comment thread go/logic/applier.go Outdated
Comment thread script/move-tables/setup
zacharysierakowski and others added 5 commits June 11, 2026 14:34
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot's findings

Comments suppressed due to low confidence (1)

go/logic/applier.go:180

  • This initializes moveTablesTargetDB twice with the same URI, which can leak the first *sql.DB handle and does redundant connection validation. Remove the duplicated second if apl.moveTablesConnectionConfig != nil { ... } block (or consolidate into a single initialization path).
	if !apl.migrationContext.IsMoveTablesMode() {
		// read target table columns from applier
		if err := apl.readTableColumns(); err != nil {
			return err
		}
	}
	if apl.moveTablesConnectionConfig != nil {
		moveTablesURI := apl.moveTablesConnectionConfig.GetDBUri(apl.migrationContext.GetTargetDatabaseName()) + "&multiStatements=true"
		if apl.moveTablesTargetDB, _, err = mysql.GetDB(apl.migrationContext.Uuid, moveTablesURI); err != nil {
			return err
		}
		if _, err := base.ValidateConnection(apl.moveTablesTargetDB, apl.moveTablesConnectionConfig, apl.migrationContext, apl.name); err != nil {
			return err
		}
	}
	if apl.moveTablesConnectionConfig != nil {
		moveTablesURI := apl.moveTablesConnectionConfig.GetDBUri(apl.migrationContext.GetTargetDatabaseName()) + "&multiStatements=true"
		if apl.moveTablesTargetDB, _, err = mysql.GetDB(apl.migrationContext.Uuid, moveTablesURI); err != nil {
			return err
		}
		if _, err := base.ValidateConnection(apl.moveTablesTargetDB, apl.moveTablesConnectionConfig, apl.migrationContext, apl.name); err != nil {
			return err
		}
	}
  • Files reviewed: 17/17 changed files
  • Comments generated: 6

Comment thread script/move-tables/setup
Comment thread script/move-tables/teardown
Comment thread go/logic/applier.go
Comment thread go/logic/applier.go
Comment thread script/move-tables/mysql-source-primary
Comment thread script/move-tables/README.md
@zacharysierakowski zacharysierakowski merged commit b538d5b into feature-move-tables Jun 11, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature-move-tables PRs that are associated with the new move-tables feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants