Thread: pg_buffercache causes assertion failure

pg_buffercache causes assertion failure

From
Michael Fuhr
Date:
I'm not sure when this broke, but using contrib/pg_buffercache with
the latest HEAD causes an assertion failure:

test=# SELECT * FROM pg_buffercache;
server closed the connection unexpectedly       This probably means the server terminated abnormally       before or
whileprocessing the request.
 
The connection to the server was lost. Attempting reset: Failed.

Here are the log entries:

TRAP: FailedAssertion("!(var->vartypmod == att_tup->atttypmod)", File: "execScan.c", Line: 220)
<2005-05-29 09:14:54 MDT 11356> LOG:  server process (PID 17300) was terminated by signal 6
<2005-05-29 09:14:54 MDT 11356> LOG:  terminating any other active server processes

-- 
Michael Fuhr
http://www.fuhr.org/~mfuhr/


Re: pg_buffercache causes assertion failure

From
Tom Lane
Date:
Michael Fuhr <mike@fuhr.org> writes:
> I'm not sure when this broke, but using contrib/pg_buffercache with
> the latest HEAD causes an assertion failure:

> test=# SELECT * FROM pg_buffercache;
> server closed the connection unexpectedly

Fixed; turns out to be an ancient parse-analysis bug that was causing
the view definition to not agree with the function definition if the
function definition included a nondefault typmod.

I wonder though why this contrib module is defining its output as
numeric(10) --- seems like a pretty inefficient choice compared to,
say, int8; or even int4 which is what the pg_locks view is using.

And it's arguably a wrong specification anyway, since the code is doing
nothing to enforce that precision.

Should tupledesc_match() in nodeFunctionscan.c be enforcing equality
of typmods?
        regards, tom lane


Re: pg_buffercache causes assertion failure

From
Mark Kirkwood
Date:
Tom Lane wrote:
>
> Fixed; turns out to be an ancient parse-analysis bug that was causing
> the view definition to not agree with the function definition if the
> function definition included a nondefault typmod.
> 
> I wonder though why this contrib module is defining its output as
> numeric(10) --- seems like a pretty inefficient choice compared to,
> say, int8; or even int4 which is what the pg_locks view is using.
> 

I couldn't use int4 as the underlying datatype is unsigned int (not 
available as exposed Pg type). However, using int8 sounds promising (is 
int8 larger than unsigned int on 64-bit platforms?).

> And it's arguably a wrong specification anyway, since the code is doing
> nothing to enforce that precision.

Hmmm - that's right, not sure why I did that :-( just using numeric in 
the view might have been more sensible.

cheers

Mark


Re: pg_buffercache causes assertion failure

From
Mark Kirkwood
Date:
Mark Kirkwood wrote:

> 
> I couldn't use int4 as the underlying datatype is unsigned int (not 
> available as exposed Pg type). However, using int8 sounds promising (is 
> int8 larger than unsigned int on 64-bit platforms?).

Blocknumber is defined as uint32 in block.h - so should always be safe 
to represent as an int8 I am thinking.

I will look at patching pg_buffercache, changing numeric -> int8 for the 
relblocknumber column. This seems a tidier solution than using numeric, 
and loses the numeric overhead.

regards

Mark


Re: pg_buffercache causes assertion failure

From
Mark Kirkwood
Date:
Mark Kirkwood wrote:
> Mark Kirkwood wrote:
>
>>
>> I couldn't use int4 as the underlying datatype is unsigned int (not
>> available as exposed Pg type). However, using int8 sounds promising
>> (is int8 larger than unsigned int on 64-bit platforms?).
>
>
> Blocknumber is defined as uint32 in block.h - so should always be safe
> to represent as an int8 I am thinking.
>
> I will look at patching pg_buffercache, changing numeric -> int8 for the
> relblocknumber column. This seems a tidier solution than using numeric,
> and loses the numeric overhead.

This patch changes the use of numeric to int8 to represent the
relblocknumber column.

regards

Mark

