@@ -354,7 +354,7 @@ func (b *Backup) doPhysical(
354354 }
355355
356356 if b .typ == defs .ExternalBackup {
357- return b .handleExternal (ctx , bcp , rsMeta , data , jrnls , bcur .Meta .DBpath , opid , inf , l )
357+ return b .handleExternal (ctx , bcp , rsMeta , data , jrnls , bcur .Meta .DBpath , opid , inf , stg , l )
358358 }
359359
360360 return b .uploadPhysical (ctx , bcp , rsMeta , data , jrnls , bcur .Meta .DBpath , stg , l )
@@ -364,16 +364,18 @@ func (b *Backup) handleExternal(
364364 ctx context.Context ,
365365 bcp * ctrl.BackupCmd ,
366366 rsMeta * BackupReplset ,
367- data ,
367+ data [] File ,
368368 jrnls []File ,
369369 dbpath string ,
370370 opid ctrl.OPID ,
371371 inf * topo.NodeInfo ,
372+ stg storage.Storage ,
372373 l log.LogEvent ,
373374) error {
375+ filelist := make (Filelist , 0 , len (data )+ len (jrnls )+ 2 ) // +2 for metadata and filelist
374376 for _ , f := range append (data , jrnls ... ) {
375377 f .Name = path .Clean ("./" + strings .TrimPrefix (f .Name , dbpath ))
376- rsMeta . Files = append (rsMeta . Files , f )
378+ filelist = append (filelist , f )
377379 }
378380
379381 // We'll rewrite rs' LastWriteTS with the cluster LastWriteTS for the meta
@@ -389,19 +391,33 @@ func (b *Backup) handleExternal(
389391 }
390392 // save rs meta along with the data files so it can be used during the restore
391393 metaf := fmt .Sprintf (defs .ExternalRsMetaFile , fsMeta .Name )
392- fsMeta .Files = append (fsMeta .Files , File {
393- Name : metaf ,
394- })
394+ filelist = append (filelist , File {Name : metaf }, File {Name : FilelistName })
395395 metadst := filepath .Join (dbpath , metaf )
396396 err = writeRSmetaToDisk (metadst , & fsMeta )
397397 if err != nil {
398398 // we can restore without it
399399 l .Warning ("failed to save rs meta file <%s>: %v" , metadst , err )
400400 }
401401
402- err = RSSetPhyFiles (ctx , b .leadConn , bcp .Name , rsMeta .Name , rsMeta )
402+ filelistPath := filepath .Join (dbpath , FilelistName )
403+ err = saveFilelist (filelistPath , filelist )
403404 if err != nil {
404- return errors .Wrap (err , "set shard's files list" )
405+ return errors .Wrap (err , "save filelist to dbpath" )
406+ }
407+
408+ if bcp .Filelist {
409+ // keep filelist on backup storage for listing files to copy
410+ bcpStoragePath := path .Join (bcp .Name , rsMeta .Name , FilelistName )
411+ _ , err = storage .Upload (ctx , filelist , stg , compress .CompressionTypeNone , nil , bcpStoragePath , - 1 )
412+ if err != nil {
413+ return errors .Wrapf (err , "save filelist to storage: %q" , bcpStoragePath )
414+ }
415+
416+ defer func () {
417+ if err := stg .Delete (bcp .Name ); err != nil {
418+ l .Warning ("remove backup folder <%s>: %v" , bcp .Name , err )
419+ }
420+ }()
405421 }
406422
407423 err = b .toState (ctx , defs .StatusCopyReady , bcp .Name , opid .String (), inf , nil )
@@ -419,10 +435,28 @@ func (b *Backup) handleExternal(
419435 if err != nil {
420436 l .Warning ("remove rs meta file <%s>: %v" , metadst , err )
421437 }
438+ err = os .Remove (filelistPath )
439+ if err != nil {
440+ l .Warning ("remove file <%s>: %v" , filelistPath , err )
441+ }
422442
423443 return nil
424444}
425445
446+ func saveFilelist (filepath string , fl Filelist ) error {
447+ fw , err := os .OpenFile (filepath , os .O_WRONLY | os .O_CREATE | os .O_TRUNC , 0o600 )
448+ if err != nil {
449+ return errors .Wrapf (err , "create/open" )
450+ }
451+ defer fw .Close ()
452+
453+ if _ , err = fl .WriteTo (fw ); err != nil {
454+ return errors .Wrap (err , "write" )
455+ }
456+
457+ return errors .Wrap (fw .Sync (), "fsync" )
458+ }
459+
426460func writeRSmetaToDisk (fname string , rsMeta * BackupReplset ) error {
427461 fw , err := os .OpenFile (fname , os .O_WRONLY | os .O_CREATE | os .O_TRUNC , 0o600 )
428462 if err != nil {
@@ -454,35 +488,38 @@ func (b *Backup) uploadPhysical(
454488 stg storage.Storage ,
455489 l log.LogEvent ,
456490) error {
457- var err error
458491 l .Info ("uploading data" )
459- rsMeta . Files , err = uploadFiles (ctx , data , bcp .Name + "/" + rsMeta .Name , dbpath ,
492+ dataFiles , err : = uploadFiles (ctx , data , bcp .Name + "/" + rsMeta .Name , dbpath ,
460493 b .typ == defs .IncrementalBackup , stg , bcp .Compression , bcp .CompressionLevel , l )
461494 if err != nil {
462- return err
495+ return errors . Wrap ( err , "upload data files" )
463496 }
464497 l .Info ("uploading data done" )
465498
466499 l .Info ("uploading journals" )
467500 ju , err := uploadFiles (ctx , jrnls , bcp .Name + "/" + rsMeta .Name , dbpath ,
468501 false , stg , bcp .Compression , bcp .CompressionLevel , l )
469502 if err != nil {
470- return err
503+ return errors . Wrap ( err , "upload journal files" )
471504 }
472505 l .Info ("uploading journals done" )
473- rsMeta .Files = append (rsMeta .Files , ju ... )
474506
475- err = RSSetPhyFiles (ctx , b .leadConn , bcp .Name , rsMeta .Name , rsMeta )
476- if err != nil {
477- return errors .Wrap (err , "set shard's files list" )
478- }
507+ filelist := Filelist (dataFiles )
508+ filelist = append (filelist , ju ... )
479509
480510 size := int64 (0 )
481- for _ , f := range rsMeta . Files {
511+ for _ , f := range filelist {
482512 size += f .StgSize
483513 }
484514
485- err = IncBackupSize (ctx , b .leadConn , bcp .Name , size )
515+ filelistPath := path .Join (bcp .Name , rsMeta .Name , FilelistName )
516+ flSize , err := storage .Upload (ctx , filelist , stg , compress .CompressionTypeNone , nil , filelistPath , - 1 )
517+ if err != nil {
518+ return errors .Wrapf (err , "upload filelist %q" , filelistPath )
519+ }
520+ l .Info ("uploaded: %q %s" , filelistPath , fmtSize (flSize ))
521+
522+ err = IncBackupSize (ctx , b .leadConn , bcp .Name , size + flSize )
486523 if err != nil {
487524 return errors .Wrap (err , "inc backup size" )
488525 }
0 commit comments