Commit d54a94b8 authored by Tom Lane's avatar Tom Lane

Take buffer lock while inspecting btree index pages in contrib/pageinspect.

It's not safe to examine a shared buffer without any lock.
parent b86327c1
...@@ -156,9 +156,9 @@ GetBTPageStatistics(BlockNumber blkno, Buffer buffer, BTPageStat *stat) ...@@ -156,9 +156,9 @@ GetBTPageStatistics(BlockNumber blkno, Buffer buffer, BTPageStat *stat)
} }
/* ----------------------------------------------- /* -----------------------------------------------
* bt_page() * bt_page_stats()
* *
* Usage: SELECT * FROM bt_page('t1_pkey', 1); * Usage: SELECT * FROM bt_page_stats('t1_pkey', 1);
* ----------------------------------------------- * -----------------------------------------------
*/ */
Datum Datum
...@@ -204,6 +204,7 @@ bt_page_stats(PG_FUNCTION_ARGS) ...@@ -204,6 +204,7 @@ bt_page_stats(PG_FUNCTION_ARGS)
CHECK_RELATION_BLOCK_RANGE(rel, blkno); CHECK_RELATION_BLOCK_RANGE(rel, blkno);
buffer = ReadBuffer(rel, blkno); buffer = ReadBuffer(rel, blkno);
LockBuffer(buffer, BUFFER_LOCK_SHARE);
/* keep compiler quiet */ /* keep compiler quiet */
stat.btpo_prev = stat.btpo_next = InvalidBlockNumber; stat.btpo_prev = stat.btpo_next = InvalidBlockNumber;
...@@ -211,6 +212,9 @@ bt_page_stats(PG_FUNCTION_ARGS) ...@@ -211,6 +212,9 @@ bt_page_stats(PG_FUNCTION_ARGS)
GetBTPageStatistics(blkno, buffer, &stat); GetBTPageStatistics(blkno, buffer, &stat);
UnlockReleaseBuffer(buffer);
relation_close(rel, AccessShareLock);
/* Build a tuple descriptor for our result type */ /* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE) if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type"); elog(ERROR, "return type must be a row type");
...@@ -247,10 +251,6 @@ bt_page_stats(PG_FUNCTION_ARGS) ...@@ -247,10 +251,6 @@ bt_page_stats(PG_FUNCTION_ARGS)
result = HeapTupleGetDatum(tuple); result = HeapTupleGetDatum(tuple);
ReleaseBuffer(buffer);
relation_close(rel, AccessShareLock);
PG_RETURN_DATUM(result); PG_RETURN_DATUM(result);
} }
...@@ -322,6 +322,7 @@ bt_page_items(PG_FUNCTION_ARGS) ...@@ -322,6 +322,7 @@ bt_page_items(PG_FUNCTION_ARGS)
CHECK_RELATION_BLOCK_RANGE(rel, blkno); CHECK_RELATION_BLOCK_RANGE(rel, blkno);
buffer = ReadBuffer(rel, blkno); buffer = ReadBuffer(rel, blkno);
LockBuffer(buffer, BUFFER_LOCK_SHARE);
/* /*
* We copy the page into local storage to avoid holding pin on the * We copy the page into local storage to avoid holding pin on the
...@@ -335,7 +336,7 @@ bt_page_items(PG_FUNCTION_ARGS) ...@@ -335,7 +336,7 @@ bt_page_items(PG_FUNCTION_ARGS)
uargs->page = palloc(BLCKSZ); uargs->page = palloc(BLCKSZ);
memcpy(uargs->page, BufferGetPage(buffer), BLCKSZ); memcpy(uargs->page, BufferGetPage(buffer), BLCKSZ);
ReleaseBuffer(buffer); UnlockReleaseBuffer(buffer);
relation_close(rel, AccessShareLock); relation_close(rel, AccessShareLock);
uargs->offset = FirstOffsetNumber; uargs->offset = FirstOffsetNumber;
...@@ -466,6 +467,8 @@ bt_metap(PG_FUNCTION_ARGS) ...@@ -466,6 +467,8 @@ bt_metap(PG_FUNCTION_ARGS)
errmsg("cannot access temporary tables of other sessions"))); errmsg("cannot access temporary tables of other sessions")));
buffer = ReadBuffer(rel, 0); buffer = ReadBuffer(rel, 0);
LockBuffer(buffer, BUFFER_LOCK_SHARE);
page = BufferGetPage(buffer); page = BufferGetPage(buffer);
metad = BTPageGetMeta(page); metad = BTPageGetMeta(page);
...@@ -492,8 +495,7 @@ bt_metap(PG_FUNCTION_ARGS) ...@@ -492,8 +495,7 @@ bt_metap(PG_FUNCTION_ARGS)
result = HeapTupleGetDatum(tuple); result = HeapTupleGetDatum(tuple);
ReleaseBuffer(buffer); UnlockReleaseBuffer(buffer);
relation_close(rel, AccessShareLock); relation_close(rel, AccessShareLock);
PG_RETURN_DATUM(result); PG_RETURN_DATUM(result);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment