]> granicus.if.org Git - postgresql/commitdiff
Take buffer lock while inspecting btree index pages in contrib/pageinspect.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 30 Nov 2012 22:02:48 +0000 (17:02 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 30 Nov 2012 22:02:48 +0000 (17:02 -0500)
It's not safe to examine a shared buffer without any lock.

contrib/pageinspect/btreefuncs.c

index 4f56864d2e18bfae67aba76bb529997c82f946f4..5036df383fc8cc35d4635f3c2c15b32681a2b8de 100644 (file)
@@ -158,9 +158,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
@@ -206,6 +206,7 @@ bt_page_stats(PG_FUNCTION_ARGS)
        CHECK_RELATION_BLOCK_RANGE(rel, blkno);
 
        buffer = ReadBuffer(rel, blkno);
+       LockBuffer(buffer, BUFFER_LOCK_SHARE);
 
        /* keep compiler quiet */
        stat.btpo_prev = stat.btpo_next = InvalidBlockNumber;
@@ -213,6 +214,9 @@ bt_page_stats(PG_FUNCTION_ARGS)
 
        GetBTPageStatistics(blkno, buffer, &stat);
 
+       UnlockReleaseBuffer(buffer);
+       relation_close(rel, AccessShareLock);
+
        /* Build a tuple descriptor for our result type */
        if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
                elog(ERROR, "return type must be a row type");
@@ -249,10 +253,6 @@ bt_page_stats(PG_FUNCTION_ARGS)
 
        result = HeapTupleGetDatum(tuple);
 
-       ReleaseBuffer(buffer);
-
-       relation_close(rel, AccessShareLock);
-
        PG_RETURN_DATUM(result);
 }
 
@@ -324,6 +324,7 @@ bt_page_items(PG_FUNCTION_ARGS)
                CHECK_RELATION_BLOCK_RANGE(rel, blkno);
 
                buffer = ReadBuffer(rel, blkno);
+               LockBuffer(buffer, BUFFER_LOCK_SHARE);
 
                /*
                 * We copy the page into local storage to avoid holding pin on the
@@ -337,7 +338,7 @@ bt_page_items(PG_FUNCTION_ARGS)
                uargs->page = palloc(BLCKSZ);
                memcpy(uargs->page, BufferGetPage(buffer), BLCKSZ);
 
-               ReleaseBuffer(buffer);
+               UnlockReleaseBuffer(buffer);
                relation_close(rel, AccessShareLock);
 
                uargs->offset = FirstOffsetNumber;
@@ -468,6 +469,8 @@ bt_metap(PG_FUNCTION_ARGS)
                                 errmsg("cannot access temporary tables of other sessions")));
 
        buffer = ReadBuffer(rel, 0);
+       LockBuffer(buffer, BUFFER_LOCK_SHARE);
+
        page = BufferGetPage(buffer);
        metad = BTPageGetMeta(page);
 
@@ -494,8 +497,7 @@ bt_metap(PG_FUNCTION_ARGS)
 
        result = HeapTupleGetDatum(tuple);
 
-       ReleaseBuffer(buffer);
-
+       UnlockReleaseBuffer(buffer);
        relation_close(rel, AccessShareLock);
 
        PG_RETURN_DATUM(result);