Re: Add visibility map information to pg_freespace.

Поиск
Список
Период
Сортировка
От Kyotaro HORIGUCHI
Тема Re: Add visibility map information to pg_freespace.
Дата
Msg-id 20130709.195555.232199346.horiguchi.kyotaro@lab.ntt.co.jp
обсуждение исходный текст
Ответ на Re: Add visibility map information to pg_freespace.  (Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp>)
Ответы Re: Add visibility map information to pg_freespace.  (Satoshi Nagayasu <snaga@uptime.jp>)
Список pgsql-hackers
Hello, I've brought visibilitymap extentions for pg_freespacemap
and pgstattuple.

At Mon, 08 Jul 2013 16:59:05 +0900 (Tokyo Standard Time), Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp> wrote in
<20130708.165905.118860769.horiguchi.kyotaro@lab.ntt.co.jp>
> I'll come again with the first implementation of it. And as for
> pg_freespacemap, I'll keep the current direction - adding column
> to present output records format of pg_freespace(). And
> documentation, if possible.

pg_freespace_vm_v2.patch:
 Interface has been changed from the first patch. The version of pg_freespace() provided with vm information is named
pg_freespace_with_vminfo()and shows output like following.
 

| postgres=# select * from pg_freespace_with_vminfo('t'::regclass) limit 10;
|  blkno | avail | is_all_visible 
| -------+-------+----------------
|      0 |    64 | t
|      1 |    32 | t
|      2 |    96 | t
|      3 |    64 | t
|      4 |    96 | t
|      5 |    96 | t
|      6 |   128 | t
|      7 |    32 | t
|      8 |    96 | t  
pgstattuple_vm_v1.patch:
 The first version of VM extension for pgstattuple. According to the previous discussion, the added column is named
'all_visible_percent'.

| postgres=# select * from pgstattuple('t');
| -[ RECORD 1 ]-------+---------
| table_len           | 71770112
| tuple_count         | 989859
| tuple_len           | 31675488
| tuple_percent       | 44.13
| dead_tuple_count    | 99
| dead_tuple_len      | 3168
| dead_tuple_percent  | 0
| free_space          | 31886052
| free_percent        | 44.43
| all_visible_percent | 99.98

regards,

-- 
Kyotaro Horiguchi
NTT Open Source Software Center

diff --git a/contrib/pg_freespacemap/Makefile b/contrib/pg_freespacemap/Makefile
index b2e3ba3..d794df2 100644
--- a/contrib/pg_freespacemap/Makefile
+++ b/contrib/pg_freespacemap/Makefile
@@ -4,7 +4,7 @@ MODULE_big = pg_freespacemapOBJS = pg_freespacemap.oEXTENSION = pg_freespacemap
-DATA = pg_freespacemap--1.0.sql pg_freespacemap--unpackaged--1.0.sql
+DATA = pg_freespacemap--1.1.sql pg_freespacemap--1.0--1.1.sql pg_freespacemap--unpackaged--1.0.sqlifdef
USE_PGXSPG_CONFIG= pg_config
 
