3636import java .util .concurrent .Executors ;
3737import java .util .concurrent .ScheduledExecutorService ;
3838import java .util .concurrent .TimeUnit ;
39+ import java .util .concurrent .atomic .AtomicBoolean ;
3940
4041import static java .util .Collections .emptyList ;
4142import static java .util .Collections .emptyMap ;
@@ -398,25 +399,21 @@ public Map<FileInfo, Boolean> gc()
398399
399400 private Map <FileInfo , Boolean > executeGC () throws Exception
400401 {
401- logger .info ("Run storage gc." );
402+ logger .info ("Run storage gc... " );
402403 Map <FileInfo , Boolean > gcResults = new HashMap <>();
403404 while ( true )
404405 {
405406 int batchSize = config .getGCBatchSize ();
406407 List <Reclaim > reclaims = pathDB .listOrphanedFiles ( batchSize );
407408
408409 int size = reclaims .size ();
409- logger .info ( "Get reclaims for GC , size: {}" , size );
410+ logger .info ( "Get reclaims for gc , size: {}" , size );
410411 if ( size <= 0 )
411412 {
412- logger .info ("gc complete." );
413- break ;
414- }
415- else if ( batchSize > 0 && size < batchSize )
416- {
417- logger .info ( "Reclaims size less than batch size {}. Break current gc." , batchSize );
413+ logger .info ("Gc complete." );
418414 break ;
419415 }
416+ final AtomicBoolean physicalStoreError = new AtomicBoolean ( false );
420417 reclaims .forEach ( reclaim -> {
421418 FileInfo fileInfo = new FileInfo ();
422419 fileInfo .setFileId ( reclaim .getFileId () );
@@ -430,13 +427,20 @@ else if ( batchSize > 0 && size < batchSize )
430427 else
431428 {
432429 logger .warn ( "Delete from physical store failed, fileInfo: {}, reclaim: {}" , fileInfo , reclaim );
430+ physicalStoreError .set ( true );
433431 }
434432 gcResults .put (fileInfo , result );
435433 });
434+ if ( physicalStoreError .get () )
435+ {
436+ // Break to avoid infinite loop. The listOrphanedFiles may fetch duplicated entries in this case.
437+ logger .info ("Gc hit physical store error. Break current gc. gcResults: {}" , gcResults );
438+ break ;
439+ }
436440 int curSize = gcResults .size ();
437441 if ( curSize >= config .getGcMaxResultSize () )
438442 {
439- logger .info ("gc reach the max result size and complete, curSize: {}" , curSize );
443+ logger .info ("Gc reach the max result size and complete, curSize: {}" , curSize );
440444 break ;
441445 }
442446 }
0 commit comments