CRITICAL FIX: Remove --single-transaction and --exit-on-error from pg_restore
- Disabled --single-transaction to prevent lock table exhaustion with large objects - Removed --exit-on-error to allow PostgreSQL to skip ignorable errors - Fixes 'could not open large object' errors (lock exhaustion with 35K+ BLOBs) - Fixes 'already exists' errors causing complete restore failure - Each object now restored in its own transaction (locks released incrementally) - PostgreSQL default behavior (continue on ignorable errors) is correct Per PostgreSQL docs: --single-transaction incompatible with large object restores and causes ALL locks to be held until commit, exhausting lock table with 1000+ objects
This commit is contained in:
@@ -371,9 +371,9 @@ 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")
|
||||
// NOTE: --exit-on-error removed because it causes entire restore to fail on
|
||||
// "already exists" errors. PostgreSQL continues on ignorable errors by default
|
||||
// and reports error count at the end, which is correct behavior for restores.
|
||||
|
||||
// Skip data restore if table creation fails (prevents duplicate data errors)
|
||||
cmd = append(cmd, "--no-data-for-failed-tables")
|
||||
|
||||
@@ -183,8 +183,8 @@ func (e *Engine) restorePostgreSQLDump(ctx context.Context, archivePath, targetD
|
||||
Clean: cleanFirst,
|
||||
NoOwner: true,
|
||||
NoPrivileges: true,
|
||||
SingleTransaction: true,
|
||||
Verbose: true, // Enable verbose for single database restores (not cluster)
|
||||
SingleTransaction: false, // CRITICAL: Disabled to prevent lock exhaustion with large objects
|
||||
Verbose: true, // Enable verbose for single database restores (not cluster)
|
||||
}
|
||||
|
||||
cmd := e.db.BuildRestoreCommand(targetDB, archivePath, opts)
|
||||
@@ -205,7 +205,7 @@ func (e *Engine) restorePostgreSQLDumpWithOwnership(ctx context.Context, archive
|
||||
Clean: false, // We already dropped the database
|
||||
NoOwner: !preserveOwnership, // Preserve ownership if we're superuser
|
||||
NoPrivileges: !preserveOwnership, // Preserve privileges if we're superuser
|
||||
SingleTransaction: true,
|
||||
SingleTransaction: false, // CRITICAL: Disabled to prevent lock exhaustion with large objects
|
||||
Verbose: false, // CRITICAL: disable verbose to prevent OOM on large restores
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user