mirror of
https://github.com/cloudnative-pg/plugin-barman-cloud.git
synced 2026-07-07 02:02:21 +02:00
fix(walrestore): use timeline-aware barman-cloud end-of-WAL markers
Update `wal-restore` to use the new `barman-cloud` restorer APIs, resolving a bug that can cause replicas to enter a broken state that CNPG cant recover from. Local marker naming, WAL timeline parsing, and restore-result filtering policy lives in `github.com/cloudnative-pg/barman-cloud/pkg/restorer`. depends on https://github.com/cloudnative-pg/barman-cloud/pull/277 Signed-off-by: Jeremy Schneider <schneider@ardentperf.com>
This commit is contained in:
parent
3cc6a882c8
commit
f25415eeb4
@ -21,7 +21,6 @@ package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
@ -331,9 +330,14 @@ func (w WALServiceImplementation) restoreFromBarmanObjectStore(
|
||||
return nil
|
||||
}
|
||||
|
||||
// Step 2: return error if the end-of-wal-stream flag is set.
|
||||
// PostgreSQL treats a restore_command failure as "WAL not available from
|
||||
// archive" and can then try streaming via primary_conninfo. When prefetch has
|
||||
// already observed archive exhaustion for this timeline, return one failure to
|
||||
// let PostgreSQL switch sources instead of repeatedly probing the archive.
|
||||
// We skip this step if streaming connection is not available
|
||||
if isStreamingAvailable(cluster, w.InstanceName) {
|
||||
if err := checkEndOfWALStreamFlag(walRestorer); err != nil {
|
||||
if err := checkEndOfWALStreamFlag(walRestorer, walName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -366,15 +370,15 @@ func (w WALServiceImplementation) restoreFromBarmanObjectStore(
|
||||
}
|
||||
|
||||
// We skip this step if streaming connection is not available
|
||||
endOfWALStream := isEndOfWALStream(walStatus)
|
||||
if isStreamingAvailable(cluster, w.InstanceName) && endOfWALStream {
|
||||
contextLogger.Info(
|
||||
"Set end-of-wal-stream flag as one of the WAL files to be prefetched was not found")
|
||||
|
||||
err = walRestorer.SetEndOfWALStream()
|
||||
if isStreamingAvailable(cluster, w.InstanceName) {
|
||||
endOfWALStream, err := walRestorer.SetEndOfWALStreamFromResults(walStatus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if endOfWALStream {
|
||||
contextLogger.Info(
|
||||
"Set end-of-wal-stream flag as one of the WAL files to be prefetched was not found")
|
||||
}
|
||||
}
|
||||
|
||||
successfulWalRestore := 0
|
||||
@ -473,32 +477,14 @@ func gatherWALFilesToRestore(walName string, parallel int) (walList []string, er
|
||||
return walList, err
|
||||
}
|
||||
|
||||
// checkEndOfWALStreamFlag returns ErrEndOfWALStreamReached if the flag is set in the restorer.
|
||||
func checkEndOfWALStreamFlag(walRestorer *barmanRestorer.WALRestorer) error {
|
||||
contain, err := walRestorer.IsEndOfWALStream()
|
||||
// checkEndOfWALStreamFlag returns ErrEndOfWALStreamReached if the flag is set for the requested WAL timeline.
|
||||
func checkEndOfWALStreamFlag(walRestorer *barmanRestorer.WALRestorer, walName string) error {
|
||||
contains, err := walRestorer.ConsumeEndOfWALStreamForWAL(walName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if contain {
|
||||
err := walRestorer.ResetEndOfWalStream()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if contains {
|
||||
return ErrEndOfWALStreamReached
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// isEndOfWALStream returns true if one of the downloads has returned
|
||||
// a file-not-found error.
|
||||
func isEndOfWALStream(results []barmanRestorer.Result) bool {
|
||||
for _, result := range results {
|
||||
if errors.Is(result.Err, barmanRestorer.ErrWALNotFound) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user