Skip to content

Commit f6a0170

Browse files
committed
Take buffer lock while inspecting btree index pages in contrib/pageinspect.
It's not safe to examine a shared buffer without any lock.
1 parent f369815 commit f6a0170

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

contrib/pageinspect/btreefuncs.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,9 @@ GetBTPageStatistics(BlockNumber blkno, Buffer buffer, BTPageStat *stat)
158158
}
159159

160160
/* -----------------------------------------------
161-
* bt_page()
161+
* bt_page_stats()
162162
*
163-
* Usage: SELECT * FROM bt_page('t1_pkey', 1);
163+
* Usage: SELECT * FROM bt_page_stats('t1_pkey', 1);
164164
* -----------------------------------------------
165165
*/
166166
Datum
@@ -206,13 +206,17 @@ bt_page_stats(PG_FUNCTION_ARGS)
206206
CHECK_RELATION_BLOCK_RANGE(rel, blkno);
207207

208208
buffer = ReadBuffer(rel, blkno);
209+
LockBuffer(buffer, BUFFER_LOCK_SHARE);
209210

210211
/* keep compiler quiet */
211212
stat.btpo_prev = stat.btpo_next = InvalidBlockNumber;
212213
stat.btpo_flags = stat.free_size = stat.avg_item_size = 0;
213214

214215
GetBTPageStatistics(blkno, buffer, &stat);
215216

217+
UnlockReleaseBuffer(buffer);
218+
relation_close(rel, AccessShareLock);
219+
216220
/* Build a tuple descriptor for our result type */
217221
if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
218222
elog(ERROR, "return type must be a row type");
@@ -249,10 +253,6 @@ bt_page_stats(PG_FUNCTION_ARGS)
249253

250254
result = HeapTupleGetDatum(tuple);
251255

252-
ReleaseBuffer(buffer);
253-
254-
relation_close(rel, AccessShareLock);
255-
256256
PG_RETURN_DATUM(result);
257257
}
258258

@@ -324,6 +324,7 @@ bt_page_items(PG_FUNCTION_ARGS)
324324
CHECK_RELATION_BLOCK_RANGE(rel, blkno);
325325

326326
buffer = ReadBuffer(rel, blkno);
327+
LockBuffer(buffer, BUFFER_LOCK_SHARE);
327328

328329
/*
329330
* We copy the page into local storage to avoid holding pin on the
@@ -337,7 +338,7 @@ bt_page_items(PG_FUNCTION_ARGS)
337338
uargs->page = palloc(BLCKSZ);
338339
memcpy(uargs->page, BufferGetPage(buffer), BLCKSZ);
339340

340-
ReleaseBuffer(buffer);
341+
UnlockReleaseBuffer(buffer);
341342
relation_close(rel, AccessShareLock);
342343

343344
uargs->offset = FirstOffsetNumber;
@@ -468,6 +469,8 @@ bt_metap(PG_FUNCTION_ARGS)
468469
errmsg("cannot access temporary tables of other sessions")));
469470

470471
buffer = ReadBuffer(rel, 0);
472+
LockBuffer(buffer, BUFFER_LOCK_SHARE);
473+
471474
page = BufferGetPage(buffer);
472475
metad = BTPageGetMeta(page);
473476

@@ -494,8 +497,7 @@ bt_metap(PG_FUNCTION_ARGS)
494497

495498
result = HeapTupleGetDatum(tuple);
496499

497-
ReleaseBuffer(buffer);
498-
500+
UnlockReleaseBuffer(buffer);
499501
relation_close(rel, AccessShareLock);
500502

501503
PG_RETURN_DATUM(result);

0 commit comments

Comments
 (0)