diff --git a/contrib/pg_freespacemap/pg_freespacemap--1.0--1.1.sql
b/contrib/pg_freespacemap/pg_freespacemap--1.0--1.1.sql
new file mode 100644
index 0000000..e7b25bd
--- /dev/null
+++ b/contrib/pg_freespacemap/pg_freespacemap--1.0--1.1.sql
@@ -0,0 +1,21 @@
+/* contrib/pg_freespacemap/pg_freespacemap--1.0--1.1.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "ALTER EXTENSION pg_freespacemap UPDATE TO '1.1'" to load this file. \quit
+
+CREATE FUNCTION pg_is_all_visible(regclass, bigint)
+RETURNS bool
+AS 'MODULE_PATHNAME', 'pg_is_all_visible'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION
+  pg_freespace_with_vminfo(rel regclass, blkno OUT bigint, avail OUT int2, is_all_visible OUT boolean)
+RETURNS SETOF RECORD
+AS $$
+  SELECT blkno, pg_freespace($1, blkno) AS avail, pg_is_all_visible($1, blkno) as is_all_visible
+  FROM generate_series(0, pg_relation_size($1) / current_setting('block_size')::bigint - 1) AS blkno;
+$$
+LANGUAGE SQL;
+
+-- Don't want these to be available to public.
+REVOKE ALL ON FUNCTION pg_freespace_with_vminfo(regclass) FROM PUBLIC;
diff --git a/contrib/pg_freespacemap/pg_freespacemap--1.0.sql b/contrib/pg_freespacemap/pg_freespacemap--1.0.sql
deleted file mode 100644
index 2adb52a..0000000
--- a/contrib/pg_freespacemap/pg_freespacemap--1.0.sql
+++ /dev/null
@@ -1,25 +0,0 @@
-/* contrib/pg_freespacemap/pg_freespacemap--1.0.sql */
-
--- complain if script is sourced in psql, rather than via CREATE EXTENSION
-\echo Use "CREATE EXTENSION pg_freespacemap" to load this file. \quit
-
--- Register the C function.
-CREATE FUNCTION pg_freespace(regclass, bigint)
-RETURNS int2
-AS 'MODULE_PATHNAME', 'pg_freespace'
-LANGUAGE C STRICT;
-
--- pg_freespace shows the recorded space avail at each block in a relation
-CREATE FUNCTION
-  pg_freespace(rel regclass, blkno OUT bigint, avail OUT int2)
-RETURNS SETOF RECORD
-AS $$
-  SELECT blkno, pg_freespace($1, blkno) AS avail
-  FROM generate_series(0, pg_relation_size($1) / current_setting('block_size')::bigint - 1) AS blkno;
-$$
-LANGUAGE SQL;
-
-
--- Don't want these to be available to public.
-REVOKE ALL ON FUNCTION pg_freespace(regclass, bigint) FROM PUBLIC;
-REVOKE ALL ON FUNCTION pg_freespace(regclass) FROM PUBLIC;
diff --git a/contrib/pg_freespacemap/pg_freespacemap--1.1.sql b/contrib/pg_freespacemap/pg_freespacemap--1.1.sql
new file mode 100644
index 0000000..7d2c2fe
--- /dev/null
+++ b/contrib/pg_freespacemap/pg_freespacemap--1.1.sql
@@ -0,0 +1,41 @@
+/* contrib/pg_freespacemap/pg_freespacemap--1.1.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION pg_freespacemap" to load this file. \quit
+
+-- Register the C function.
+CREATE FUNCTION pg_freespace(regclass, bigint)
+RETURNS int2
+AS 'MODULE_PATHNAME', 'pg_freespace'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION pg_is_all_visible(regclass, bigint)
+RETURNS bool
+AS 'MODULE_PATHNAME', 'pg_is_all_visible'
+LANGUAGE C STRICT;
+
+-- pg_freespace shows the recorded space avail at each block in a relation
+CREATE FUNCTION
+  pg_freespace(rel regclass, blkno OUT bigint, avail OUT int2)
+RETURNS SETOF RECORD
+AS $$
+  SELECT blkno, pg_freespace($1, blkno) AS avail
+  FROM generate_series(0, pg_relation_size($1) / current_setting('block_size')::bigint - 1) AS blkno;
+$$
+LANGUAGE SQL;
+
+CREATE FUNCTION
+  pg_freespace_with_vminfo(rel regclass, blkno OUT bigint, avail OUT int2, is_all_visible OUT boolean)
+RETURNS SETOF RECORD
+AS $$
+  SELECT blkno, pg_freespace($1, blkno) AS avail, pg_is_all_visible($1, blkno) as is_all_visible
+  FROM generate_series(0, pg_relation_size($1) / current_setting('block_size')::bigint - 1) AS blkno;
+$$
+LANGUAGE SQL;
+
+
+
+-- Don't want these to be available to public.
+REVOKE ALL ON FUNCTION pg_freespace(regclass, bigint) FROM PUBLIC;
+REVOKE ALL ON FUNCTION pg_freespace(regclass) FROM PUBLIC;
+REVOKE ALL ON FUNCTION pg_freespace_with_vminfo(regclass) FROM PUBLIC;
diff --git a/contrib/pg_freespacemap/pg_freespacemap.c b/contrib/pg_freespacemap/pg_freespacemap.c
index f6f7d2e..61b1a04 100644
--- a/contrib/pg_freespacemap/pg_freespacemap.c
+++ b/contrib/pg_freespacemap/pg_freespacemap.c
@@ -10,17 +10,20 @@#include "funcapi.h"#include "storage/freespace.h"
-
+#include "access/visibilitymap.h"
+#include "storage/bufmgr.h"PG_MODULE_MAGIC;Datum        pg_freespace(PG_FUNCTION_ARGS);
+Datum        pg_is_all_visible(PG_FUNCTION_ARGS);/* * Returns the amount of free space on a given page, according to
the* free space map. */PG_FUNCTION_INFO_V1(pg_freespace);
 
