To: Dirk Lutzebaeck <lutzeb@aeccom.com>
cc: pgsql-bugs@postgreSQL.org
Subject: Re: [BUGS] vacuum analyze corrupts db with larger tuples (< 8k) 
In-reply-to: <13309.947002358@sss.pgh.pa.us> 
References: <14449.58495.638146.353607@ampato.aeccom.com> <13309.947002358@sss.pgh.pa.us>
Comments: In-reply-to Tom Lane <tgl@sss.pgh.pa.us>
	message dated "Tue, 04 Jan 2000 11:12:38 -0500"
Date: Tue, 04 Jan 2000 12:30:54 -0500
Message-ID: <13859.947007054@sss.pgh.pa.us>
From: Tom Lane <tgl@sss.pgh.pa.us>
Sender: owner-bugs@postgreSQL.org
Precedence: bulk

I wrote:
> Ohhh ... I know what's going on.  The oversize tuple is the one that
> VACUUM is attempting to store in pg_statistic, containing the min and
> max values for your varchar column.  In this example, both the min and
> max are just shy of 5K characters, so the pg_statistic tuple is too
> big to fit on a page.

I have applied the attached patch to the REL6_5 branch.  (There is
already similar code in the current branch.)  I'm afraid it won't
help you recover from an already-corrupted pg_statistic table, though.

			regards, tom lane

*** src/backend/commands/vacuum.c.orig	Wed Aug 25 08:01:45 1999
--- src/backend/commands/vacuum.c	Tue Jan  4 12:15:17 2000
***************
*** 2405,2414 ****
  					stup = heap_formtuple(sd->rd_att, values, nulls);
  
  					/* ----------------
! 					 *	insert the tuple in the relation and get the tuple's oid.
  					 * ----------------
  					 */
! 					heap_insert(sd, stup);
  					pfree(DatumGetPointer(values[3]));
  					pfree(DatumGetPointer(values[4]));
  					pfree(stup);
--- 2405,2425 ----
  					stup = heap_formtuple(sd->rd_att, values, nulls);
  
  					/* ----------------
! 					 *	Watch out for oversize tuple, which can happen if
! 					 *	both of the saved data values are long.
! 					 *	Our fallback strategy is just to not store the
! 					 *	pg_statistic tuple at all in that case.  (We could
! 					 *	replace the values by NULLs and still store the
! 					 *	numeric stats, but presently selfuncs.c couldn't
! 					 *	do anything useful with that case anyway.)
  					 * ----------------
  					 */
! 					if (MAXALIGN(stup->t_len) <= MaxTupleSize)
! 					{
! 						/* OK to store tuple */
! 						heap_insert(sd, stup);
! 					}
! 
  					pfree(DatumGetPointer(values[3]));
  					pfree(DatumGetPointer(values[4]));
  					pfree(stup);

************
