Skip to content

Add 'dbdeployer deploy proxysql' and --with-proxysql for replication#46

Merged
renecannao merged 2 commits intomasterfrom
phase2b/task4-5-deploy-proxysql
Mar 24, 2026
Merged

Add 'dbdeployer deploy proxysql' and --with-proxysql for replication#46
renecannao merged 2 commits intomasterfrom
phase2b/task4-5-deploy-proxysql

Conversation

@renecannao
Copy link
Copy Markdown

Summary

  • Add new dbdeployer deploy proxysql subcommand for standalone ProxySQL sandbox deployment with --port, --admin-user, --admin-password, and --skip-start flags
  • Add --with-proxysql flag to dbdeployer deploy replication that automatically deploys a topology-aware ProxySQL instance alongside MySQL replication, with master in hostgroup 0 and slaves in hostgroup 1
  • Add sandbox.DeployProxySQLForTopology() helper that creates a ProxySQL sandbox configured with backend servers from an existing MySQL topology

Closes #39
Closes #40

Test plan

  • go build succeeds
  • go vet ./... passes
  • dbdeployer deploy --help shows proxysql subcommand
  • dbdeployer deploy proxysql --help shows correct flags and defaults
  • dbdeployer deploy replication --help shows --with-proxysql flag
  • dbdeployer deploy proxysql fails with clear "proxysql binary not found" message when proxysql is not installed

Copilot AI review requested due to automatic review settings March 24, 2026 01:45
@gemini-code-assist
Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 24, 2026

Warning

Rate limit exceeded

@renecannao has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 58 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 79f68dee-1bee-4939-822d-2141fb3b2ea9

📥 Commits

Reviewing files that changed from the base of the PR and between 1f8cbb1 and a87a2b6.

📒 Files selected for processing (3)
  • cmd/deploy_proxysql.go
  • cmd/replication.go
  • sandbox/proxysql_topology.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch phase2b/task4-5-deploy-proxysql

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@renecannao renecannao merged commit 5402472 into master Mar 24, 2026
6 of 17 checks passed
@renecannao renecannao deleted the phase2b/task4-5-deploy-proxysql branch March 24, 2026 01:45
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 24, 2026

Warning

Rate limit exceeded

@renecannao has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 58 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 79f68dee-1bee-4939-822d-2141fb3b2ea9

📥 Commits

Reviewing files that changed from the base of the PR and between 1f8cbb1 and a87a2b6.

📒 Files selected for processing (3)
  • cmd/deploy_proxysql.go
  • cmd/replication.go
  • sandbox/proxysql_topology.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch phase2b/task4-5-deploy-proxysql

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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds first-class ProxySQL deployment support to DBDeployer, including a standalone deploy proxysql command and an option to deploy a topology-aware ProxySQL sidecar with replication sandboxes.

Changes:

  • Introduces dbdeployer deploy proxysql with flags for admin port, admin credentials, and skipping start.
  • Adds --with-proxysql to dbdeployer deploy replication to deploy ProxySQL alongside a replication sandbox.
  • Adds sandbox.DeployProxySQLForTopology() helper to create/configure/start a ProxySQL sandbox from an existing MySQL topology.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 11 comments.

File Description
sandbox/proxysql_topology.go New helper to deploy ProxySQL configured with master/slave hostgroups based on topology ports.
cmd/replication.go Adds --with-proxysql flag and post-deploy logic to deploy ProxySQL for the created replication sandbox.
cmd/deploy_proxysql.go New deploy proxysql subcommand to deploy a standalone ProxySQL sandbox using the provider.

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

Comment thread cmd/deploy_proxysql.go
}

