Tatsuhito Kasahara wrote:
> Hello.
>
> I found a bug in contrib/pgstatindex.c to reports a strange value of
> leaf_fragmentation with some cases.
> #Look the following test example.
>
> In GetBTPageStatistics(), stat->fragments is not initialized properly
> so that invalid leaf_fragments values are inserted in results.
Right. Checking that code, it seems btpo.xact is also being incorrectly
handled, is it not? Incidentally, the return value seems a bit useless.
--
Alvaro Herrera http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.
Index: pgstatindex.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/contrib/pgstattuple/pgstatindex.c,v
retrieving revision 1.2
diff -c -p -r1.2 pgstatindex.c
*** pgstatindex.c 4 Sep 2006 02:03:04 -0000 1.2
--- pgstatindex.c 9 Mar 2007 03:16:30 -0000
*************** typedef struct BTIndexStat
*** 139,145 ****
* Collect statistics of single b-tree leaf page
* -------------------------------------------------
*/
! static bool
GetBTPageStatistics(BlockNumber blkno, Buffer buffer, BTPageStat * stat)
{
Page page = BufferGetPage(buffer);
--- 139,145 ----
* Collect statistics of single b-tree leaf page
* -------------------------------------------------
*/
! static void
GetBTPageStatistics(BlockNumber blkno, Buffer buffer, BTPageStat * stat)
{
Page page = BufferGetPage(buffer);
*************** GetBTPageStatistics(BlockNumber blkno, B
*** 154,159 ****
--- 154,160 ----
stat->max_avail = BLCKSZ - (BLCKSZ - phdr->pd_special + SizeOfPageHeaderData);
stat->dead_items = stat->live_items = 0;
+ stat->fragments = 0;
stat->page_size = PageGetPageSize(page);
*************** GetBTPageStatistics(BlockNumber blkno, B
*** 161,167 ****
if (P_ISDELETED(opaque))
{
stat->type = 'd';
! return true;
}
else if (P_IGNORE(opaque))
stat->type = 'e';
--- 162,169 ----
if (P_ISDELETED(opaque))
{
stat->type = 'd';
! stat->btpo.xact = opaque->btpo.xact;
! return;
}
else if (P_IGNORE(opaque))
stat->type = 'e';
*************** GetBTPageStatistics(BlockNumber blkno, B
*** 175,184 ****
/* btpage opaque data */
stat->btpo_prev = opaque->btpo_prev;
stat->btpo_next = opaque->btpo_next;
! if (P_ISDELETED(opaque))
! stat->btpo.xact = opaque->btpo.xact;
! else
! stat->btpo.level = opaque->btpo.level;
stat->btpo_flags = opaque->btpo_flags;
stat->btpo_cycleid = opaque->btpo_cycleid;
--- 177,183 ----
/* btpage opaque data */
stat->btpo_prev = opaque->btpo_prev;
stat->btpo_next = opaque->btpo_next;
! stat->btpo.level = opaque->btpo.level;
stat->btpo_flags = opaque->btpo_flags;
stat->btpo_cycleid = opaque->btpo_cycleid;
*************** GetBTPageStatistics(BlockNumber blkno, B
*** 187,193 ****
* it means a fragmentation.
*----------------------------------------------
*/
- stat->fragments = 0;
if (stat->type == 'l')
{
if (opaque->btpo_next != P_NONE && opaque->btpo_next < blkno)
--- 186,191 ----
*************** GetBTPageStatistics(BlockNumber blkno, B
*** 216,223 ****
stat->avg_item_size = item_size / (stat->live_items + stat->dead_items);
else
stat->avg_item_size = 0;
-
- return true;
}
--- 214,219 ----
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings