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.
This commit is contained in:
Aaron Son
2023-12-15 12:49:09 -08:00
parent 3c0b84760a
commit 0fbfd0d80a
2 changed files with 92 additions and 1 deletions

View File

@@ -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)

View File

@@ -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"]