D22: every restore puts the data back exactly on failure and after a power cut (R-1177, R-1195); whole restore asks the unit first (R-1178); no mirror during a restore (R-1180); W22 restore refusals in Hungarian; unreleased
gates / gates (push) Successful in 1m40s

This commit is contained in:
2026-10-21 21:19:46 +02:00
parent 7848d4aaac
commit d582feb245
25 changed files with 1065 additions and 71 deletions
+20 -3
View File
@@ -304,6 +304,13 @@ func (m *Manager) RestoreTier2Whole(stackName string) (WholeRestoreResult, error
m.logger.Printf("[WARN] [backup] whole restore REFUSED for %s: the file half needs %d B and %d B is free (floor %d B) — nothing moved", stackName, need, free, wholeRestoreFloorBytes)
return res, &wholeRestoreSpace{need: need, free: free}
}
// R-1178: the unit half's refusals are asked HERE, before the file half — measured before: files merged, then the
// unit refused (a cut-off database copy) and the app was left STOPPED under a page that said „untouched".
unitDir := tier2UnitDir(destBase)
if _, err := m.RestoreFromRecoveryUnitAtWith(stackName, unitDir, UnitRestoreOptions{AcceptMissingFiles: true, CheckOnly: true}); err != nil {
m.logger.Printf("[WARN] [backup] whole restore REFUSED for %s before the file half: the unit half would refuse (%v) — nothing moved", stackName, err)
return res, err
}
// THE FILE HALF, under the backup single-flight, with the app stopped.
if err := m.acquireRunning(); err != nil {
@@ -341,9 +348,19 @@ func (m *Manager) RestoreTier2Whole(stackName string) (WholeRestoreResult, error
return res, util.MsgError("err.backup.fajlmasolas_sikertelen", mergeErr)
}
// THE UNIT HALF — the existing restore, told that the files are handled (R-538 stays for every other caller).
unitDir := tier2UnitDir(destBase)
res.Unit, err = m.RestoreFromRecoveryUnitAtWith(stackName, unitDir, UnitRestoreOptions{AcceptMissingFiles: true})
// THE UNIT HALF — the existing restore, told that the files are handled (R-538 stays for every other caller) and
// how many it placed (a put-back then says those files stay, D22).
placed := res.Files.Restored + res.Files.Replaced
res.Unit, err = m.RestoreFromRecoveryUnitAtWith(stackName, unitDir, UnitRestoreOptions{AcceptMissingFiles: true, FilesPlaced: placed})
if err != nil && !res.Unit.Stopped {
// R-1178: the unit refused before touching anything (asked above, so only a change in between gets here) —
// but the file half HAS changed files and stopped the app. Start it, and say what changed.
m.logger.Printf("[ERROR] [backup] whole restore %s: the unit half refused after the file half (%v) — starting the app; %d file(s) restored, %d replaced", stackName, err, res.Files.Restored, res.Files.Replaced)
if startErr := m.stackProvider.StartStack(stackName); startErr != nil {
m.logger.Printf("[ERROR] [backup] restarting %s after the unit half refused also failed: %v", stackName, startErr)
}
err = util.MsgError("err.backup.whole_restore_unit_refused_files_changed", stackName, res.Files.Restored, res.Files.Replaced)
}
m.rehydratePrimaryUnit(stackName, unitDir, err)
return res, err
}