Skip to content

Commit

Permalink
Add readonly tooling
Browse files Browse the repository at this point in the history
  • Loading branch information
DAlperin committed Apr 4, 2023
1 parent 909f45d commit 7475618
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
36 changes: 36 additions & 0 deletions pkg/commands/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,39 @@ func handleStolonDBUid(w http.ResponseWriter, r *http.Request) {

render.Err(w, errors.New("can't find db"))
}

func handleEnableReadonly(w http.ResponseWriter, r *http.Request) {
conn, close, err := localConnection(r.Context())
if err != nil {
render.Err(w, err)
return
}
defer close()

err = admin.SetReadonly(r.Context(), conn, true)
if err != nil {
render.Err(w, err)
}

resp := &Response{Result: true}

render.JSON(w, resp, http.StatusOK)
}

func handleDisableReadonly(w http.ResponseWriter, r *http.Request) {
conn, close, err := localConnection(r.Context())
if err != nil {
render.Err(w, err)
return
}
defer close()

err = admin.SetReadonly(r.Context(), conn, false)
if err != nil {
render.Err(w, err)
}

resp := &Response{Result: true}

render.JSON(w, resp, http.StatusOK)
}
2 changes: 2 additions & 0 deletions pkg/commands/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ func Handler() http.Handler {
r.Get("/restart", handleRestart)
r.Get("/settings/view", handleViewSettings)
r.Get("/replicationstats", handleReplicationStats)
r.Post("/readonly/enable", handleEnableReadonly)
r.Post("/readonly/disable", handleDisableReadonly)
r.Get("/dbuid", handleStolonDBUid)
r.Post("/settings/update", handleUpdateSettings)
})
Expand Down
30 changes: 30 additions & 0 deletions pkg/flypg/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"crypto/md5"
"fmt"
"github.com/pkg/errors"
"os"
"strings"

Expand Down Expand Up @@ -276,6 +277,35 @@ func ResolveReplicationLag(ctx context.Context, pg *pgx.Conn) ([]*ReplicationSta
return stats, nil
}

func SetReadonly(ctx context.Context, pg *pgx.Conn, enable bool) error {
role, err := ResolveRole(ctx, pg)
if err != nil {
return err
}
if role != "leader" {
return errors.New("can't set non primary to read-only")
}

databases, err := ListDatabases(ctx, pg)
if err != nil {
return err
}

for _, db := range databases {
// exclude administrative dbs
if db.Name == "postgres" {
continue
}

sql := fmt.Sprintf("ALTER DATABASE %s SET default_transaction_read_only=%v;", db.Name, enable)
if _, err = pg.Exec(ctx, sql); err != nil {
return fmt.Errorf("failed to alter readonly state on db %s: %s", db.Name, err)
}
}

return nil
}

func ResolveSettings(ctx context.Context, pg *pgx.Conn, list []string) (*flypg.Settings, error) {
node, err := flypg.NewNode()
if err != nil {
Expand Down

0 comments on commit 7475618

Please sign in to comment.