From f697d7d36bf4d79ac3b0ea6985331f5a94a55117 Mon Sep 17 00:00:00 2001 From: Jianghua Yang Date: Fri, 15 May 2026 23:10:16 +0800 Subject: [PATCH] AO vacuum: CommandCounterIncrement before AppendOptimizedTruncateToEOF ClearAOCSFileSegInfo/ClearFileSegInfo (called from ao_vacuum_rel_recycle_dead_segments) updates pg_aoseg rows via simple_heap_update, which assigns the current CommandId to the new tuple. AppendOptimizedTruncateToEOF then opens a catalog snapshot via GetCatalogSnapshot, which also uses GetCurrentCommandId. Because both operations share the same CommandId, the just-zeroed rows are invisible to the snapshot (cid >= snapshot->curcid), while the old rows with their original non-zero EOF values remain visible. TruncateAOSegmentFile then sees a 0-byte physical file but a non-zero logical EOF and raises: "file size smaller than logical eof" Advancing the command counter before AppendOptimizedTruncateToEOF ensures the zeroed rows are visible to its catalog snapshot (their cid is now strictly less than the new curcid). Fixes: https://github.com/apache/cloudberry/issues/1746 --- src/backend/commands/vacuum_ao.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/backend/commands/vacuum_ao.c b/src/backend/commands/vacuum_ao.c index 466fe30665d..dff6ecf332d 100644 --- a/src/backend/commands/vacuum_ao.c +++ b/src/backend/commands/vacuum_ao.c @@ -224,6 +224,14 @@ ao_vacuum_rel_pre_cleanup(Relation onerel, VacuumParams *params, BufferAccessStr */ ao_vacuum_rel_recycle_dead_segments(onerel, params, bstrategy, vacrelstats); + /* + * Make the pg_aoseg updates above visible to AppendOptimizedTruncateToEOF's + * catalog snapshot; without this the zeroed-eof rows are invisible (same + * CommandId) and the old non-zero-eof rows appear live, triggering "file + * size smaller than logical eof". + */ + CommandCounterIncrement(); + /* * Also truncate all live segments to the EOF values stored in pg_aoseg. * This releases space left behind by aborted inserts.