Skip to content

Commit

Permalink
Add the --dump-only option to only dump databases
Browse files Browse the repository at this point in the history
The new option --dump-only allows skipping dumps of configuration and
globals, including database ACL and configuration when pg_dump is older
than 11. More than one file can still be created, for example if
checksum are enabled. The corresponding configuration parameter is
dump_only, it is false by default.
  • Loading branch information
orgrim committed May 3, 2024
1 parent 358c8ba commit df166fa
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 29 deletions.
7 changes: 6 additions & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ type options struct {
CipherPrivateKey string
Decrypt bool
WithRolePasswords bool
DumpOnly bool

Upload string // values are none, s3, sftp, gcs
PurgeRemote bool
Expand Down Expand Up @@ -261,6 +262,7 @@ func parseCli(args []string) (options, []string, error) {
WithoutTemplates := pflag.Bool("without-templates", false, "force exclude templates")
pflag.BoolVar(&opts.WithRolePasswords, "with-role-passwords", true, "dump globals with role passwords")
WithoutRolePasswords := pflag.Bool("without-role-passwords", false, "do not dump passwords of roles")
pflag.BoolVar(&opts.DumpOnly, "dump-only", false, "only dump databases, excluding configuration and globals")
pflag.IntVarP(&opts.PauseTimeout, "pause-timeout", "T", 3600, "abort if replication cannot be paused after this number\nof seconds")
pflag.IntVarP(&opts.Jobs, "jobs", "j", 1, "dump this many databases concurrently")
pflag.StringVarP(&format, "format", "F", "custom", "database dump format: plain, custom, tar or directory")
Expand Down Expand Up @@ -484,7 +486,7 @@ func validateConfigurationFile(cfg *ini.File) error {
"sftp_port", "sftp_user", "sftp_password", "sftp_directory", "sftp_identity",
"sftp_ignore_hostkey", "gcs_bucket", "gcs_endpoint", "gcs_keyfile",
"azure_container", "azure_account", "azure_key", "azure_endpoint", "pg_dump_options",
"dump_role_passwords",
"dump_role_passwords", "dump_only",
}

gkLoop:
Expand Down Expand Up @@ -561,6 +563,7 @@ func loadConfigurationFile(path string) (options, error) {
opts.Dbnames = s.Key("include_dbs").Strings(",")
opts.WithTemplates = s.Key("with_templates").MustBool(false)
opts.WithRolePasswords = s.Key("dump_role_passwords").MustBool(true)
opts.DumpOnly = s.Key("dump_only").MustBool(false)
format = s.Key("format").MustString("custom")
opts.DirJobs = s.Key("parallel_backup_jobs").MustInt(1)
opts.CompressLevel = s.Key("compress_level").MustInt(-1)
Expand Down Expand Up @@ -758,6 +761,8 @@ func mergeCliAndConfigOptions(cliOpts options, configOpts options, onCli []strin
opts.WithTemplates = cliOpts.WithTemplates
case "with-role-passwords":
opts.WithRolePasswords = cliOpts.WithRolePasswords
case "dump-only":
opts.DumpOnly = cliOpts.DumpOnly
case "pause-timeout":
opts.PauseTimeout = cliOpts.PauseTimeout
case "jobs":
Expand Down
68 changes: 40 additions & 28 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func run() (retVal error) {
var cliOptions options

if cliOpts.NoConfigFile {
l.Infoln("*** Skipping reading config file")
l.Infoln("Skipping reading config file")
cliOptions = defaultOptions()
} else {
// Load configuration file and allow the default configuration
Expand Down Expand Up @@ -277,38 +277,40 @@ func run() (retVal error) {
}
defer db.Close()

if !db.superuser {
l.Infoln("connection user is not superuser, some information will not be dumped")
}
if !opts.DumpOnly {
if !db.superuser {
l.Infoln("connection user is not superuser, some information will not be dumped")
}

// Then we can implicitely avoid dumping role password when using a
// regular user
dumpRolePasswords := opts.WithRolePasswords && db.superuser
if dumpRolePasswords {
l.Infoln("dumping globals")
} else {
l.Infoln("dumping globals without role passwords")
}
if err := dumpGlobals(opts.Directory, opts.TimeFormat, dumpRolePasswords, conninfo, producedFiles); err != nil {
return fmt.Errorf("pg_dumpall of globals failed: %w", err)
}
// Then we can implicitely avoid dumping role password when using a
// regular user
dumpRolePasswords := opts.WithRolePasswords && db.superuser
if dumpRolePasswords {
l.Infoln("dumping globals")
} else {
l.Infoln("dumping globals without role passwords")
}
if err := dumpGlobals(opts.Directory, opts.TimeFormat, dumpRolePasswords, conninfo, producedFiles); err != nil {
return fmt.Errorf("pg_dumpall of globals failed: %w", err)
}

l.Infoln("dumping instance configuration")
var (
verr *pgVersionError
perr *pgPrivError
)
l.Infoln("dumping instance configuration")
var (
verr *pgVersionError
perr *pgPrivError
)

if err := dumpSettings(opts.Directory, opts.TimeFormat, db, producedFiles); err != nil {
if errors.As(err, &verr) || errors.As(err, &perr) {
l.Warnln(err)
} else {
return fmt.Errorf("could not dump configuration parameters: %w", err)
if err := dumpSettings(opts.Directory, opts.TimeFormat, db, producedFiles); err != nil {
if errors.As(err, &verr) || errors.As(err, &perr) {
l.Warnln(err)
} else {
return fmt.Errorf("could not dump configuration parameters: %w", err)
}
}
}

if err := dumpConfigFiles(opts.Directory, opts.TimeFormat, db, producedFiles); err != nil {
return fmt.Errorf("could not dump configuration files: %w", err)
if err := dumpConfigFiles(opts.Directory, opts.TimeFormat, db, producedFiles); err != nil {
return fmt.Errorf("could not dump configuration files: %w", err)
}
}

databases, err := listDatabases(db, opts.WithTemplates, opts.ExcludeDbs, opts.Dbnames)
Expand Down Expand Up @@ -367,6 +369,15 @@ func run() (retVal error) {

canDumpACL := true
canDumpConfig := true

// When asked to only dump database, exclude ACL and config even if
// this can lead of missing info on restore when pg_dump is older than
// 11
if opts.DumpOnly {
canDumpACL = false
canDumpConfig = false
}

// collect the result of the jobs
for j := 0; j < numJobs; j++ {
var b, c string
Expand Down Expand Up @@ -407,6 +418,7 @@ func run() (retVal error) {
l.Verboseln("dumping configuration of", dbname)
c, err = dumpDBConfig(db, dbname)
if err != nil {
var verr *pgVersionError
if !errors.As(err, &verr) {
l.Errorln(err)
exitCode = 1
Expand Down
3 changes: 3 additions & 0 deletions pg_back.conf
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ exclude_dbs =
# include_dbs is empty.
with_templates = false

# Dump only databases, excluding configuration and globals
dump_only = false

# Format of the dump, understood by pg_dump. Possible values are
# plain, custom, tar or directory.
format = custom
Expand Down

0 comments on commit df166fa

Please sign in to comment.