+PG_FUNCTION_INFO_V1(pg_is_all_visible);Datumpg_freespace(PG_FUNCTION_ARGS)
@@ -38,7 +41,32 @@ pg_freespace(PG_FUNCTION_ARGS)                 errmsg("invalid block number")));    freespace =
GetRecordedFreeSpace(rel,blkno);
 
-    relation_close(rel, AccessShareLock);    PG_RETURN_INT16(freespace);}
+
+Datum
+pg_is_all_visible(PG_FUNCTION_ARGS)
+{
+    Oid            relid = PG_GETARG_OID(0);
+    int64        blkno = PG_GETARG_INT64(1);
+    Buffer      vmbuffer = InvalidBuffer;
+    int            all_visible;
+    Relation    rel;
+
+    rel = relation_open(relid, AccessShareLock);
+
+    if (blkno < 0 || blkno > MaxBlockNumber)
+        ereport(ERROR,
+                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                 errmsg("invalid block number")));
+
+    all_visible = visibilitymap_test(rel, blkno, &vmbuffer);
+    if (vmbuffer != InvalidBuffer)
+    {
+        ReleaseBuffer(vmbuffer);
+        vmbuffer = InvalidBuffer;
+    }
+    relation_close(rel, AccessShareLock);
+    PG_RETURN_BOOL(all_visible);
+}
diff --git a/contrib/pg_freespacemap/pg_freespacemap.control b/contrib/pg_freespacemap/pg_freespacemap.control
index 34b695f..7d1e62a 100644
--- a/contrib/pg_freespacemap/pg_freespacemap.control
+++ b/contrib/pg_freespacemap/pg_freespacemap.control
@@ -1,5 +1,5 @@# pg_freespacemap extension
-comment = 'examine the free space map (FSM)'
-default_version = '1.0'
+comment = 'examine the free space map (FSM) and visibility map (VM)'
+default_version = '1.1'module_pathname = '$libdir/pg_freespacemap'relocatable = true
diff --git a/contrib/pgstattuple/Makefile b/contrib/pgstattuple/Makefile
index fc893d8..e842afc 100644
--- a/contrib/pgstattuple/Makefile
+++ b/contrib/pgstattuple/Makefile
@@ -4,7 +4,7 @@ MODULE_big    = pgstattupleOBJS        = pgstattuple.o pgstatindex.oEXTENSION = pgstattuple
-DATA = pgstattuple--1.1.sql pgstattuple--1.0--1.1.sql pgstattuple--unpackaged--1.0.sql
+DATA = pgstattuple--1.2.sql pgstattuple--1.1--1.2.sql pgstattuple--1.0--1.2.sql
pgstattuple--unpackaged--1.0.sqlREGRESS= pgstattuple
 
diff --git a/contrib/pgstattuple/expected/pgstattuple.out b/contrib/pgstattuple/expected/pgstattuple.out
index ab28f50..44c324d 100644
--- a/contrib/pgstattuple/expected/pgstattuple.out
+++ b/contrib/pgstattuple/expected/pgstattuple.out
@@ -6,15 +6,15 @@ CREATE EXTENSION pgstattuple;--create table test (a int primary key, b int[]);select * from
pgstattuple('test'::text);
- table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent |
free_space| free_percent 
 

------------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
-         0 |           0 |         0 |             0 |                0 |              0 |                  0 |
 0 |            0
 
+ table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent |
free_space| free_percent | all_visible_percent 
 

+-----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------+---------------------
+         0 |           0 |         0 |             0 |                0 |              0 |                  0 |
 0 |            0 |                   0(1 row)select * from pgstattuple('test'::regclass);
 
- table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent |
free_space| free_percent 
 

------------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
-         0 |           0 |         0 |             0 |                0 |              0 |                  0 |
 0 |            0
 
