mirror of https://github.com/restic/restic.git
Merge pull request #1589 from restic/fix-intermediate-index-upload
archiver: Fix intermediate index upload
This commit is contained in:
commit
e706f1a8d1
|
@ -0,0 +1,17 @@
|
|||
Bugfix: Complete intermediate index upload
|
||||
|
||||
After a user posted a comprehensive report of what he observed, we were able to
|
||||
find a bug and correct it: During backup, restic uploads so-called
|
||||
"intermediate" index files. When the backup finishes during a transfer of such
|
||||
an intermediate index, the upload is cancelled, but the backup is finished
|
||||
without an error. This leads to an inconsistent state, where the snapshot
|
||||
references data that is contained in the repo, but is not referenced in any
|
||||
index.
|
||||
|
||||
The situation can be resolved by building a new index with `rebuild-index`, but
|
||||
looks very confusing at first. Since all the data got uploaded to the repo
|
||||
successfully, there was no risk of data loss, just minor inconvenience for our
|
||||
users.
|
||||
|
||||
https://github.com/restic/restic/pull/1589
|
||||
https://forum.restic.net/t/error-loading-tree-check-prune-and-forget-gives-error-b2-backend/406
|
|
@ -620,7 +620,7 @@ func (j archiveJob) Copy() pipe.Job {
|
|||
const saveIndexTime = 30 * time.Second
|
||||
|
||||
// saveIndexes regularly queries the master index for full indexes and saves them.
|
||||
func (arch *Archiver) saveIndexes(ctx context.Context, wg *sync.WaitGroup) {
|
||||
func (arch *Archiver) saveIndexes(saveCtx, shutdownCtx context.Context, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
ticker := time.NewTicker(saveIndexTime)
|
||||
|
@ -628,11 +628,13 @@ func (arch *Archiver) saveIndexes(ctx context.Context, wg *sync.WaitGroup) {
|
|||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-saveCtx.Done():
|
||||
return
|
||||
case <-shutdownCtx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
debug.Log("saving full indexes")
|
||||
err := arch.repo.SaveFullIndex(ctx)
|
||||
err := arch.repo.SaveFullIndex(saveCtx)
|
||||
if err != nil {
|
||||
debug.Log("save indexes returned an error: %v", err)
|
||||
fmt.Fprintf(os.Stderr, "error saving preliminary index: %v\n", err)
|
||||
|
@ -748,16 +750,16 @@ func (arch *Archiver) Snapshot(ctx context.Context, p *restic.Progress, paths, t
|
|||
|
||||
// run index saver
|
||||
var wgIndexSaver sync.WaitGroup
|
||||
indexCtx, indexCancel := context.WithCancel(ctx)
|
||||
shutdownCtx, indexShutdown := context.WithCancel(ctx)
|
||||
wgIndexSaver.Add(1)
|
||||
go arch.saveIndexes(indexCtx, &wgIndexSaver)
|
||||
go arch.saveIndexes(ctx, shutdownCtx, &wgIndexSaver)
|
||||
|
||||
// wait for all workers to terminate
|
||||
debug.Log("wait for workers")
|
||||
wg.Wait()
|
||||
|
||||
// stop index saver
|
||||
indexCancel()
|
||||
indexShutdown()
|
||||
wgIndexSaver.Wait()
|
||||
|
||||
debug.Log("workers terminated")
|
||||
|
|
Loading…
Reference in New Issue