diff -Ncar pgsql.orig/contrib/pg_buffercache/README.pg_buffercache pgsql/contrib/pg_buffercache/README.pg_buffercache
*** pgsql.orig/contrib/pg_buffercache/README.pg_buffercache    Tue May 31 11:02:41 2005
--- pgsql/contrib/pg_buffercache/README.pg_buffercache    Tue May 31 11:05:48 2005
***************
*** 66,78 ****
     relfilenode    | oid     |
     reltablespace  | oid     |
     reldatabase    | oid     |
!    relblocknumber | numeric |
     isdirty        | boolean |
    View definition:
     SELECT p.bufferid, p.relfilenode, p.reltablespace, p.reldatabase,
            p.relblocknumber, p.isdirty
       FROM pg_buffercache_pages() p(bufferid integer, relfilenode oid,
!      reltablespace oid, reldatabase oid, relblocknumber numeric(10,0),
       isdirty boolean);

    regression=# SELECT c.relname, count(*) AS buffers
--- 66,78 ----
     relfilenode    | oid     |
     reltablespace  | oid     |
     reldatabase    | oid     |
!    relblocknumber | bigint  |
     isdirty        | boolean |
    View definition:
     SELECT p.bufferid, p.relfilenode, p.reltablespace, p.reldatabase,
            p.relblocknumber, p.isdirty
       FROM pg_buffercache_pages() p(bufferid integer, relfilenode oid,
!      reltablespace oid, reldatabase oid, relblocknumber bigint,
       isdirty boolean);

    regression=# SELECT c.relname, count(*) AS buffers
diff -Ncar pgsql.orig/contrib/pg_buffercache/pg_buffercache.sql.in pgsql/contrib/pg_buffercache/pg_buffercache.sql.in
*** pgsql.orig/contrib/pg_buffercache/pg_buffercache.sql.in    Tue May 31 11:02:41 2005
--- pgsql/contrib/pg_buffercache/pg_buffercache.sql.in    Tue May 31 09:15:03 2005
***************
*** 11,17 ****
  CREATE VIEW pg_buffercache AS
      SELECT P.* FROM pg_buffercache_pages() AS P
       (bufferid integer, relfilenode oid, reltablespace oid, reldatabase oid,
!       relblocknumber numeric(10), isdirty bool);

  -- Don't want these to be available at public.
  REVOKE ALL ON FUNCTION pg_buffercache_pages() FROM PUBLIC;
--- 11,17 ----
  CREATE VIEW pg_buffercache AS
      SELECT P.* FROM pg_buffercache_pages() AS P
       (bufferid integer, relfilenode oid, reltablespace oid, reldatabase oid,
!       relblocknumber int8, isdirty bool);

  -- Don't want these to be available at public.
  REVOKE ALL ON FUNCTION pg_buffercache_pages() FROM PUBLIC;
diff -Ncar pgsql.orig/contrib/pg_buffercache/pg_buffercache_pages.c pgsql/contrib/pg_buffercache/pg_buffercache_pages.c
*** pgsql.orig/contrib/pg_buffercache/pg_buffercache_pages.c    Tue May 31 11:02:41 2005
--- pgsql/contrib/pg_buffercache/pg_buffercache_pages.c    Tue May 31 11:23:46 2005
***************
*** 93,99 ****
          TupleDescInitEntry(tupledesc, (AttrNumber) 4, "reldatabase",
                                      OIDOID, -1, 0);
          TupleDescInitEntry(tupledesc, (AttrNumber) 5, "relblockbumber",
!                                     NUMERICOID, -1, 0);
          TupleDescInitEntry(tupledesc, (AttrNumber) 6, "isdirty",
                                      BOOLOID, -1, 0);

--- 93,99 ----
          TupleDescInitEntry(tupledesc, (AttrNumber) 4, "reldatabase",
                                      OIDOID, -1, 0);
          TupleDescInitEntry(tupledesc, (AttrNumber) 5, "relblockbumber",
!                                     INT8OID, -1, 0);
          TupleDescInitEntry(tupledesc, (AttrNumber) 6, "isdirty",
                                      BOOLOID, -1, 0);