CVS User Account cvsuser
Wed Mar 8 10:29:13 PST 2006
Log Message:
-----------
Multi purpose commit, though 1 was needed for the other.
A) Clean up version detection, we can now test against patch levels as well.
B) With the introduction of autovacuum into the PG backend, we need better autodetection than relying on vac_freq being 0.  We now check to see if auto vac is enabled in version 8.1 and newer.  If it is we check the pg_autovacuum in the pg_catalog schema to see if our internal tables are disabled, if they are we vacuum them, otherwise we leave it upto the autovacuum process to deal with.

Modified Files:
--------------
    slony1-engine/src/slon:
        cleanup_thread.c (r1.31 -> r1.32)
        dbutils.c (r1.19 -> r1.20)
        slon.c (r1.63 -> r1.64)
        slon.h (r1.58 -> r1.59)
    slony1-engine/src/slonik:
        dbutil.c (r1.9 -> r1.10)
        slonik.c (r1.57 -> r1.58)
        slonik.h (r1.26 -> r1.27)

-------------- next part --------------
Index: dbutils.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/dbutils.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -Lsrc/slon/dbutils.c -Lsrc/slon/dbutils.c -u -w -r1.19 -r1.20
--- src/slon/dbutils.c
+++ src/slon/dbutils.c
@@ -30,6 +30,7 @@
 
 
 static int	slon_appendquery_int(SlonDString * dsp, char *fmt, va_list ap);
+static int	db_get_version(PGconn *conn);
 
 #if (PG_VERSION_MAJOR < 8)
 /* ----
@@ -105,6 +106,17 @@
 	 */
 	conn = slon_make_dummyconn(symname);
 	conn->dbconn = dbconn;
+	conn->pg_version = db_get_version(dbconn);
+        if (conn->pg_version < 70303)
+        {
+                slon_log(SLON_ERROR,
+                        "slon_connectdb: PQconnectdb(\"%s\") PostgreSQL version not supported\n",
+                        conninfo);
+                PQfinish(dbconn);
+                return NULL;
+        }
+        slon_log(SLON_DEBUG4,
+                "version for \"%s\" is %d\n", conninfo, conn->pg_version);
 
 	return conn;
 }
@@ -461,6 +473,37 @@
 	return 0;
 }
 
+static int db_get_version(PGconn *conn)
+{
+	PGresult    *res;
+	SlonDString query;
+	char	    versionstr[7];
+	int	    version=0;
+	int	    major=0;
+	int	    minor=0;
+	int	    patch=0;
+
+	dstring_init(&query);
+	slon_mkquery(&query, "SELECT version();");
+	res = PQexec(conn, dstring_data(&query));
+
+	if ( !res || PQresultStatus(res) != PGRES_TUPLES_OK )
+        {
+		PQclear(res);
+		return -1;
+	}
+	if (sscanf(PQgetvalue(res, 0, 0), "PostgreSQL %d.%d.%d", &major, &minor, &patch) < 2)
+	{
+		PQclear(res);
+		return -1;
+	}
+	PQclear(res);
+	snprintf(versionstr, 7, "%.2d%.2d%.2d", major, minor, patch);
+	version=atoi(versionstr);
+
+	return version;
+}
+	
 /*
  * Local Variables:
  *	tab-width: 4
Index: slon.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/slon.c,v
retrieving revision 1.63
retrieving revision 1.64
diff -Lsrc/slon/slon.c -Lsrc/slon/slon.c -u -w -r1.63 -r1.64
--- src/slon/slon.c
+++ src/slon/slon.c
@@ -91,6 +91,7 @@
 	fprintf(stderr, "usage: %s [options] clustername conninfo\n", argv[0]);
 	fprintf(stderr, "\n");
 	fprintf(stderr, "Options:\n");
+
 	fprintf(stderr, "    -d <debuglevel>       verbosity of logging (1..4)\n");
 	fprintf(stderr, "    -s <milliseconds>     SYNC check interval (default 10000)\n");
 	fprintf(stderr, "    -t <milliseconds>     SYNC interval timeout (default 60000)\n");
@@ -323,7 +324,7 @@
 		FILE	   *pidfile;
 
 		pidfile = fopen(pid_file, "w");
-		if (pidfile != NULL)
+		if (pidfile)
 		{
 			fprintf(pidfile, "%d", slon_pid);
 			fclose(pidfile);
@@ -713,6 +714,7 @@
 				 strerror(errno));
 		slon_retry();
 	}
+
 #ifdef HAVE_NETSNMP
 	if (pthread_create(&local_snmp_thread, NULL, snmpThread_main, NULL) < 0)
 	{
Index: slon.h
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/slon.h,v
retrieving revision 1.58
retrieving revision 1.59
diff -Lsrc/slon/slon.h -Lsrc/slon/slon.h -u -w -r1.58 -r1.59
--- src/slon/slon.h
+++ src/slon/slon.h
@@ -155,6 +155,7 @@
 
 	int			condition;		/* what are we waiting for? */
 	struct timeval timeout;		/* timeofday for timeout */