if _, err := p.FindBinary(""); err != nil {
common.Exitf(1, "proxysql binary not found in PATH: %s", err)
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

The error from p.FindBinary already includes "proxysql binary not found in PATH". Wrapping it with the same phrase here results in a duplicated message ("... in PATH: proxysql binary not found in PATH: ..."). Consider using a shorter wrapper like "proxysql binary not found" or just printing err directly.

Suggested change
common.Exitf(1, "proxysql binary not found in PATH: %s", err)
common.Exitf(1, "%s", err)

Copilot uses AI. Check for mistakes.
Comment thread cmd/deploy_proxysql.go
Comment on lines +29 to +33
flags := cmd.Flags()
port, _ := flags.GetInt("port")
adminUser, _ := flags.GetString("admin-user")
adminPassword, _ := flags.GetString("admin-password")
skipStart, _ := flags.GetBool("skip-start")
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

This command always uses the requested/default admin port (6032) without checking for conflicts or reserving the required 2-port range (admin + mysql interface). Consider using common.GetInstalledPorts + common.FindFreePort (howMany=2), at least when the user did not explicitly set --port.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +3
package sandbox

import (
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

New sandbox file is missing the standard DBDeployer Apache 2.0 license header comment block that is present at the top of other files in this package (e.g. sandbox/sandbox.go). Please add the header for consistency and licensing clarity.

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +39
proxysqlPort = 6032
// Try to find a free port
freePort, err := common.FindFreePort(proxysqlPort, []int{}, 1)
if err == nil {
proxysqlPort = freePort
}
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

When proxysqlPort==0, this calls common.FindFreePort with an empty installedPorts list and ignores the returned error. This effectively always selects 6032 even if it conflicts with existing sandboxes, and can silently fall back to a busy port. Use the actual installed ports (e.g. from common.GetInstalledPorts on the sandbox home) and return an error if a free port cannot be found.

Suggested change
proxysqlPort = 6032
// Try to find a free port
freePort, err := common.FindFreePort(proxysqlPort, []int{}, 1)
if err == nil {
proxysqlPort = freePort
}
// Determine currently used ports from the sandbox home (parent of sandboxDir)
sandboxHome := path.Dir(sandboxDir)
installedPorts, err := common.GetInstalledPorts(sandboxHome)
if err != nil {
return fmt.Errorf("cannot determine installed ports in %s: %w", sandboxHome, err)
}
proxysqlPort = 6032
// Try to find a free port starting from the default ProxySQL admin port
freePort, err := common.FindFreePort(proxysqlPort, installedPorts, 1)
if err != nil {
return fmt.Errorf("no free port available for ProxySQL starting at %d: %w", proxysqlPort, err)
}
proxysqlPort = freePort

Copilot uses AI. Check for mistakes.
Comment on lines +69 to +72
// Start ProxySQL
if err := p.StartSandbox(proxysqlDir); err != nil {
return fmt.Errorf("starting ProxySQL: %w", err)
}
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

This helper always starts ProxySQL after creating the sandbox. When used from replication deployment, it should respect the user's --skip-start choice (i.e., avoid starting ProxySQL when the replication sandbox was deployed with SkipStart), or accept a skipStart parameter.

Copilot uses AI. Check for mistakes.
Comment thread cmd/replication.go
Comment on lines +112 to +119
// Determine the sandbox directory that was created
sandboxDir := path.Join(sd.SandboxDir, defaults.Defaults().MasterSlavePrefix+common.VersionToName(origin))
if sd.DirName != "" {
sandboxDir = path.Join(sd.SandboxDir, sd.DirName)
}

// Read port info from child sandbox descriptions
masterDesc, err := common.ReadSandboxDescription(path.Join(sandboxDir, defaults.Defaults().MasterName))
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

The ProxySQL sidecar logic assumes a master/slave replication layout (master directory name + node%d slaves) and constructs sandboxDir using MasterSlavePrefix regardless of the selected --topology. For non-master-slave topologies (group, fan-in, all-masters, pxc, ndb) this path/layout will be wrong and the subsequent ReadSandboxDescription calls will fail. Either restrict --with-proxysql to globals.MasterSlaveLabel, or compute the sandbox directory/layout based on the chosen topology (mirroring sandbox.CreateReplicationSandbox’s topology switch).

Copilot uses AI. Check for mistakes.
Comment thread cmd/replication.go
slavePorts = append(slavePorts, nodeDesc.Port[0])
}

err = sandbox.DeployProxySQLForTopology(sandboxDir, masterPort, slavePorts, 0, "127.0.0.1")
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

ProxySQL is deployed with host hardcoded to "127.0.0.1". If the replication sandboxes were created with a different bind address (via the global --bind-address flag), ProxySQL may not be able to reach the backends. Prefer using the Host from the sandbox descriptions (masterDesc.Host) or the bind-address value used during deployment.

Copilot uses AI. Check for mistakes.
Comment thread cmd/replication.go
Comment on lines +135 to +138
err = sandbox.DeployProxySQLForTopology(sandboxDir, masterPort, slavePorts, 0, "127.0.0.1")
if err != nil {
common.Exitf(1, "ProxySQL deployment failed: %s", err)
}
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

If the user deployed replication with --skip-start (sd.SkipStart), this currently still deploys and starts ProxySQL. That creates a sidecar pointing at backends that are not running and diverges from the expected semantics of skip-start. Consider skipping ProxySQL start/deployment when skip-start is set, or propagating skip-start down to the helper.

Copilot uses AI. Check for mistakes.
Comment thread cmd/deploy_proxysql.go
Comment on lines +30 to +35
port, _ := flags.GetInt("port")
adminUser, _ := flags.GetString("admin-user")
adminPassword, _ := flags.GetString("admin-password")
skipStart, _ := flags.GetBool("skip-start")

p, err := providers.DefaultRegistry.Get("proxysql")
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

--port can be set to 0/negative, which will produce an invalid config (ProxySQL provider will end up with adminPort=0 and mysqlPort=1). Validate that port is >0 (or explicitly support port=0 as "auto" and implement free-port selection) before continuing.

Copilot uses AI. Check for mistakes.
Comment on lines +35 to +36
// Try to find a free port
freePort, err := common.FindFreePort(proxysqlPort, []int{}, 1)
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

ProxySQL uses two consecutive ports (adminPort and adminPort+1 for the MySQL interface). The auto-port selection requests only 1 port, so it may choose an admin port whose +1 is already in use, causing start failures. The free-port search should reserve/check a range of 2 ports.

Suggested change
// Try to find a free port
freePort, err := common.FindFreePort(proxysqlPort, []int{}, 1)
// Try to find a free range of two consecutive ports (admin and MySQL interface)
freePort, err := common.FindFreePort(proxysqlPort, []int{}, 2)

Copilot uses AI. Check for mistakes.
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.

Add --with-proxysql flag to replication deployment Add 'dbdeployer deploy proxysql' command

2 participants