@@ -353,6 +353,10 @@ ptrackCheckpoint(void)
353
353
struct stat stat_buf ;
354
354
uint64 i = 0 ;
355
355
uint64 j = 0 ;
356
+ XLogRecPtr new_init_lsn ;
357
+ uint32 new_init_lsn32 ;
358
+ uint32 latest_lsn ;
359
+ bool lsn_was_advanced = false;
356
360
357
361
elog (DEBUG1 , "ptrack checkpoint" );
358
362
@@ -408,21 +412,25 @@ ptrackCheckpoint(void)
408
412
ptrack_write_chunk (ptrack_tmp_fd , & crc , (char * ) ptrack_map ,
409
413
offsetof(PtrackMapHdr , init_lsn ));
410
414
415
+ latest_lsn = pg_atomic_read_u32 (& ptrack_map -> latest_lsn );
411
416
init_lsn = pg_atomic_read_u32 (& ptrack_map -> init_lsn );
412
417
413
418
/* Set init_lsn during checkpoint if it is not set yet */
414
419
if (init_lsn == InvalidXLogRecPtr )
415
420
{
416
- XLogRecPtr new_init_lsn ;
417
- uint32 new_init_lsn32 ;
418
-
419
421
if (RecoveryInProgress ())
420
422
new_init_lsn = GetXLogReplayRecPtr (NULL );
421
423
else
422
424
new_init_lsn = GetXLogInsertRecPtr ();
423
425
424
426
new_init_lsn32 = (uint32 )(new_init_lsn >> 16 );
425
-
427
+ pg_atomic_write_u32 (& ptrack_map -> init_lsn , new_init_lsn32 );
428
+ init_lsn = new_init_lsn32 ;
429
+ }
430
+ else if (lsn_diff (lsn_advance (init_lsn , PtrackLSNGap ), latest_lsn ) < 0 )
431
+ {
432
+ new_init_lsn32 = lsn_advance (init_lsn , PtrackLSNGap );
433
+ lsn_was_advanced = true;
426
434
pg_atomic_write_u32 (& ptrack_map -> init_lsn , new_init_lsn32 );
427
435
init_lsn = new_init_lsn32 ;
428
436
}
@@ -449,7 +457,11 @@ ptrackCheckpoint(void)
449
457
* TODO: is it safe and can we do any better?
450
458
*/
451
459
lsn = pg_atomic_read_u32 (& ptrack_map -> entries [i ]);
452
- buf [j ].value = lsn ;
460
+
461
+ if (lsn_was_advanced && lsn_diff (lsn , init_lsn ) < 0 )
462
+ buf [j ].value = InvalidXLogRecPtr ;
463
+ else
464
+ buf [j ].value = lsn ;
453
465
454
466
i ++ ;
455
467
j ++ ;
@@ -467,7 +479,6 @@ ptrackCheckpoint(void)
467
479
ptrack_write_chunk (ptrack_tmp_fd , & crc , (char * ) buf , writesz );
468
480
elog (DEBUG5 , "ptrack checkpoint: i " UINT64_FORMAT ", j " UINT64_FORMAT ", writesz %zu PtrackContentNblocks " UINT64_FORMAT ,
469
481
i , j , writesz , (uint64 ) PtrackContentNblocks );
470
-
471
482
j = 0 ;
472
483
}
473
484
}
@@ -726,7 +737,12 @@ ptrack_mark_block(RelFileNodeBackend smgr_rnode,
726
737
!pg_atomic_compare_exchange_u32 (& ptrack_map -> init_lsn , (uint32 * ) & old_init_lsn .value , new_lsn32 ));
727
738
}
728
739
729
- /* Atomically assign new LSN value to the first slot */
740
+ /* Assign latest_lsn first */
741
+ old_lsn .value = pg_atomic_read_u32 (& ptrack_map -> latest_lsn );
742
+ while (old_lsn .value < new_lsn32 &&
743
+ !pg_atomic_compare_exchange_u32 (& ptrack_map -> latest_lsn , (uint32 * ) & old_lsn .value , new_lsn32 ));
744
+
745
+ /* Then, atomically assign new LSN value to the first slot */
730
746
old_lsn .value = pg_atomic_read_u32 (& ptrack_map -> entries [slot1 ]);
731
747
elog (DEBUG3 , "ptrack_mark_block: map[%zu]=%u <- %u" , slot1 , old_lsn .value , new_lsn32 );
732
748
while (old_lsn .value < new_lsn32 &&
0 commit comments