restore: add critical PostgreSQL restore flags per official documentation
Based on PostgreSQL documentation research (postgresql.org/docs/current/app-pgrestore.html): CRITICAL FIXES: - Add --exit-on-error: pg_restore continues on errors by default, masking failures - Add --no-data-for-failed-tables: prevents duplicate data in existing tables - Use template0 for CREATE DATABASE: avoids duplicate definition errors from template1 additions - Fix --jobs incompatibility: cannot use with --single-transaction per docs WHY THIS MATTERS: - Without --exit-on-error, pg_restore returns success even with failures - Without --no-data-for-failed-tables, restore fails on existing objects - template1 may have local additions causing 'duplicate definition' errors - --jobs with --single-transaction causes pg_restore to fail This should resolve the 'exit status 1' cluster restore failures.
This commit is contained in:
@@ -349,8 +349,8 @@ func (p *PostgreSQL) BuildRestoreCommand(database, inputFile string, options Res
|
||||
}
|
||||
cmd = append(cmd, "-U", p.cfg.User)
|
||||
|
||||
// Parallel jobs
|
||||
if options.Parallel > 1 {
|
||||
// Parallel jobs (incompatible with --single-transaction per PostgreSQL docs)
|
||||
if options.Parallel > 1 && !options.SingleTransaction {
|
||||
cmd = append(cmd, "--jobs="+strconv.Itoa(options.Parallel))
|
||||
}
|
||||
|
||||
@@ -371,6 +371,13 @@ func (p *PostgreSQL) BuildRestoreCommand(database, inputFile string, options Res
|
||||
cmd = append(cmd, "--single-transaction")
|
||||
}
|
||||
|
||||
// CRITICAL: Exit on first error (by default pg_restore continues on errors)
|
||||
// This ensures we catch failures immediately instead of at the end
|
||||
cmd = append(cmd, "--exit-on-error")
|
||||
|
||||
// Skip data restore if table creation fails (prevents duplicate data errors)
|
||||
cmd = append(cmd, "--no-data-for-failed-tables")
|
||||
|
||||
// Add verbose flag for better error reporting
|
||||
cmd = append(cmd, "--verbose")
|
||||
|
||||
|
||||
@@ -865,13 +865,15 @@ func (e *Engine) ensureDatabaseExists(ctx context.Context, dbName string) error
|
||||
}
|
||||
|
||||
// Database doesn't exist, create it
|
||||
e.log.Info("Creating database", "name", dbName)
|
||||
// IMPORTANT: Use template0 to avoid duplicate definition errors from local additions to template1
|
||||
// See PostgreSQL docs: https://www.postgresql.org/docs/current/app-pgrestore.html#APP-PGRESTORE-NOTES
|
||||
e.log.Info("Creating database from template0", "name", dbName)
|
||||
|
||||
createArgs := []string{
|
||||
"-p", fmt.Sprintf("%d", e.cfg.Port),
|
||||
"-U", e.cfg.User,
|
||||
"-d", "postgres",
|
||||
"-c", fmt.Sprintf("CREATE DATABASE \"%s\"", dbName),
|
||||
"-c", fmt.Sprintf("CREATE DATABASE \"%s\" WITH TEMPLATE template0", dbName),
|
||||
}
|
||||
|
||||
// Only add -h flag if host is not localhost (to use Unix socket for peer auth)
|
||||
@@ -891,7 +893,7 @@ func (e *Engine) ensureDatabaseExists(ctx context.Context, dbName string) error
|
||||
return fmt.Errorf("failed to create database '%s': %w (output: %s)", dbName, err, strings.TrimSpace(string(output)))
|
||||
}
|
||||
|
||||
e.log.Info("Successfully created database", "name", dbName)
|
||||
e.log.Info("Successfully created database from template0", "name", dbName)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user