+	int	pg_version;		/* PostgreSQL version */
 
 	SlonConn   *prev;
 	SlonConn   *next;
Index: cleanup_thread.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/cleanup_thread.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -Lsrc/slon/cleanup_thread.c -Lsrc/slon/cleanup_thread.c -u -w -r1.31 -r1.32
--- src/slon/cleanup_thread.c
+++ src/slon/cleanup_thread.c
@@ -46,12 +46,9 @@
 	"%s.sl_seqlog",
 	"pg_catalog.pg_listener",
 	"pg_catalog.pg_statistic",
-	"pg_catalog.pg_listener",
-	"pg_catalog.pg_listener"
+	NULL
 };
 
-#define MAX_VAC_TABLE 8			/* Add to this if additional tables are added
-								 * above */
 
 static char tstring[255];		/* string used to store table names for the
 								 * VACUUM statements */
@@ -79,6 +76,7 @@
 	int			n,
 				t;
 	int			vac_count = 0;
+	int			vac_enable = SLON_VACUUM_FREQUENCY;
 	char	   *vacuum_action;
 
 	slon_log(SLON_DEBUG1, "cleanupThread: thread starts\n");
@@ -228,53 +226,135 @@
 		/*
 		 * Detain the usual suspects (vacuum event and log data)
 		 */
