Bug in pg_autovacuum ?

Started by Cott Langalmost 22 years ago8 messages
#1Cott Lang
cott@internetstaff.com

I'm having a problem with pg_autovacuum against both 7.3.2 and 7.4.1 on
Redhat 9 and Fedora Core 1. I'm using pg_autovacuum from 7.4.1,
everything comes from the postgresql.org RPMs.

If the number of tuples is sufficiently high, pg reports 'reltuples'
back in TABLE_STATS_QUERY in scientific notation instead of an integer.

Example:

4.35351e+06 instead of 4353514

pg_autovacuum then uses atoi() to reach the incorrect conclusion that
there are 4 tuples. Obviously, if that table gets more than a couple of
updates, it gets vacuumed a bit too often. :)

Changing from atoi() to atof() solves the problem completely.

new_tbl->reltuples =
atof(PQgetvalue(res, row, PQfnumber(res, "reltuples")));

new_tbl->relpages =
atof(PQgetvalue(res, row, PQfnumber(res, "relpages")));

I'm not sure how I can be the only person running into this. :)

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Cott Lang (#1)
Re: Bug in pg_autovacuum ?

Cott Lang <cott@internetstaff.com> writes:

If the number of tuples is sufficiently high, pg reports 'reltuples'
back in TABLE_STATS_QUERY in scientific notation instead of an integer.

Right, because that column is actually a float4.

Changing from atoi() to atof() solves the problem completely.

new_tbl->reltuples =
atof(PQgetvalue(res, row, PQfnumber(res, "reltuples")));

new_tbl->relpages =
atof(PQgetvalue(res, row, PQfnumber(res, "relpages")));

I should think this would break in different ways once reltuples exceeds
INT_MAX. A full fix would require changing new_tbl->reltuples to be
float or double, and coping with any downstream changes that implies.

Also, relpages *is* an integer, though it's best interpreted as an
unsigned one. (Ditto for relid.) Looks like this code is 0-for-3 on
getting the datatypes right :-(

regards, tom lane

#3Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Tom Lane (#2)
Re: [BUGS] Bug in pg_autovacuum ?

Would someone review these problems and submit a patch? Thanks.

---------------------------------------------------------------------------

Tom Lane wrote:

Cott Lang <cott@internetstaff.com> writes:

If the number of tuples is sufficiently high, pg reports 'reltuples'
back in TABLE_STATS_QUERY in scientific notation instead of an integer.

Right, because that column is actually a float4.

Changing from atoi() to atof() solves the problem completely.

new_tbl->reltuples =
atof(PQgetvalue(res, row, PQfnumber(res, "reltuples")));

new_tbl->relpages =
atof(PQgetvalue(res, row, PQfnumber(res, "relpages")));

I should think this would break in different ways once reltuples exceeds
INT_MAX. A full fix would require changing new_tbl->reltuples to be
float or double, and coping with any downstream changes that implies.

Also, relpages *is* an integer, though it's best interpreted as an
unsigned one. (Ditto for relid.) Looks like this code is 0-for-3 on
getting the datatypes right :-(

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
#4Matthew T. O'Connor
matthew@zeut.net
In reply to: Bruce Momjian (#3)
Re: [BUGS] Bug in pg_autovacuum ?

Yeah, I'll take a look at it and submit a patch. Sorry I didn't see it
sooner, but I don't read the bugs mailing list.

Show quoted text

On Wed, 2004-02-11 at 17:29, Bruce Momjian wrote:

Would someone review these problems and submit a patch? Thanks.

---------------------------------------------------------------------------

Tom Lane wrote:

Cott Lang <cott@internetstaff.com> writes:

If the number of tuples is sufficiently high, pg reports 'reltuples'
back in TABLE_STATS_QUERY in scientific notation instead of an integer.

Right, because that column is actually a float4.

Changing from atoi() to atof() solves the problem completely.

new_tbl->reltuples =
atof(PQgetvalue(res, row, PQfnumber(res, "reltuples")));

new_tbl->relpages =
atof(PQgetvalue(res, row, PQfnumber(res, "relpages")));

I should think this would break in different ways once reltuples exceeds
INT_MAX. A full fix would require changing new_tbl->reltuples to be
float or double, and coping with any downstream changes that implies.

Also, relpages *is* an integer, though it's best interpreted as an
unsigned one. (Ditto for relid.) Looks like this code is 0-for-3 on
getting the datatypes right :-(

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

#5Cott Lang
cott@internetstaff.com
In reply to: Matthew T. O'Connor (#4)
Re: [BUGS] Bug in pg_autovacuum ?

I have my original changes + Tom's recommended changes applied to 7.4.1
if you're interested.

Show quoted text

On Wed, 2004-02-11 at 15:57, Matthew T. O'Connor wrote:

Yeah, I'll take a look at it and submit a patch. Sorry I didn't see it
sooner, but I don't read the bugs mailing list.

On Wed, 2004-02-11 at 17:29, Bruce Momjian wrote:

Would someone review these problems and submit a patch? Thanks.

---------------------------------------------------------------------------

Tom Lane wrote:

Cott Lang <cott@internetstaff.com> writes:

If the number of tuples is sufficiently high, pg reports 'reltuples'
back in TABLE_STATS_QUERY in scientific notation instead of an integer.

Right, because that column is actually a float4.

Changing from atoi() to atof() solves the problem completely.

new_tbl->reltuples =
atof(PQgetvalue(res, row, PQfnumber(res, "reltuples")));

new_tbl->relpages =
atof(PQgetvalue(res, row, PQfnumber(res, "relpages")));

I should think this would break in different ways once reltuples exceeds
INT_MAX. A full fix would require changing new_tbl->reltuples to be
float or double, and coping with any downstream changes that implies.

Also, relpages *is* an integer, though it's best interpreted as an
unsigned one. (Ditto for relid.) Looks like this code is 0-for-3 on
getting the datatypes right :-(

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

#6Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Cott Lang (#5)
Re: [BUGS] Bug in pg_autovacuum ?

Cott Lang wrote:

I have my original changes + Tom's recommended changes applied to 7.4.1
if you're interested.

Sure, shoot them over to hackers or patches. The pg_autovacuum author
is looking into this.

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
#7Cott Lang
cott@internetstaff.com
In reply to: Bruce Momjian (#6)
1 attachment(s)
Re: [BUGS] Bug in pg_autovacuum ?

On Wed, 2004-02-11 at 16:25, Bruce Momjian wrote:

Sure, shoot them over to hackers or patches. The pg_autovacuum author
is looking into this.

Here they are. They've worked well for me, but someone wiser in the ways
of C should certainly look them over. :)

Attachments:

autovac.patchtext/x-patch; charset=; name=autovac.patchDownload
? autovac.patch
? pg_autovacuum
Index: pg_autovacuum.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/contrib/pg_autovacuum/pg_autovacuum.c,v
retrieving revision 1.13
diff -u -r1.13 pg_autovacuum.c
--- pg_autovacuum.c	8 Dec 2003 21:54:00 -0000	1.13
+++ pg_autovacuum.c	12 Feb 2004 00:25:57 -0000
@@ -118,7 +118,7 @@
 	new_tbl->curr_vacuum_count = new_tbl->CountAtLastVacuum;
 
 	new_tbl->relid = atoi(PQgetvalue(res, row, PQfnumber(res, "oid")));
-	new_tbl->reltuples = atoi(PQgetvalue(res, row, PQfnumber(res, "reltuples")));
+	new_tbl->reltuples = atof(PQgetvalue(res, row, PQfnumber(res, "reltuples")));
 	new_tbl->relpages = atoi(PQgetvalue(res, row, PQfnumber(res, "relpages")));
 
 	if (strcmp("t", PQgetvalue(res, row, PQfnumber(res, "relisshared"))))
@@ -159,7 +159,7 @@
 		if (res != NULL)
 		{
 			tbl->reltuples =
-				atoi(PQgetvalue(res, 0, PQfnumber(res, "reltuples")));
+				atof(PQgetvalue(res, 0, PQfnumber(res, "reltuples")));
 			tbl->relpages = atoi(PQgetvalue(res, 0, PQfnumber(res, "relpages")));
 
 			/*
@@ -363,7 +363,7 @@
 	log_entry(logbuffer);
 	sprintf(logbuffer, "     relid: %i;   relisshared: %i", tbl->relid, tbl->relisshared);
 	log_entry(logbuffer);
-	sprintf(logbuffer, "     reltuples: %i;  relpages: %i", tbl->reltuples, tbl->relpages);
+	sprintf(logbuffer, "     reltuples: %.0f;  relpages: %i", tbl->reltuples, tbl->relpages);
 	log_entry(logbuffer);
 	sprintf(logbuffer, "     curr_analyze_count:  %li; cur_delete_count:   %li",
 			tbl->curr_analyze_count, tbl->curr_vacuum_count);
Index: pg_autovacuum.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/contrib/pg_autovacuum/pg_autovacuum.h,v
retrieving revision 1.8
diff -u -r1.8 pg_autovacuum.h
--- pg_autovacuum.h	1 Dec 2003 23:19:33 -0000	1.8
+++ pg_autovacuum.h	12 Feb 2004 00:25:57 -0000
@@ -84,10 +84,12 @@
 {
 	char	   *schema_name,
 			   *table_name;
-	int			relid,
-				reltuples,
-				relisshared,
-				relpages;
+	unsigned int	relid,
+			relpages;
+
+	int		relisshared;
+	double		reltuples;
+
 	long		analyze_threshold,
 				vacuum_threshold;
 	long		CountAtLastAnalyze;		/* equal to: inserts + updates as
#8Bruce Momjian
pgman@candle.pha.pa.us
In reply to: Cott Lang (#7)
Re: [BUGS] Bug in pg_autovacuum ?

Not sure if anyone reported to you but we fixed these in current CVS and
will have the fix in 7.4.3.

---------------------------------------------------------------------------

Cott Lang wrote:

On Wed, 2004-02-11 at 16:25, Bruce Momjian wrote:

Sure, shoot them over to hackers or patches. The pg_autovacuum author
is looking into this.

Here they are. They've worked well for me, but someone wiser in the ways
of C should certainly look them over. :)

[ Attachment, skipping... ]

---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?

http://archives.postgresql.org

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073