Re: [GENERAL] Mismatched pg_class.reltuples between table and primary key

2013-12-02 Thread bricklen
Hi Alvaro,

Thanks for the link.

On Mon, Dec 2, 2013 at 4:35 PM, Alvaro Herrera wrote:

> bricklen escribió:
> > We recently experienced a hard crash of a dev server due to lack of
> > resources (we think, still investigating).
> > That resulted in an interesting scenario where one of the tables was
> > returning 12 rows from "select * from tbl", but "select * from tbl order
> by
> > " was only returning 11.
> > Looking at pg_class.reltuples, it could be clearly seen that the table in
> > question had a value of 12, but the primary key had only 11.
>
> This sounds very similar to what was reported in
>
> http://www.postgresql.org/message-id/20131126123244.gi23...@alap2.anarazel.de
>
> In short, you probably want to make sure to upgrade to this week's
> release.
>

If it is indeed the same issue (and I see something similar in an actual
production system running 9.2.5 which was recovered from a crashed LVM just
the other day), are the chances of data corruption particularly high? From
reading over that linked thread, it looked like the problem was likely to
stem from wraparound.

Once the patch is applied, will the existing data still be vulnerable? I
haven't been paying close attention to that particular thread, so I might
have missed a few things regarding the fixes -- will a full dump + reload
be necessary?

Thanks,

Bricklen


Re: [GENERAL] Mismatched pg_class.reltuples between table and primary key

2013-12-02 Thread Alvaro Herrera
bricklen escribió:
> We recently experienced a hard crash of a dev server due to lack of
> resources (we think, still investigating).
> That resulted in an interesting scenario where one of the tables was
> returning 12 rows from "select * from tbl", but "select * from tbl order by
> " was only returning 11.
> Looking at pg_class.reltuples, it could be clearly seen that the table in
> question had a value of 12, but the primary key had only 11.

This sounds very similar to what was reported in 
http://www.postgresql.org/message-id/20131126123244.gi23...@alap2.anarazel.de

In short, you probably want to make sure to upgrade to this week's
release.

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services


-- 
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] Mismatched pg_class.reltuples between table and primary key

2013-12-02 Thread Tom Lane
bricklen  writes:
> We recently experienced a hard crash of a dev server due to lack of
> resources (we think, still investigating).
> That resulted in an interesting scenario where one of the tables was
> returning 12 rows from "select * from tbl", but "select * from tbl order by
> " was only returning 11.
> Looking at pg_class.reltuples, it could be clearly seen that the table in
> question had a value of 12, but the primary key had only 11.

> My system catalog ignorance is probably showing, but I assumed that the
> table and PK pg_class.reltuples values should always be the same?

I wouldn't assume that --- they're only approximations, anyway.
In particular there's some moving-average behavior in there that might
prevent small errors in the value from ever going away completely.

> The initial observations were made by a developer:
> 1). After an ANALYZE, PK reltuples remained at 11.
> 2). After REINDEX, PK reltuples was still 11.
> 3). After VACUUM FULL, PK reltuples was reset to 12.

(2) is a bit surprising, but I'm not sure that REINDEX recomputes the
reltuples value for the index.

regards, tom lane


-- 
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[GENERAL] Mismatched pg_class.reltuples between table and primary key

2013-12-02 Thread bricklen
We recently experienced a hard crash of a dev server due to lack of
resources (we think, still investigating).
That resulted in an interesting scenario where one of the tables was
returning 12 rows from "select * from tbl", but "select * from tbl order by
" was only returning 11.
Looking at pg_class.reltuples, it could be clearly seen that the table in
question had a value of 12, but the primary key had only 11.

My system catalog ignorance is probably showing, but I assumed that the
table and PK pg_class.reltuples values should always be the same?

The initial observations were made by a developer:
1). After an ANALYZE, PK reltuples remained at 11.
2). After REINDEX, PK reltuples was still 11.
3). After VACUUM FULL, PK reltuples was reset to 12.

The db was quiescent at this point (rows were not being added or removed).

I would chalk this up to a localized index corruption issue, but earlier
today I observed the same thing on a different table which did not
originally show a difference between the table and PK reltuples values.
This is following a VACUUM FREEZE, and an ANALYZE run, as well as at least
two restarts of the db cluster since the initial failure.

Can anyone suggest whether this is an index corruption issue, or maybe a
misunderstanding on my part about what the reltuples attribute means? Or
perhaps it is something else?


PostgreSQL 9.3.1 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.1.2
20080704 (Red Hat 4.1.2-54), 64-bit
default_statistics_target = 200


Here is a query I hacked together to raise a WARNING if the reltuples value
of a table was different than the associated primary key or unique key. I
visually ignored any values that were above the default_statistics_target
value, to factor out sample size issues.

DO
$$
DECLARE
rec RECORD;
BEGIN
FOR rec IN
SELECT  n.nspname schemaname,
c.relname as tablename,
c.reltuples::NUMERIC as tbl_tuples,
i.relname as idx_name,
i.reltuples::NUMERIC as idx_tuples
FROM pg_index x
JOIN pg_class c ON c.oid = x.indrelid
JOIN pg_class i ON i.oid = x.indexrelid
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'::"char"
AND i.relkind = 'i'::"char"
AND n.nspname NOT IN ('pg_catalog','information_schema')
AND (x.indisunique IS TRUE OR x.indisprimary IS TRUE)
ORDER BY 1,2,4
LOOP
IF ( rec.idx_name IS NOT NULL
 AND rec.tbl_tuples IS DISTINCT FROM rec.idx_tuples ) THEN
RAISE WARNING 'Mismatched tuple counts - Table %, tuples: %,
unique key: %, tuples: %',
rec.schemaname||'.'||rec.tablename, rec.tbl_tuples,
rec.idx_name, rec.idx_tuples;
END IF;
END LOOP;
END
$$;