-		if (vac_frequency != 0 && ++vac_count >= vac_frequency)
+		if (vac_frequency !=0)
+		{
+			vac_enable = vac_frequency;
+		}
+		if (++vac_count >= vac_enable)
 		{
 			unsigned long latest_xid;
+			int a_vac = 0;
 
 			vac_count = 0;
-			latest_xid = get_earliest_xid(dbconn);
-			if (earliest_xid != latest_xid)
+
+			dstring_init(&query3);
+
+			/* 
+			 * if we are running a version >= 8.1, check to see 
+			 * if autovacuum is enabled, if so we should only run
+			 * analyze on the tables in table_list[], otherwise it
+			 * is ok to vacuum analyze
+			 */
+
+			if (conn->pg_version >=80100)
+			{
+				dstring_reset(&query3);
+				slon_mkquery(&query3, "show autovacuum");
+				res = PQexec(dbconn, dstring_data(&query3));
+				if (PQresultStatus(res)  != PGRES_TUPLES_OK)
 			{
-				vacuum_action = "vacuum analyze";
+					slon_log(SLON_ERROR,
+                                                         "cleanupThread: \"%s\" - %s",
+                                                   dstring_data(&query3), PQresultErrorMessage(res));
+
+                                        /*
+                                         * slon_retry(); break;
+                                         */
 			}
-			else
+				else if (strncmp(PQgetvalue(res, 0, 0), "on", 2) == 0)
 			{
-				vacuum_action = "analyze";
+					/*
+					 * autovacuum is on
+					 */
+					a_vac=1;
+				}
+                                PQclear(res);
+				dstring_reset(&query3);
+			}
+			latest_xid = get_earliest_xid(dbconn);
+			if (earliest_xid == latest_xid)
+			{
+				
+				vacuum_action = "";
 				slon_log(SLON_DEBUG4,
 					"cleanupThread: xid %d still active - analyze instead\n",
 					earliest_xid);
 			}
+			else
+			{
+				if ((vac_enable == vac_frequency) && (a_vac==0))
+				{
+					vacuum_action = "vacuum ";
+				}
+			}
 			earliest_xid = latest_xid;
 
 			/*
 			 * Build the query string for vacuuming replication runtime data
 			 * and event tables
 			 */
-			dstring_init(&query3);
 			gettimeofday(&tv_start, NULL);
-			for (t = 0; t < MAX_VAC_TABLE; t++)
+			for (t = 0; table_list[t] != NULL ; t++)
 			{
+
 				sprintf(tstring, table_list[t], rtcfg_namespace);
-				slon_mkquery(&query3,
-							 "%s %s;",
-							 vacuum_action,
-							 tstring);
+				if (a_vac==1)
+				{
+					slon_mkquery(&query3,"select (case when pga.enabled ISNULL THEN true ELSE pga.enabled END) "
+						"from \"pg_catalog\".pg_namespace PGN, \"pg_catalog\".pg_class PGC LEFT OUTER JOIN "
+						"\"pg_catalog\".pg_autovacuum pga ON (PGC.oid = pga.vacrelid) where PGC.relnamespace = PGN.oid "
+						"and %s.slon_quote_input('%s')=%s.slon_quote_brute(PGN.nspname) || '.' || %s.slon_quote_brute(PGC.relname);",
+					 	rtcfg_namespace,tstring, rtcfg_namespace, rtcfg_namespace);
 
 				res = PQexec(dbconn, dstring_data(&query3));
-				if (PQresultStatus(res) != PGRES_COMMAND_OK)
+					if (PQresultStatus(res) != PGRES_TUPLES_OK)  /* query error */
 				{
 					slon_log(SLON_ERROR,
 							 "cleanupThread: \"%s\" - %s",
 						   dstring_data(&query3), PQresultErrorMessage(res));
+						/*
+						 * slon_retry(); break;
+						 */
+					}
+					else	/* no errors */
+					{
+						if (PQntuples(res) == 1)	/* we want 1 and only 1 row, otherwise skip */
+						{
+							if (strncmp(PQgetvalue(res, 0, 0), "f", 1) == 0) 
+							{
+								/* 
+								 * pg_avac is NOT enabled for this table
+								 * so this means we need to handel it internaly
+								 */
+								if (vac_enable == vac_frequency)
+								{
+									vacuum_action = "vacuum ";
+								}
+							}
+							else
+							{
+								vacuum_action = "";
+							}
+						}
+					}
 					PQclear(res);
+				}
+				dstring_reset(&query3);
 
+				slon_mkquery(&query3,"%s analyze %s;",vacuum_action, tstring);
+				res = PQexec(dbconn, dstring_data(&query3));
+				if (PQresultStatus(res) != PGRES_COMMAND_OK)  /* query error */
+                                {
+                 	                slon_log(SLON_ERROR,
+	                                        "cleanupThread: \"%s\" - %s",
+                                                dstring_data(&query3), PQresultErrorMessage(res));
 					/*
 					 * slon_retry(); break;
 					 */
 				}
-			}
 			PQclear(res);
+				dstring_reset(&query3);
+			}
 			gettimeofday(&tv_end, NULL);
 			slon_log(SLON_DEBUG2,
 					 "cleanupThread: %8.3f seconds for vacuuming\n",
Index: slonik.h
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slonik/slonik.h,v
retrieving revision 1.26
retrieving revision 1.27
diff -Lsrc/slonik/slonik.h -Lsrc/slonik/slonik.h -u -w -r1.26 -r1.27
--- src/slonik/slonik.h
+++ src/slonik/slonik.h
@@ -109,8 +109,7 @@
 	char	   *conninfo;
 	PGconn	   *dbconn;
 	int64		last_event;
-	int			version_major;
-	int			version_minor;
+	int			pg_version;
 	int			nodeid_checked;
 	int			have_xact;
 	SlonikScript *script;
@@ -578,8 +577,7 @@
 				  SlonDString * query);
 PGresult *db_exec_select(SlonikStmt * stmt, SlonikAdmInfo * adminfo,
 			   SlonDString * query);