+ table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent |
free_space| free_percent | all_visible_percent 
 

+-----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------+---------------------
+         0 |           0 |         0 |             0 |                0 |              0 |                  0 |
 0 |            0 |                   0(1 row)select * from pgstatindex('test_pkey');
 
diff --git a/contrib/pgstattuple/pgstattuple--1.0--1.1.sql b/contrib/pgstattuple/pgstattuple--1.0--1.1.sql
deleted file mode 100644
index cf582a0..0000000
--- a/contrib/pgstattuple/pgstattuple--1.0--1.1.sql
+++ /dev/null
@@ -1,11 +0,0 @@
-/* contrib/pgstattuple/pgstattuple--1.0--1.1.sql */
-
--- complain if script is sourced in psql, rather than via ALTER EXTENSION
-\echo Use "ALTER EXTENSION pgstattuple UPDATE TO '1.1'" to load this file. \quit
-
-CREATE FUNCTION pgstatginindex(IN relname regclass,
-    OUT version INT4,
-    OUT pending_pages INT4,
-    OUT pending_tuples BIGINT)
-AS 'MODULE_PATHNAME', 'pgstatginindex'
-LANGUAGE C STRICT;
diff --git a/contrib/pgstattuple/pgstattuple--1.0--1.2.sql b/contrib/pgstattuple/pgstattuple--1.0--1.2.sql
new file mode 100644
index 0000000..051a04b
--- /dev/null
+++ b/contrib/pgstattuple/pgstattuple--1.0--1.2.sql
@@ -0,0 +1,41 @@
+/* contrib/pgstattuple/pgstattuple--1.0--1.2.sql */
+
+-- complain if script is sourced in psql, rather than via ALTER EXTENSION
+\echo Use "ALTER EXTENSION pgstattuple UPDATE TO '1.2'" to load this file. \quit
+
+CREATE FUNCTION pgstatginindex(IN relname regclass,
+    OUT version INT4,
+    OUT pending_pages INT4,
+    OUT pending_tuples BIGINT)
+AS 'MODULE_PATHNAME', 'pgstatginindex'
+LANGUAGE C STRICT;
+
+DROP FUNCTION pgstattuple(text);
+CREATE OR REPLACE FUNCTION pgstattuple(IN relname text,
+    OUT table_len BIGINT,        -- physical table length in bytes
+    OUT tuple_count BIGINT,        -- number of live tuples
+    OUT tuple_len BIGINT,        -- total tuples length in bytes
+    OUT tuple_percent FLOAT8,        -- live tuples in %
+    OUT dead_tuple_count BIGINT,    -- number of dead tuples
+    OUT dead_tuple_len BIGINT,        -- total dead tuples length in bytes
+    OUT dead_tuple_percent FLOAT8,    -- dead tuples in %
+    OUT free_space BIGINT,        -- free space in bytes
+    OUT free_percent FLOAT8,        -- free space in %
+    OUT all_visible_percent FLOAT8)        -- all visible blocks in %
+AS 'MODULE_PATHNAME', 'pgstattuple'
+LANGUAGE C STRICT;
+
+DROP FUNCTION pgstattuple(oid);
+CREATE OR REPLACE FUNCTION pgstattuple(IN reloid oid,
+    OUT table_len BIGINT,        -- physical table length in bytes
+    OUT tuple_count BIGINT,        -- number of live tuples
+    OUT tuple_len BIGINT,        -- total tuples length in bytes
+    OUT tuple_percent FLOAT8,        -- live tuples in %
+    OUT dead_tuple_count BIGINT,    -- number of dead tuples
+    OUT dead_tuple_len BIGINT,        -- total dead tuples length in bytes
+    OUT dead_tuple_percent FLOAT8,    -- dead tuples in %
+    OUT free_space BIGINT,        -- free space in bytes
+    OUT free_percent FLOAT8,        -- free space in %
+    OUT all_visible_percent FLOAT8)        -- all visible blocks in %
+AS 'MODULE_PATHNAME', 'pgstattuplebyid'
+LANGUAGE C STRICT;
diff --git a/contrib/pgstattuple/pgstattuple--1.1--1.2.sql b/contrib/pgstattuple/pgstattuple--1.1--1.2.sql
new file mode 100644
index 0000000..124ae3e
--- /dev/null
+++ b/contrib/pgstattuple/pgstattuple--1.1--1.2.sql
@@ -0,0 +1,34 @@
+/* contrib/pgstattuple/pgstattuple--1.1--1.2.sql */
+
+-- complain if script is sourced in psql, rather than via ALTER EXTENSION
+\echo Use "ALTER EXTENSION pgstattuple UPDATE TO '1.2'" to load this file. \quit
+
+DROP FUNCTION pgstattuple(text);
+CREATE OR REPLACE FUNCTION pgstattuple(IN relname text,
+    OUT table_len BIGINT,        -- physical table length in bytes
+    OUT tuple_count BIGINT,        -- number of live tuples
+    OUT tuple_len BIGINT,        -- total tuples length in bytes
+    OUT tuple_percent FLOAT8,        -- live tuples in %
+    OUT dead_tuple_count BIGINT,    -- number of dead tuples
+    OUT dead_tuple_len BIGINT,        -- total dead tuples length in bytes
+    OUT dead_tuple_percent FLOAT8,    -- dead tuples in %
+    OUT free_space BIGINT,        -- free space in bytes
+    OUT free_percent FLOAT8,        -- free space in %
+    OUT all_visible_percent FLOAT8)        -- all visible blocks in %
+AS 'MODULE_PATHNAME', 'pgstattuple'
+LANGUAGE C STRICT;
+
+DROP FUNCTION pgstattuple(oid);
+CREATE OR REPLACE FUNCTION pgstattuple(IN reloid oid,
+    OUT table_len BIGINT,        -- physical table length in bytes
+    OUT tuple_count BIGINT,        -- number of live tuples
+    OUT tuple_len BIGINT,        -- total tuples length in bytes
+    OUT tuple_percent FLOAT8,        -- live tuples in %
+    OUT dead_tuple_count BIGINT,    -- number of dead tuples
+    OUT dead_tuple_len BIGINT,        -- total dead tuples length in bytes
+    OUT dead_tuple_percent FLOAT8,    -- dead tuples in %
+    OUT free_space BIGINT,        -- free space in bytes
+    OUT free_percent FLOAT8,        -- free space in %
+    OUT all_visible_percent FLOAT8)        -- all visible blocks in %
+AS 'MODULE_PATHNAME', 'pgstattuplebyid'
+LANGUAGE C STRICT;
diff --git a/contrib/pgstattuple/pgstattuple--1.1.sql b/contrib/pgstattuple/pgstattuple--1.1.sql
deleted file mode 100644
index b21fbf8..0000000
--- a/contrib/pgstattuple/pgstattuple--1.1.sql
+++ /dev/null
@@ -1,58 +0,0 @@
-/* contrib/pgstattuple/pgstattuple--1.1.sql */
-
--- complain if script is sourced in psql, rather than via CREATE EXTENSION
-\echo Use "CREATE EXTENSION pgstattuple" to load this file. \quit
-
-CREATE FUNCTION pgstattuple(IN relname text,
-    OUT table_len BIGINT,        -- physical table length in bytes
-    OUT tuple_count BIGINT,        -- number of live tuples
-    OUT tuple_len BIGINT,        -- total tuples length in bytes
-    OUT tuple_percent FLOAT8,        -- live tuples in %
-    OUT dead_tuple_count BIGINT,    -- number of dead tuples
-    OUT dead_tuple_len BIGINT,        -- total dead tuples length in bytes
-    OUT dead_tuple_percent FLOAT8,    -- dead tuples in %
-    OUT free_space BIGINT,        -- free space in bytes
-    OUT free_percent FLOAT8)        -- free space in %
-AS 'MODULE_PATHNAME', 'pgstattuple'
-LANGUAGE C STRICT;
-
-CREATE FUNCTION pgstattuple(IN reloid oid,
-    OUT table_len BIGINT,        -- physical table length in bytes
-    OUT tuple_count BIGINT,        -- number of live tuples
-    OUT tuple_len BIGINT,        -- total tuples length in bytes
-    OUT tuple_percent FLOAT8,        -- live tuples in %
-    OUT dead_tuple_count BIGINT,    -- number of dead tuples
-    OUT dead_tuple_len BIGINT,        -- total dead tuples length in bytes
-    OUT dead_tuple_percent FLOAT8,    -- dead tuples in %
-    OUT free_space BIGINT,        -- free space in bytes
-    OUT free_percent FLOAT8)        -- free space in %
-AS 'MODULE_PATHNAME', 'pgstattuplebyid'
-LANGUAGE C STRICT;
-
-CREATE FUNCTION pgstatindex(IN relname text,
-    OUT version INT,
-    OUT tree_level INT,
-    OUT index_size BIGINT,
-    OUT root_block_no BIGINT,
-    OUT internal_pages BIGINT,
-    OUT leaf_pages BIGINT,
-    OUT empty_pages BIGINT,
-    OUT deleted_pages BIGINT,
-    OUT avg_leaf_density FLOAT8,
-    OUT leaf_fragmentation FLOAT8)
-AS 'MODULE_PATHNAME', 'pgstatindex'
-LANGUAGE C STRICT;
-
-CREATE FUNCTION pg_relpages(IN relname text)
-RETURNS BIGINT
-AS 'MODULE_PATHNAME', 'pg_relpages'
-LANGUAGE C STRICT;
-
-/* New stuff in 1.1 begins here */
-
-CREATE FUNCTION pgstatginindex(IN relname regclass,
-    OUT version INT4,
-    OUT pending_pages INT4,
-    OUT pending_tuples BIGINT)
-AS 'MODULE_PATHNAME', 'pgstatginindex'
-LANGUAGE C STRICT;
diff --git a/contrib/pgstattuple/pgstattuple--1.2.sql b/contrib/pgstattuple/pgstattuple--1.2.sql
new file mode 100644
index 0000000..51fed69
--- /dev/null
+++ b/contrib/pgstattuple/pgstattuple--1.2.sql
@@ -0,0 +1,58 @@
+/* contrib/pgstattuple/pgstattuple--1.2.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION pgstattuple" to load this file. \quit
+
+CREATE FUNCTION pgstattuple(IN relname text,
+    OUT table_len BIGINT,        -- physical table length in bytes
+    OUT tuple_count BIGINT,        -- number of live tuples
+    OUT tuple_len BIGINT,        -- total tuples length in bytes
+    OUT tuple_percent FLOAT8,        -- live tuples in %
+    OUT dead_tuple_count BIGINT,    -- number of dead tuples
+    OUT dead_tuple_len BIGINT,        -- total dead tuples length in bytes
+    OUT dead_tuple_percent FLOAT8,    -- dead tuples in %
+    OUT free_space BIGINT,        -- free space in bytes
+    OUT free_percent FLOAT8,        -- free space in %
+    OUT all_visible_percent FLOAT8)        -- all visible blocks in %
+AS 'MODULE_PATHNAME', 'pgstattuple'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION pgstattuple(IN reloid oid,
+    OUT table_len BIGINT,        -- physical table length in bytes
+    OUT tuple_count BIGINT,        -- number of live tuples
+    OUT tuple_len BIGINT,        -- total tuples length in bytes
+    OUT tuple_percent FLOAT8,        -- live tuples in %
+    OUT dead_tuple_count BIGINT,    -- number of dead tuples
+    OUT dead_tuple_len BIGINT,        -- total dead tuples length in bytes
+    OUT dead_tuple_percent FLOAT8,    -- dead tuples in %
+    OUT free_space BIGINT,        -- free space in bytes
+    OUT free_percent FLOAT8,        -- free space in %
+    OUT all_visible_percent FLOAT8)        -- all visible blocks in %
+AS 'MODULE_PATHNAME', 'pgstattuplebyid'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION pgstatindex(IN relname text,
+    OUT version INT,
+    OUT tree_level INT,
+    OUT index_size BIGINT,
+    OUT root_block_no BIGINT,
+    OUT internal_pages BIGINT,
+    OUT leaf_pages BIGINT,
+    OUT empty_pages BIGINT,
+    OUT deleted_pages BIGINT,
+    OUT avg_leaf_density FLOAT8,
+    OUT leaf_fragmentation FLOAT8)
+AS 'MODULE_PATHNAME', 'pgstatindex'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION pg_relpages(IN relname text)
+RETURNS BIGINT
+AS 'MODULE_PATHNAME', 'pg_relpages'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION pgstatginindex(IN relname regclass,
+    OUT version INT4,
+    OUT pending_pages INT4,
+    OUT pending_tuples BIGINT)
+AS 'MODULE_PATHNAME', 'pgstatginindex'
+LANGUAGE C STRICT;
diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c
index 7f41ec3..1e5d7a5 100644
--- a/contrib/pgstattuple/pgstattuple.c
+++ b/contrib/pgstattuple/pgstattuple.c
@@ -35,6 +35,7 @@#include "storage/lmgr.h"#include "utils/builtins.h"#include "utils/tqual.h"
+#include "access/visibilitymap.h"PG_MODULE_MAGIC;
@@ -59,6 +60,7 @@ typedef struct pgstattuple_type    uint64        dead_tuple_count;    uint64        dead_tuple_len;
uint64        free_space;        /* free/reusable space in bytes */
 
