Skip to content

Commit

Permalink
Consider host read-only only on high min-replicas-to-write count
Browse files Browse the repository at this point in the history
  • Loading branch information
secwall committed Dec 17, 2024
1 parent 19d81a3 commit 7f50459
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 10 deletions.
2 changes: 1 addition & 1 deletion internal/app/repair.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (app *App) repairShard(shardState map[string]*HostState, activeNodes []stri
}

func (app *App) repairMaster(node *redis.Node, activeNodes []string, state *HostState) {
if state.IsReadOnly {
if state.IsReadOnly || state.MinReplicasToWrite != 0 {
err, rewriteErr := node.SetReadWrite(app.ctx)
if err != nil {
app.logger.Error("Unable to set master read-write", "fqdn", node.FQDN(), "error", err)
Expand Down
3 changes: 2 additions & 1 deletion internal/app/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,12 @@ func (app *App) getHostState(fqdn string) *HostState {
}
state.ReplicaState = &rs
}
state.IsReadOnly, err = node.IsReadOnly(app.ctx)
state.MinReplicasToWrite, err = node.GetMinReplicasToWrite(app.ctx)
if err != nil {
app.setStateError(&state, fqdn, err.Error())
return &state
}
state.IsReadOnly = node.IsReadOnly(state.MinReplicasToWrite)
state.IsOffline, err = node.IsOffline(app.ctx)
if err != nil {
app.setStateError(&state, fqdn, err.Error())
Expand Down
1 change: 1 addition & 0 deletions internal/app/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ type HostState struct {
SecondReplicationOffset int64 `json:"second_replication_offset"`
ReplicationBacklogStart int64 `json:"replication_backlog_start"`
ReplicationBacklogSize int64 `json:"replication_backlog_size"`
MinReplicasToWrite int64 `json:"min_replicas_to_write"`
ReplicationID string `json:"replication_id"`
ReplicationID2 string `json:"replication_id2"`
Error string `json:"error"`
Expand Down
21 changes: 13 additions & 8 deletions internal/redis/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,25 +366,30 @@ func (n *Node) SetAppendonly(ctx context.Context, value bool) error {
return n.configRewrite(ctx)
}

// IsReadOnly returns ReadOnly status for node
func (n *Node) IsReadOnly(ctx context.Context) (bool, error) {
// GetMinReplicasToWrite returns number of replicas required to write on node
func (n *Node) GetMinReplicasToWrite(ctx context.Context) (int64, error) {
cmd := client.NewStringSliceCmd(ctx, n.config.Renames.Config, "get", "min-replicas-to-write")
err := n.conn.Process(ctx, cmd)
if err != nil {
return false, err
return 0, err
}
vals, err := cmd.Result()
if err != nil {
return false, err
return 0, err
}
if len(vals) != 2 {
return false, fmt.Errorf("unexpected config get result for min-replicas-to-write: %v", vals)
return 0, fmt.Errorf("unexpected config get result for min-replicas-to-write: %v", vals)
}
ret, err := strconv.ParseInt(vals[1], 10, 32)
ret, err := strconv.ParseInt(vals[1], 10, 64)
if err != nil {
return false, fmt.Errorf("unable to parse min-replicas-to-write value: %s", err.Error())
return 0, fmt.Errorf("unable to parse min-replicas-to-write value: %s", err.Error())
}
return int(ret) > 0, nil
return ret, nil
}

// IsReadOnly returns ReadOnly status for node
func (n *Node) IsReadOnly(minReplicasToWrite int64) bool {
return minReplicasToWrite == highMinReplicas
}

// SetReadOnly makes node read-only by setting min replicas to unreasonably high value and disconnecting clients
Expand Down

0 comments on commit 7f50459

Please sign in to comment.