-int db_get_version(SlonikStmt * stmt, SlonikAdmInfo * adminfo,
-			   int *major, int *minor);
+int db_get_version(SlonikStmt * stmt, SlonikAdmInfo * adminfo);
 int db_check_namespace(SlonikStmt * stmt, SlonikAdmInfo * adminfo,
 				   char *clustername);
 int db_check_requirements(SlonikStmt * stmt, SlonikAdmInfo * adminfo,
Index: dbutil.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slonik/dbutil.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -Lsrc/slonik/dbutil.c -Lsrc/slonik/dbutil.c -u -w -r1.9 -r1.10
--- src/slonik/dbutil.c
+++ src/slonik/dbutil.c
@@ -314,10 +314,15 @@
  * ----------
  */
 int
-db_get_version(SlonikStmt * stmt, SlonikAdmInfo * adminfo, int *major, int *minor)
+db_get_version(SlonikStmt * stmt, SlonikAdmInfo * adminfo)
 {
 	PGresult   *res;
 	SlonDString query;
+	char        versionstr[7];
+	int	    major=0;
+	int	    minor=0;
+	int         patch=0;
+	int         version=0;
 
 	if (db_begin_xact(stmt, adminfo) < 0)
 		return -1;
@@ -330,7 +335,7 @@
 	if (res == NULL)
 		return -1;
 
-	if (sscanf(PQgetvalue(res, 0, 0), "PostgreSQL %d.%d", major, minor) != 2)
+	if (sscanf(PQgetvalue(res, 0, 0), "PostgreSQL %d.%d.%d", &major, &minor, &patch) < 2)
 	{
 		fprintf(stderr, "%s:%d: failed to parse %s for DB version\n",
 				stmt->stmt_filename, stmt->stmt_lno,
@@ -339,8 +344,9 @@
 		return -1;
 	}
 	PQclear(res);
-
-	return 0;
+	snprintf(versionstr, 7, "%.2d%.2d%.2d", major, minor, patch);
+	version=atoi(versionstr);
+	return version;
 }
 
 
Index: slonik.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slonik/slonik.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -Lsrc/slonik/slonik.c -Lsrc/slonik/slonik.c -u -w -r1.57 -r1.58
--- src/slonik/slonik.c
+++ src/slonik/slonik.c
@@ -1684,8 +1684,7 @@
 		if (db_connect(stmt, adminfo) < 0)
 			return NULL;
 
-		if (db_get_version(stmt, adminfo,
-				   &(adminfo->version_major), &(adminfo->version_minor)) < 0)
+		if (adminfo->pg_version = db_get_version(stmt, adminfo) < 0)
 		{
 			PQfinish(adminfo->dbconn);
 			adminfo->dbconn = NULL;
@@ -1854,57 +1853,38 @@
 		return -1;
 	}
 
-	switch (adminfo->version_major)
-	{
-		case 7:
-			use_major = 7;
+	/* determine what schema version we should load */
 
-			switch (adminfo->version_minor)
+	if (adminfo->pg_version > 70300)	/* 7.2 and lower */
 			{
-				case 3:
-					use_minor = 3;
-					break;
-
-				case 4:
-					use_minor = 4;
-					break;
-				case 5:
-					use_minor = 4;
-					break;
-
-				default:
 					printf("%s:%d: unsupported PostgreSQL "
 						   "version %d.%d\n",
 						   stmt->stmt_filename, stmt->stmt_lno,
-						   adminfo->version_major, adminfo->version_minor);
+			(adminfo->pg_version/10000), ((adminfo->pg_version%10000)/100));
 			}
-			break;
-		case 8:
-			use_major = 8;
-
-			switch (adminfo->version_minor)
+	else if ((adminfo->pg_version >= 70300) && (adminfo->pg_version<70400)) /* 7.3 */
 			{
-				case 0:
-					use_minor = 0;
-					break;
-				case 1:
+		use_major = 7;
+		use_minor = 3;
+	}
+	else if ((adminfo->pg_version >= 70400) && (adminfo->pg_version<70500)) /* 7.4 */
+	{
+		use_major = 7;
+		use_minor = 4;
+	}
+	else if ((adminfo->pg_version >= 70500) && adminfo->pg_version < 80200)	/* 8.0 and 8.1 */ 
+	{
+		use_major = 8;
 					use_minor = 0;
-					break;
-				default:
+	}
+	else	/* 8.2 and above */
+	{
+		use_major = 8;
 					use_minor = 0;
 					printf("%s:%d: Possible unsupported PostgreSQL "
-						   "version %d.%d\n",
-						   stmt->stmt_filename, stmt->stmt_lno,
-						   adminfo->version_major, adminfo->version_minor);
-					break;
-			}
-			break;
-
-		default:
-			printf("%s:%d: unsupported PostgreSQL "
-				   "version %d.%d\n",
-				   stmt->stmt_filename, stmt->stmt_lno,
-				   adminfo->version_major, adminfo->version_minor);
+			"version (%d) %d.%d, defaulting to 8.0 support\n",
+                        stmt->stmt_filename, stmt->stmt_lno, adminfo->pg_version,
+			(adminfo->pg_version/10000), ((adminfo->pg_version%10000)/100));
 	}
 
 #define ROWIDBITS "_Slony-I__rowID"
