From 0fbfd0d80a8bbe02abbee699c5693b72b990c75d Mon Sep 17 00:00:00 2001 From: Aaron Son Date: Fri, 15 Dec 2023 12:49:09 -0800 Subject: [PATCH] go: sqle: cluster: Create missing remotes for cluster replication on startup if they do not already exist. Previously `dolt sql-server` would error if there were existing databases and they were missing any of the remotes listed as cluster replication remotes in the config.yaml. This changes it so that those remotes are automatically created at startup instead. --- .../doltcore/sqle/cluster/controller.go | 7 +- .../tests/sql-server-cluster.yaml | 86 +++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/go/libraries/doltcore/sqle/cluster/controller.go b/go/libraries/doltcore/sqle/cluster/controller.go index f90a80998b..8b5d72f8a0 100644 --- a/go/libraries/doltcore/sqle/cluster/controller.go +++ b/go/libraries/doltcore/sqle/cluster/controller.go @@ -299,9 +299,14 @@ func (c *Controller) applyCommitHooks(ctx context.Context, name string, bt *sql. dialprovider := c.gRPCDialProvider(denv) var hooks []*commithook for _, r := range c.cfg.StandbyRemotes() { + remoteUrl := strings.Replace(r.RemoteURLTemplate(), dsess.URLTemplateDatabasePlaceholder, name, -1) remote, ok := remotes.Get(r.Name()) if !ok { - return nil, fmt.Errorf("sqle: cluster: standby replication: destination remote %s does not exist on database %s", r.Name(), name) + remote = env.NewRemote(r.Name(), remoteUrl, nil) + err := denv.AddRemote(remote) + if err != nil { + return nil, fmt.Errorf("sqle: cluster: standby replication: could not create remote %s for database %s: %v", r.Name(), name, err) + } } commitHook := newCommitHook(c.lgr, r.Name(), remote.Url, name, c.role, func(ctx context.Context) (*doltdb.DoltDB, error) { return remote.GetRemoteDB(ctx, types.Format_Default, dialprovider) diff --git a/integration-tests/go-sql-server-driver/tests/sql-server-cluster.yaml b/integration-tests/go-sql-server-driver/tests/sql-server-cluster.yaml index 5a696d7132..54bd4f1227 100644 --- a/integration-tests/go-sql-server-driver/tests/sql-server-cluster.yaml +++ b/integration-tests/go-sql-server-driver/tests/sql-server-cluster.yaml @@ -1736,3 +1736,89 @@ tests: - on: server1 queries: - exec: "call dolt_assume_cluster_role('primary', '3')" +# Assert that we can add a new standby to an existing server and bring the server up. +- name: adding new remotes to the config creates those remotes on startup + multi_repos: + - name: server1 + with_files: + - name: onestandby.yaml + contents: | + log_level: trace + listener: + host: 0.0.0.0 + port: 3309 + cluster: + standby_remotes: + - name: standby_one + remote_url_template: http://localhost:3852/{database} + bootstrap_role: primary + bootstrap_epoch: 1 + remotesapi: + port: 3851 + - name: twostandbys.yaml + contents: | + log_level: trace + listener: + host: 0.0.0.0 + port: 3309 + cluster: + standby_remotes: + - name: standby_one + remote_url_template: http://localhost:3852/{database} + - name: standby_two + remote_url_template: http://localhost:3853/{database} + bootstrap_role: primary + bootstrap_epoch: 1 + remotesapi: + port: 3851 + server: + args: ["--config", "onestandby.yaml"] + port: 3309 + - name: standby + with_files: + - name: config.yaml + contents: | + log_level: trace + listener: + host: 0.0.0.0 + port: 3310 + cluster: + standby_remotes: + - name: standby + remote_url_template: http://localhost:3851/{database} + bootstrap_role: standby + bootstrap_epoch: 1 + remotesapi: + port: 3853 + server: + args: ["--config", "config.yaml"] + port: 3310 + connections: + - on: server1 + queries: + - exec: "create database testdb" + - on: server1 + restart_server: + args: ["--config", "twostandbys.yaml"] + - on: server1 + queries: + - exec: "use testdb" + - query: "select count(*) from dolt_remotes" + result: + columns: ["count(*)"] + rows: + - ["2"] + - exec: 'SET @@GLOBAL.dolt_cluster_ack_writes_timeout_secs = 1' + - exec: "create table vals (id int primary key)" + - query: "show warnings" + result: + columns: ["Level", "Code", "Message"] + rows: + - ["Warning", "3024", "Timed out replication of commit to 1 out of 2 replicas."] + - on: standby + queries: + - query: "select count(*) from `testdb`.`vals`" + result: + columns: ["count(*)"] + rows: + - ["0"]