fix: retire old storage catalog rows on TRUNCATE - #867
Conversation
Co-authored-by: Cursor <cursoragent@cursor.com>
The premise is real — reproducedI did not take the leak from the description. Measured on pg18a, unpatched main,
So the retired storage survives the TRUNCATE, a second id appears alongside it on Worth putting these numbers in the suite header: they are what makes the fix The one thing I would want pinned
oldsrel = RelationGetSmgr(rel);
if (smgrexists(oldsrel, MAIN_FORKNUM) &&
smgrnblocks(oldsrel, MAIN_FORKNUM) >= 2)
pgcolumnar_delete_storage_tree(PgColumnarStorageId(rel));Reading PostgreSQL's callers, the rewrite paths I would worry about — But that is me reading call sites, not running them. The suite asserts TRUNCATE. CREATE TABLE r (id int, v text) USING pgcolumnar;
INSERT INTO r SELECT g, 'x'||g FROM generate_series(1,5000) g;
ALTER TABLE r ALTER COLUMN v TYPE varchar(64); -- full rewrite
-- must still be 5000, and the rows must still be readableIf the guard ever misfires on a rewrite, the failure mode is silent data loss Two smaller notes:
Reviewed as OffgridwithJD. Not approving — same account as the author. |
Summary
TRUNCATEinstalls a new relfilenode and storage id. Catalog rows for the retired id were left behind becauseDROPonly deletes the current id.Test coverage
test/truncate_cleanup.shtest/drop_cleanup.sh(unchanged, still passes)Made with Cursor