@@ -1966,54 +1946,38 @@
 
 	dbconn = adminfo->dbconn;
 
-	switch (adminfo->version_major)
-	{
-		case 7:
-			use_major = 7;
+        /* determine what schema version we should load */
 
-			switch (adminfo->version_minor)
+        if (adminfo->pg_version > 70300)        /* 7.2 and lower */
 			{
-				case 3:
-					use_minor = 3;
-					break;
-
-				case 4:
-				case 5:
-					use_minor = 4;
-					break;
-
-				default:
 					printf("%s:%d: unsupported PostgreSQL "
 						   "version %d.%d\n",
 						   stmt->stmt_filename, stmt->stmt_lno,
-						   adminfo->version_major, adminfo->version_minor);
+                        (adminfo->pg_version/10000), ((adminfo->pg_version%10000)/100));
 			}
-			break;
-		case 8:
-			use_major = 8;
-			switch (adminfo->version_minor)
+        else if ((adminfo->pg_version >= 70300) && (adminfo->pg_version<70400)) /* 7.3 */
 			{
-				case 0:
-					use_minor = 0;
-					break;
-				case 1:
+                use_major = 7;
+                use_minor = 3;
+        }
+        else if ((adminfo->pg_version >= 70400) && (adminfo->pg_version<70500)) /* 7.4 */
+        {
+                use_major = 7;
+                use_minor = 4;
+        }
+        else if ((adminfo->pg_version >= 70500) && adminfo->pg_version < 80200) /* 8.0 and 8.1 */
+        {
+                use_major = 8;
 					use_minor = 0;
-					break;
-				default:
+        }
+        else    /* 8.2 and above */
+        {
+                use_major = 8;
 					use_minor = 0;
 					printf("%s:%d: Possible unsupported PostgreSQL "
-						   "version %d.%d\n",
-						   stmt->stmt_filename, stmt->stmt_lno,
-						   adminfo->version_major, adminfo->version_minor);
-					break;
-			}
-			break;
-
-		default:
-			printf("%s:%d: unsupported PostgreSQL "
-				   "version %d.%d\n",
+                        "version %d.%d, defaulting to 8.0 support\n",
 				   stmt->stmt_filename, stmt->stmt_lno,
-				   adminfo->version_major, adminfo->version_minor);
+                        (adminfo->pg_version/10000), ((adminfo->pg_version%10000)/100));
 	}
 
 	/* Load schema, DB version specific */



More information about the Slony1-commit mailing list