+    double        all_visible_ratio;} pgstattuple_type;typedef void (*pgstat_page) (pgstattuple_type *, Relation,
BlockNumber,
@@ -88,7 +90,7 @@ static void pgstat_index_page(pgstattuple_type *stat, Page page,static
Datumbuild_pgstattuple_type(pgstattuple_type*stat, FunctionCallInfo fcinfo){
 
-#define NCOLUMNS    9
+#define NCOLUMNS    10#define NCHARS        32    HeapTuple    tuple;
@@ -97,7 +99,7 @@ build_pgstattuple_type(pgstattuple_type *stat, FunctionCallInfo fcinfo)    int            i;
double       tuple_percent;    double        dead_tuple_percent;
 
-    double        free_percent;    /* free/reusable space in % */
+    double        free_percent;        /* free/reusable space in % */    TupleDesc    tupdesc;    AttInMetadata
*attinmeta;
@@ -141,6 +143,7 @@ build_pgstattuple_type(pgstattuple_type *stat, FunctionCallInfo fcinfo)    snprintf(values[i++],
NCHARS,"%.2f", dead_tuple_percent);    snprintf(values[i++], NCHARS, INT64_FORMAT, stat->free_space);
snprintf(values[i++],NCHARS, "%.2f", free_percent);
 
+    snprintf(values[i++], NCHARS, "%.2f", stat->all_visible_ratio * 100.0);    /* build a tuple */    tuple =
BuildTupleFromCStrings(attinmeta,values);
 
@@ -275,7 +278,9 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo)    BlockNumber nblocks;    BlockNumber block =
0;       /* next block to count free space in */    BlockNumber tupblock;
 
+    BlockNumber all_visible_pages = 0;    Buffer        buffer;
+    Buffer        vmbuffer = InvalidBuffer;    pgstattuple_type stat = {0};    BufferAccessStrategy bstrategy;
@@ -341,6 +346,26 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo)        block++;    }
+    /*
+     * The only reason to check for visibilitymap here is the consistency of
+     * all_visible_pages against other stats.
+     */
+    for (block = 0 ; block < nblocks ; block++)
+    {
+        if (visibilitymap_test(rel, block, &vmbuffer))
+            all_visible_pages++;
+    }
+    if (vmbuffer != InvalidBuffer)
+    {
+        ReleaseBuffer(vmbuffer);
+        vmbuffer = InvalidBuffer;
+    }
+
+    if (nblocks > 0)
+        stat.all_visible_ratio = (double)all_visible_pages / nblocks;
+    else
+        stat.all_visible_ratio = 0.0;
+    relation_close(rel, AccessShareLock);    stat.table_len = (uint64) nblocks *BLCKSZ;
diff --git a/contrib/pgstattuple/pgstattuple.control b/contrib/pgstattuple/pgstattuple.control
index fcfd36f..a7cf47f 100644
--- a/contrib/pgstattuple/pgstattuple.control
+++ b/contrib/pgstattuple/pgstattuple.control
@@ -1,5 +1,5 @@# pgstattuple extensioncomment = 'show tuple-level statistics'
-default_version = '1.1'
+default_version = '1.2'module_pathname = '$libdir/pgstattuple'relocatable = true

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Dimitri Fontaine
Дата:
Сообщение: Re: Review: extension template
Следующее
От: Peter Eisentraut
Дата:
Сообщение: Re: [PATCH] Add session_preload_libraries configuration parameter