From ea4b9f14f3a5e4edb0120bae412de505a36a06b6 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Mon, 1 Dec 2003 23:19:33 +0000
Subject: [PATCH] I've run across a pretty serious problem with pg_autovacuum.
 pg_autovacuum looses track of any table that's ever been truncated (possibly
 other situations too).   When i truncate a table it gets a new relfilenode in
 pg_class.  This is a problem because pg_autovacuum assumes
 pg_class.relfilenode will join to pg_stats_all_tables.relid.
 pg_stats_all_tables.relid is actallly the oid from pg_class, not the
 relfilenode.   These two values start out equal so pg_autovacuum works
 initially, but it fails later on because of this incorrect assumption.

This patch fixes that problem.  Applied to HEAD and 7.4.X.

Brian Hirt
---
 contrib/pg_autovacuum/pg_autovacuum.c | 12 ++++++------
 contrib/pg_autovacuum/pg_autovacuum.h |  6 +++---
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/contrib/pg_autovacuum/pg_autovacuum.c b/contrib/pg_autovacuum/pg_autovacuum.c
index f4e11744347..00ccdc68bb8 100644
--- a/contrib/pg_autovacuum/pg_autovacuum.c
+++ b/contrib/pg_autovacuum/pg_autovacuum.c
@@ -116,7 +116,7 @@ init_table_info(PGresult *res, int row, db_info * dbi)
 		 atol(PQgetvalue(res, row, PQfnumber(res, "n_tup_upd"))));
 	new_tbl->curr_vacuum_count = new_tbl->CountAtLastVacuum;
 
-	new_tbl->relfilenode = atoi(PQgetvalue(res, row, PQfnumber(res, "relfilenode")));
+	new_tbl->relid = atoi(PQgetvalue(res, row, PQfnumber(res, "oid")));
 	new_tbl->reltuples = atoi(PQgetvalue(res, row, PQfnumber(res, "reltuples")));
 	new_tbl->relpages = atoi(PQgetvalue(res, row, PQfnumber(res, "relpages")));
 
@@ -154,7 +154,7 @@ update_table_thresholds(db_info * dbi, tbl_info * tbl, int vacuum_type)
 
 	if (dbi->conn != NULL)
 	{
-		snprintf(query, sizeof(query), PAGES_QUERY, tbl->relfilenode);
+		snprintf(query, sizeof(query), PAGES_QUERY, tbl->relid);
 		res = send_query(query, dbi);
 		if (res != NULL)
 		{
@@ -237,7 +237,7 @@ update_table_list(db_info * dbi)
 			for (i = 0; i < t; i++)
 			{					/* loop through result set looking for a
 								 * match */
-				if (tbl->relfilenode == atoi(PQgetvalue(res, i, PQfnumber(res, "relfilenode"))))
+				if (tbl->relid == atoi(PQgetvalue(res, i, PQfnumber(res, "oid"))))
 				{
 					found_match = 1;
 					break;
@@ -267,7 +267,7 @@ update_table_list(db_info * dbi)
 			while (tbl_elem != NULL)
 			{
 				tbl = ((tbl_info *) DLE_VAL(tbl_elem));
-				if (tbl->relfilenode == atoi(PQgetvalue(res, i, PQfnumber(res, "relfilenode"))))
+				if (tbl->relid == atoi(PQgetvalue(res, i, PQfnumber(res, "oid"))))
 				{
 					found_match = 1;
 					break;
@@ -361,7 +361,7 @@ print_table_info(tbl_info * tbl)
 {
 	sprintf(logbuffer, "  table name:     %s.%s", tbl->dbi->dbname, tbl->table_name);
 	log_entry(logbuffer);
-	sprintf(logbuffer, "     relfilenode: %i;   relisshared: %i", tbl->relfilenode, tbl->relisshared);
+	sprintf(logbuffer, "     relid: %i;   relisshared: %i", tbl->relid, tbl->relisshared);
 	log_entry(logbuffer);
 	sprintf(logbuffer, "     reltuples: %i;  relpages: %i", tbl->reltuples, tbl->relpages);
 	log_entry(logbuffer);
@@ -1072,7 +1072,7 @@ main(int argc, char *argv[])
 						{		/* Loop through tables in list */
 							tbl = ((tbl_info *) DLE_VAL(tbl_elem));		/* set tbl_info =
 																		 * current_table */
-							if (tbl->relfilenode == atoi(PQgetvalue(res, j, PQfnumber(res, "relfilenode"))))
+							if (tbl->relid == atoi(PQgetvalue(res, j, PQfnumber(res, "oid"))))
 							{
 								tbl->curr_analyze_count =
 									(atol(PQgetvalue(res, j, PQfnumber(res, "n_tup_ins"))) +
diff --git a/contrib/pg_autovacuum/pg_autovacuum.h b/contrib/pg_autovacuum/pg_autovacuum.h
index 5e8cf158bb2..308ebdf7ffd 100644
--- a/contrib/pg_autovacuum/pg_autovacuum.h
+++ b/contrib/pg_autovacuum/pg_autovacuum.h
@@ -34,10 +34,10 @@
 #define VACUUM_ANALYZE		0
 #define ANALYZE_ONLY		1
 
-#define TABLE_STATS_QUERY	"select a.relfilenode,a.relname,a.relnamespace,a.relpages,a.relisshared,a.reltuples,b.schemaname,b.n_tup_ins,b.n_tup_upd,b.n_tup_del from pg_class a, pg_stat_all_tables b where a.relfilenode=b.relid and a.relkind = 'r'"
+#define TABLE_STATS_QUERY	"select a.oid,a.relname,a.relnamespace,a.relpages,a.relisshared,a.reltuples,b.schemaname,b.n_tup_ins,b.n_tup_upd,b.n_tup_del from pg_class a, pg_stat_all_tables b where a.oid=b.relid and a.relkind = 'r'"
 
 #define FRONTEND
-#define PAGES_QUERY "select relfilenode,reltuples,relpages from pg_class where relfilenode=%i"
+#define PAGES_QUERY "select oid,reltuples,relpages from pg_class where oid=%i"
 #define FROZENOID_QUERY "select oid,age(datfrozenxid) from pg_database where datname = 'template1'"
 #define FROZENOID_QUERY2 "select oid,datname,age(datfrozenxid) from pg_database where datname!='template0'"
 
@@ -84,7 +84,7 @@ struct tableinfo
 {
 	char	   *schema_name,
 			   *table_name;
-	int			relfilenode,
+	int			relid,
 				reltuples,
 				relisshared,
 				relpages;
-- 
GitLab