On Wed, Feb 22, 2012 at 12:27 AM, Noah Misch <n...@leadboat.com> wrote: > On Tue, Feb 14, 2012 at 02:04:26AM -0500, Jaime Casanova wrote: >> >> 1) pgstattuple-gin_spgist.patch >> This first patch adds gin and spgist support to pgstattuple, also >> makes pgstattuple use a ring buffer when reading tables or indexes. > > The buffer access strategy usage bits look fine to commit. >
ok. i extracted that part. which basically makes pgstattuple usable in production (i mean, by not bloating shared buffers when using the function) -- Jaime Casanova www.2ndQuadrant.com Professional PostgreSQL: Soporte 24x7 y capacitación
diff --git a/contrib/pgstattuple/pgstatindex.c b/contrib/pgstattuple/pgstatindex.c new file mode 100644 index beff1b9..9f2ec1f *** a/contrib/pgstattuple/pgstatindex.c --- b/contrib/pgstattuple/pgstatindex.c *************** pgstatindex(PG_FUNCTION_ARGS) *** 95,100 **** --- 95,101 ---- BlockNumber nblocks; BlockNumber blkno; BTIndexStat indexStat; + BufferAccessStrategy bstrategy = GetAccessStrategy(BAS_BULKREAD); if (!superuser()) ereport(ERROR, *************** pgstatindex(PG_FUNCTION_ARGS) *** 122,128 **** * Read metapage */ { ! Buffer buffer = ReadBuffer(rel, 0); Page page = BufferGetPage(buffer); BTMetaPageData *metad = BTPageGetMeta(page); --- 123,129 ---- * Read metapage */ { ! Buffer buffer = ReadBufferExtended(rel, MAIN_FORKNUM, 0, RBM_NORMAL, bstrategy); Page page = BufferGetPage(buffer); BTMetaPageData *metad = BTPageGetMeta(page); *************** pgstatindex(PG_FUNCTION_ARGS) *** 159,165 **** CHECK_FOR_INTERRUPTS(); /* Read and lock buffer */ ! buffer = ReadBuffer(rel, blkno); LockBuffer(buffer, BUFFER_LOCK_SHARE); page = BufferGetPage(buffer); --- 160,166 ---- CHECK_FOR_INTERRUPTS(); /* Read and lock buffer */ ! buffer = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy); LockBuffer(buffer, BUFFER_LOCK_SHARE); page = BufferGetPage(buffer); diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c new file mode 100644 index e5ddd87..580e24e *** a/contrib/pgstattuple/pgstattuple.c --- b/contrib/pgstattuple/pgstattuple.c *************** static Datum pgstat_index(Relation rel, *** 78,83 **** --- 78,90 ---- static void pgstat_index_page(pgstattuple_type *stat, Page page, OffsetNumber minoff, OffsetNumber maxoff); + /* + * Buffer access strategy for reading relations, it's simpler to keep it + * global because pgstat_*_page() functions read one buffer at a time. + * pgstat_heap() and pgstat_index() should initialize it before use. + */ + BufferAccessStrategy bstrategy; + /* * build_pgstattuple_type -- build a pgstattuple_type tuple */ *************** pgstat_relation(Relation rel, FunctionCa *** 231,236 **** --- 238,246 ---- case GIN_AM_OID: err = "gin index"; break; + case SPGIST_AM_OID: + err = "spgist index"; + break; default: err = "unknown index"; break; *************** pgstat_heap(Relation rel, FunctionCallIn *** 276,281 **** --- 286,295 ---- nblocks = scan->rs_nblocks; /* # blocks to be scanned */ + /* prepare access strategy for this table */ + bstrategy = GetAccessStrategy(BAS_BULKREAD); + scan->rs_strategy = bstrategy; + /* scan the relation */ while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { *************** pgstat_heap(Relation rel, FunctionCallIn *** 309,315 **** { CHECK_FOR_INTERRUPTS(); ! buffer = ReadBuffer(rel, block); LockBuffer(buffer, BUFFER_LOCK_SHARE); stat.free_space += PageGetHeapFreeSpace((Page) BufferGetPage(buffer)); UnlockReleaseBuffer(buffer); --- 323,329 ---- { CHECK_FOR_INTERRUPTS(); ! buffer = ReadBufferExtended(rel, MAIN_FORKNUM, block, RBM_NORMAL, bstrategy); LockBuffer(buffer, BUFFER_LOCK_SHARE); stat.free_space += PageGetHeapFreeSpace((Page) BufferGetPage(buffer)); UnlockReleaseBuffer(buffer); *************** pgstat_heap(Relation rel, FunctionCallIn *** 322,328 **** { CHECK_FOR_INTERRUPTS(); ! buffer = ReadBuffer(rel, block); LockBuffer(buffer, BUFFER_LOCK_SHARE); stat.free_space += PageGetHeapFreeSpace((Page) BufferGetPage(buffer)); UnlockReleaseBuffer(buffer); --- 336,342 ---- { CHECK_FOR_INTERRUPTS(); ! buffer = ReadBufferExtended(rel, MAIN_FORKNUM, block, RBM_NORMAL, bstrategy); LockBuffer(buffer, BUFFER_LOCK_SHARE); stat.free_space += PageGetHeapFreeSpace((Page) BufferGetPage(buffer)); UnlockReleaseBuffer(buffer); *************** pgstat_btree_page(pgstattuple_type *stat *** 345,351 **** Buffer buf; Page page; ! buf = ReadBuffer(rel, blkno); LockBuffer(buf, BT_READ); page = BufferGetPage(buf); --- 359,365 ---- Buffer buf; Page page; ! buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy); LockBuffer(buf, BT_READ); page = BufferGetPage(buf); *************** pgstat_hash_page(pgstattuple_type *stat, *** 389,395 **** Page page; _hash_getlock(rel, blkno, HASH_SHARE); ! buf = _hash_getbuf(rel, blkno, HASH_READ, 0); page = BufferGetPage(buf); if (PageGetSpecialSize(page) == MAXALIGN(sizeof(HashPageOpaqueData))) --- 403,409 ---- Page page; _hash_getlock(rel, blkno, HASH_SHARE); ! buf = _hash_getbuf_with_strategy(rel, blkno, HASH_READ, 0, bstrategy); page = BufferGetPage(buf); if (PageGetSpecialSize(page) == MAXALIGN(sizeof(HashPageOpaqueData))) *************** pgstat_gist_page(pgstattuple_type *stat, *** 431,437 **** Buffer buf; Page page; ! buf = ReadBuffer(rel, blkno); LockBuffer(buf, GIST_SHARE); gistcheckpage(rel, buf); page = BufferGetPage(buf); --- 445,451 ---- Buffer buf; Page page; ! buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy); LockBuffer(buf, GIST_SHARE); gistcheckpage(rel, buf); page = BufferGetPage(buf); *************** pgstat_index(Relation rel, BlockNumber s *** 460,465 **** --- 474,482 ---- BlockNumber blkno; pgstattuple_type stat = {0}; + /* prepare access strategy for this index */ + bstrategy = GetAccessStrategy(BAS_BULKREAD); + blkno = start; for (;;) {
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers