CVS User Account cvsuser
Wed Oct 13 19:51:30 PDT 2004
Log Message:
-----------
Added checks that ensure that slon is not running against any 
database that has either the wrong slony schema loaded or the
wrong shared module version installed.

Jan

Modified Files:
--------------
    slony1-engine:
        config.h.in (r1.8 -> r1.9)
    slony1-engine/src/backend:
        slony1_funcs.c (r1.23 -> r1.24)
        slony1_funcs.sql (r1.31 -> r1.32)
    slony1-engine/src/slon:
        dbutils.c (r1.12 -> r1.13)
        remote_listen.c (r1.16 -> r1.17)
        slon.c (r1.31 -> r1.32)
        slon.h (r1.39 -> r1.40)

-------------- next part --------------
Index: slony1_funcs.sql
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/backend/slony1_funcs.sql,v
retrieving revision 1.31
retrieving revision 1.32
diff -Lsrc/backend/slony1_funcs.sql -Lsrc/backend/slony1_funcs.sql -u -w -r1.31 -r1.32
--- src/backend/slony1_funcs.sql
+++ src/backend/slony1_funcs.sql
@@ -167,6 +167,19 @@
   'not yet documented';
 
 -- ----------------------------------------------------------------------
+-- FUNCTION getModuleVersion ()
+--
+--	Returns the compiled in version number of the Slony-I shared
+--	object.
+-- ----------------------------------------------------------------------
+create or replace function @NAMESPACE at .getModuleVersion () returns text
+    as '$libdir/slony1_funcs', '_Slony_I_getModuleVersion'
+	language C
+	security definer;
+grant execute on function @NAMESPACE at .getModuleVersion () to public;
+
+
+-- ----------------------------------------------------------------------
 -- FUNCTION setSessionRole (name, role)
 --
 --	
Index: slony1_funcs.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/backend/slony1_funcs.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -Lsrc/backend/slony1_funcs.c -Lsrc/backend/slony1_funcs.c -u -w -r1.23 -r1.24
--- src/backend/slony1_funcs.c
+++ src/backend/slony1_funcs.c
@@ -36,6 +36,7 @@
 
 PG_FUNCTION_INFO_V1(_Slony_I_createEvent);
 PG_FUNCTION_INFO_V1(_Slony_I_getLocalNodeId);
+PG_FUNCTION_INFO_V1(_Slony_I_getModuleVersion);
 
 PG_FUNCTION_INFO_V1(_Slony_I_setSessionRole);
 PG_FUNCTION_INFO_V1(_Slony_I_getSessionRole);
@@ -47,6 +48,7 @@
 
 Datum           _Slony_I_createEvent(PG_FUNCTION_ARGS);
 Datum           _Slony_I_getLocalNodeId(PG_FUNCTION_ARGS);
+Datum           _Slony_I_getModuleVersion(PG_FUNCTION_ARGS);
 
 Datum           _Slony_I_setSessionRole(PG_FUNCTION_ARGS);
 Datum           _Slony_I_getSessionRole(PG_FUNCTION_ARGS);
@@ -259,6 +261,28 @@
 }
 
 
+/*
+ * _Slony_I_getModuleVersion -
+ *    
+ *    SQL callable function to determine the version number
+ *    of this shared object during the startup checks.
+ *
+ */
+Datum
+_Slony_I_getModuleVersion(PG_FUNCTION_ARGS)
+{
+	text   *retval;
+	int		len;
+
+	len = strlen(SLONY_I_VERSION_STRING);
+	retval = palloc(VARHDRSZ + len);
+	VARATT_SIZEP(retval) = VARHDRSZ + len;
+	memcpy(VARDATA(retval), SLONY_I_VERSION_STRING, len);
+
+	PG_RETURN_TEXT_P(retval);
+}
+
+
 Datum
 _Slony_I_setSessionRole(PG_FUNCTION_ARGS)
 {
Index: config.h.in
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/config.h.in,v
retrieving revision 1.8
retrieving revision 1.9
diff -Lconfig.h.in -Lconfig.h.in -u -w -r1.8 -r1.9
--- config.h.in
+++ config.h.in
@@ -12,6 +12,8 @@
 #ifndef	SLONY_I_CONFIG_H
 #define SLONY_I_CONFIG_H
 
+#define SLONY_I_VERSION_STRING	"1.1.0"
+
 #undef PGSHARE
 
 /* Set to 1 if libpq contains PQfreemem() */
Index: remote_listen.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/remote_listen.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -Lsrc/slon/remote_listen.c -Lsrc/slon/remote_listen.c -u -w -r1.16 -r1.17
--- src/slon/remote_listen.c
+++ src/slon/remote_listen.c
@@ -273,6 +273,24 @@
 
 				continue;
 			}
+			if (db_checkSchemaVersion(dbconn) < 0)
+			{
+				slon_log(SLON_ERROR,
+				"remoteListenThread_%d: db_checkSchemaVersion() "
+					 "failed\n",
+					 node->no_id);
+
+				slon_disconnectdb(conn);
+				free(conn_conninfo);
+				conn = NULL;
+				conn_conninfo = NULL;
+
+				rc = sched_msleep(node, pa_connretry * 1000);
+				if (rc != SCHED_STATUS_OK && rc != SCHED_STATUS_CANCEL)
+					break;
+
+				continue;
+			}
 			slon_log(SLON_DEBUG1,
 			       "remoteListenThread_%d: connected to '%s'\n",
 				 node->no_id, conn_conninfo);
Index: dbutils.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/dbutils.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -Lsrc/slon/dbutils.c -Lsrc/slon/dbutils.c -u -w -r1.12 -r1.13
--- src/slon/dbutils.c
+++ src/slon/dbutils.c
@@ -205,6 +205,105 @@
 }
 
 
+/* ----------
+ * db_checkSchemaVersion
+ *
+ *	Check the Slony schema on a connection for the correct version number
+ * ----------
+ */
+int
+db_checkSchemaVersion(PGconn *conn)
+{
+	char		query[1024];
+	PGresult   *res;
+	int			retval = 0;
+
+	/*
+	 * Select the version number from the schema
+	 */
+	snprintf(query, 1024, "select %s.slonyVersion()",
+			rtcfg_namespace);
+	res = PQexec(conn, query);
+	if (PQresultStatus(res) != PGRES_TUPLES_OK)
+	{
+		slon_log(SLON_ERROR,
+				"cannot get Slony-I schema version - %s",
+				PQresultErrorMessage(res));
+		slon_log(SLON_ERROR,
+				"please upgrade Slony-I schema to version %s\n",
+				SLONY_I_VERSION_STRING);
+		PQclear(res);
+		return -1;
+	}
+	if (PQntuples(res) != 1)
+	{
+		slon_log(SLON_ERROR,
+				"query '%s' returned %d rows (expected 1)\n",
+				query, PQntuples(res));
+		PQclear(res);
+		return -1;
+	}
+
+	/*
+	 * Check the version string of the schema
+	 */
+	if (strcmp(PQgetvalue(res, 0, 0), SLONY_I_VERSION_STRING) != 0)
+	{
+		slon_log(SLON_ERROR,
+				"Slony-I schema version is %s\n",
+				PQgetvalue(res, 0, 0));
+		slon_log(SLON_ERROR,
+				"please upgrade Slony-I schema to version %s\n",
+				SLONY_I_VERSION_STRING);
+		retval = -1;
+	}
+	PQclear(res);
+	
+	/*
+	 * Select the version number from the module
+	 */
+	snprintf(query, 1024, "select %s.getModuleVersion()",
+			rtcfg_namespace);
+	res = PQexec(conn, query);
+	if (PQresultStatus(res) != PGRES_TUPLES_OK)
+	{
+		slon_log(SLON_ERROR,
+				"cannot get Slony-I module version - %s",
+				PQresultErrorMessage(res));
+		slon_log(SLON_ERROR,
+				"please upgrade Slony-I shared module to version %s\n",
+				SLONY_I_VERSION_STRING);
+		PQclear(res);
+		return -1;
+	}
+	if (PQntuples(res) != 1)
+	{
+		slon_log(SLON_ERROR,
+				"query '%s' returned %d rows (expected 1)\n",
+				query, PQntuples(res));
+		PQclear(res);
+		return -1;
+	}
+
+	/*
+	 * Check the version string of the module
+	 */
+	if (strcmp(PQgetvalue(res, 0, 0), SLONY_I_VERSION_STRING) != 0)
+	{
+		slon_log(SLON_ERROR,
+				"Slony-I module version is %s\n",
+				PQgetvalue(res, 0, 0));
+		slon_log(SLON_ERROR,
+				"please upgrade Slony-I shared module to version %s\n",
+				SLONY_I_VERSION_STRING);
+		retval = -1;
+	}
+	PQclear(res);
+	
+	return retval;
+}
+
+
 /*
  * ---------- slon_mkquery
  * 
Index: slon.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/slon.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -Lsrc/slon/slon.c -Lsrc/slon/slon.c -u -w -r1.31 -r1.32
--- src/slon/slon.c
+++ src/slon/slon.c
@@ -171,6 +171,9 @@
 	*cp2++ = '"';
 	*cp2 = '\0';
 
+	slon_log(SLON_CONFIG, "main: slon version %s starting up\n",
+			SLONY_I_VERSION_STRING);
+
 	/*
 	 * Remember the connection information for the local node.
 	 */
@@ -202,6 +205,11 @@
 		slon_log(SLON_FATAL, "main: Node is not initialized properly\n");
 		slon_exit(-1);
 	}
+	if (db_checkSchemaVersion(startup_conn) < 0)
+	{
+		slon_log(SLON_FATAL, "main: Node has wrong Slony-I schema or module version loaded\n");
+		slon_exit(-1);
+	}
 	slon_log(SLON_CONFIG, "main: local node id = %d\n", rtcfg_nodeid);
         
 	if (pid_file)
Index: slon.h
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/slon.h,v
retrieving revision 1.39
retrieving revision 1.40
diff -Lsrc/slon/slon.h -Lsrc/slon/slon.h -u -w -r1.39 -r1.40
--- src/slon/slon.h
+++ src/slon/slon.h
@@ -485,6 +485,7 @@
 extern void		slon_free_dummyconn(SlonConn *conn);
 
 extern int		db_getLocalNodeId(PGconn *conn);
+extern int		db_checkSchemaVersion(PGconn *conn);
 
 extern int		slon_mkquery(SlonDString *ds, char *fmt, ...);
 extern int		slon_appendquery(SlonDString *ds, char *fmt, ...);


More information about the Slony1-commit mailing list