From: | Tatsuhito Kasahara <kasahara(dot)tatsuhito(at)oss(dot)ntt(dot)co(dot)jp> |
---|---|
To: | pgsql-patches(at)postgresql(dot)org |
Cc: | "kasahara(OSSC)" <kasahara(dot)tatsuhito(at)oss(dot)ntt(dot)co(dot)jp> |
Subject: | Patch for pgstatindex to fix a bug reporting a value of strange leaf_fragmentation |
Date: | 2007-03-08 03:26:43 |
Message-ID: | 45EF8273.40404@oss.ntt.co.jp |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-patches |
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.
For example, GetBTPageStatistics() read a dead_leaf_block
(stat->type = 'd';) first, stat->fragments hold a strange value because
stat->fragments is not initialized before "return true"(pgstatindex.c
164th line)
And then, the strange value is just inserted in result. Under normal
circumstances, stat.fragments must be incremented only when stat->type
is 'l'.
So pgstatindex reports strange leaf_fragmentation.
I made the patch.
Please confirm this.
Best regards.
======== Test (postgresql8.2.1)========
test=# CREATE TABLE test (id int);
CREATE TABLE
test=# INSERT INTO test select generate_series(1,1000);
INSERT 0 1000
test=# CREATE INDEX idx_test ON test(id);
CREATE INDEX
test=# SELECT leaf_fragmentation from pgstatindex('idx_test');
-[ RECORD 1 ]------+--
leaf_fragmentation | 0
test=# DELETE FROM test;
DELETE 1000
test=# SELECT leaf_fragmentation from pgstatindex('idx_test');
-[ RECORD 1 ]------+--
leaf_fragmentation | 0
test=# VACUUM test;
VACUUM
test=# SELECT leaf_fragmentation from pgstatindex('idx_test');
-[ RECORD 1 ]------+------------
leaf_fragmentation | 28943878400 <- Invalid value
======== Test (postgresql8.2.1)========
=========gdb============
(gdb) b GetBTPageStatistics
Breakpoint 4 at 0xfd8126: file pgstatindex.c, line 145.
(gdb) c
Continuing.
Breakpoint 4, GetBTPageStatistics (blkno=1, buffer=101, stat=0xbfc3fbe4)
at pgstatindex.c:145
145 Page page = BufferGetPage(buffer);
(gdb) print stat.fragments
$4 = 144719392 <- Already have a invalid value.
(snip)
Breakpoint 3, GetBTPageStatistics (blkno=1, buffer=<value optimized out>,
stat=0xbfc3fbe4) at pgstatindex.c:161
161 if (P_ISDELETED(opaque))
(gdb) n
163 stat->type = 'd';
(snip)
pgstatindex (fcinfo=0xbfc3fc70) at pgstatindex.c:297
297 switch (stat.type)
(gdb) n
300 indexStat.deleted_pages++;
(gdb) n
319 indexStat.fragments += stat.fragments;
(gdb) print stat.fragments
$3 = 144719392 <- Just inserts inavlid value in result even if stat.type is 'dead'.
=========gdb============
=========patch test============
test=# CREATE TABLE test2 (id int);
CREATE TABLE
test=# INSERT INTO test2 select generate_series(1,1000);
INSERT 0 1000
test=# CREATE INDEX idx_test2 ON test2(id);
CREATE INDEX
test=# DELETE FROM test2;
DELETE 1000
test=# VACUUM test2;
VACUUM
test=# SELECT leaf_fragmentation from pgstatindex('idx_test2');
-[ RECORD 1 ]------+--
leaf_fragmentation | 0 <- OK
test=# INSERT INTO test2 select generate_series(1,1000);
INSERT 0 1000
test=# SELECT leaf_fragmentation from pgstatindex('idx_test2');
-[ RECORD 1 ]------+--
leaf_fragmentation | 0 <- OK
test=# INSERT INTO test2 select generate_series(1,1000);
INSERT 0 1000
test=# SELECT leaf_fragmentation from pgstatindex('idx_test2');
-[ RECORD 1 ]------+------
leaf_fragmentation | 28.57 <- OK.
=========patch test============
--
NTT OSS Center
Tatsuhito Kasahara
kasahara.tatsuhito _at_ oss.ntt.co.jp
Attachment | Content-Type | Size |
---|---|---|
pgstatindex.c.patch | text/plain | 626 bytes |
From | Date | Subject | |
---|---|---|---|
Next Message | Luke Lonergan | 2007-03-08 03:32:14 | Re: Auto creation of Partitions |
Previous Message | Joris Dobbelsteen | 2007-03-07 20:13:40 | Re: Auto creation of Partitions |