Skip to content

Commit b2e237a

Browse files
committed
Release lock on heap buffer before vacuuming FSM
When there are no indexes on a table, we vacuum each heap block after pruning it and then update the freespace map. Periodically, we also vacuum the freespace map. This was done while unnecessarily holding a lock on the heap page. Release the lock before calling FreeSpaceMapVacuumRange() and, while we're at it, ensure the range includes the heap block we just vacuumed. There are no known deadlocks or other similar issues, therefore don't backpatch. It's certainly not good to do all this work under a lock, but it's not frequently reached, making it not worth the risk of backpatching. Author: Melanie Plageman <melanieplageman@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/CAAKRu_YiL%3D44GvGnt1dpYouDSSoV7wzxVoXs8m3p311rp-TVQQ%40mail.gmail.com
1 parent f7816ae commit b2e237a

File tree

1 file changed

+18
-12
lines changed

1 file changed

+18
-12
lines changed

src/backend/access/heap/vacuumlazy.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,18 +1046,6 @@ lazy_scan_heap(LVRelState *vacrel)
10461046
/* Forget the LP_DEAD items that we just vacuumed */
10471047
dead_items->num_items = 0;
10481048

1049-
/*
1050-
* Periodically perform FSM vacuuming to make newly-freed
1051-
* space visible on upper FSM pages. Note we have not yet
1052-
* performed FSM processing for blkno.
1053-
*/
1054-
if (blkno - next_fsm_block_to_vacuum >= VACUUM_FSM_EVERY_PAGES)
1055-
{
1056-
FreeSpaceMapVacuumRange(vacrel->rel, next_fsm_block_to_vacuum,
1057-
blkno);
1058-
next_fsm_block_to_vacuum = blkno;
1059-
}
1060-
10611049
/*
10621050
* Now perform FSM processing for blkno, and move on to next
10631051
* page.
@@ -1071,6 +1059,24 @@ lazy_scan_heap(LVRelState *vacrel)
10711059

10721060
UnlockReleaseBuffer(buf);
10731061
RecordPageWithFreeSpace(vacrel->rel, blkno, freespace);
1062+
1063+
/*
1064+
* Periodically perform FSM vacuuming to make newly-freed
1065+
* space visible on upper FSM pages. FreeSpaceMapVacuumRange()
1066+
* vacuums the portion of the freespace map covering heap
1067+
* pages from start to end - 1. Include the block we just
1068+
* vacuumed by passing it blkno + 1. Overflow isn't an issue
1069+
* because MaxBlockNumber + 1 is InvalidBlockNumber which
1070+
* causes FreeSpaceMapVacuumRange() to vacuum freespace map
1071+
* pages covering the remainder of the relation.
1072+
*/
1073+
if (blkno - next_fsm_block_to_vacuum >= VACUUM_FSM_EVERY_PAGES)
1074+
{
1075+
FreeSpaceMapVacuumRange(vacrel->rel, next_fsm_block_to_vacuum,
1076+
blkno + 1);
1077+
next_fsm_block_to_vacuum = blkno + 1;
1078+
}
1079+
10741080
continue;
10751081
}
10761082

0 commit comments

Comments
 (0)