CVS User Account cvsuser
Mon Mar 20 14:12:08 PST 2006
Log Message:
-----------
Revisions to DDL Script processing.

1.  There were some errors in what had previously been committed,
    evidently, with regards to memory allocation.

2.  DDL code hadn't done any meaningful logging of what was going on.

    slonik and slon have both been modified to start by listing how many
    statements they'll be processing, and then list each statement
    and its results as it is applied.

Also, fixed a typo in what was being logged per Sergei Klimov.
(This was in a subscribe set function not really related; it's just
a typo.)

Modified Files:
--------------
    slony1-engine/src/backend:
        slony1_funcs.sql (r1.79 -> r1.80)
    slony1-engine/src/slon:
        remote_worker.c (r1.108 -> r1.109)
    slony1-engine/src/slonik:
        slonik.c (r1.58 -> r1.59)

-------------- next part --------------
Index: slony1_funcs.sql
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/backend/slony1_funcs.sql,v
retrieving revision 1.79
retrieving revision 1.80
diff -Lsrc/backend/slony1_funcs.sql -Lsrc/backend/slony1_funcs.sql -u -w -r1.79 -r1.80
--- src/backend/slony1_funcs.sql
+++ src/backend/slony1_funcs.sql
@@ -119,7 +119,6 @@
 
 Create an sl_event entry';
 
-
 -- ----------------------------------------------------------------------
 -- FUNCTION denyAccess (cluster_name)
 --
@@ -3598,17 +3597,16 @@
 replicated table trig_tabid IS disabled.';
 
 -- ----------------------------------------------------------------------
--- FUNCTION ddlScript (set_id, script, only_on_node)
+-- FUNCTION ddlScript_prepare (set_id, only_on_node)
 --
 --	Generate the DDL_SCRIPT event
 -- ----------------------------------------------------------------------
-create or replace function @NAMESPACE at .ddlScript (int4, text, int4)
-returns bigint
+create or replace function @NAMESPACE at .ddlScript_prepare (int4, int4)
+returns integer
 as '
 declare
 	p_set_id			alias for $1;
-	p_script			alias for $2;
-	p_only_on_node		alias for $3;
+	p_only_on_node		alias for $2;
 	v_set_origin		int4;
 begin
 	-- ----
@@ -3635,31 +3633,53 @@
 	-- Create a SYNC event, run the script and generate the DDL_SCRIPT event
 	-- ----
 	perform @NAMESPACE at .createEvent(''_ at CLUSTERNAME@'', ''SYNC'', NULL);
-	perform @NAMESPACE at .ddlScript_int(p_set_id, p_script, p_only_on_node);
+	return 1;
+end;
+' language plpgsql;
+
+comment on function @NAMESPACE at .ddlScript_prepare (int4, int4) is 
+'Prepare for DDL script execution on origin';
+
+-- 	perform @NAMESPACE at .ddlScript_int(p_set_id, p_script, p_only_on_node);
+
+-- ----------------------------------------------------------------------
+-- FUNCTION ddlScript_complete (set_id, script, only_on_node)
+--
+--	Generate the DDL_SCRIPT event
+-- ----------------------------------------------------------------------
+create or replace function @NAMESPACE at .ddlScript_complete (int4, text, int4)
+returns integer
+as '
+declare
+	p_set_id			alias for $1;
+	p_script			alias for $2;
+	p_only_on_node		alias for $3;
+	v_set_origin		int4;
+begin
 	perform @NAMESPACE at .updateRelname(p_set_id, p_only_on_node);
 	return  @NAMESPACE at .createEvent(''_ at CLUSTERNAME@'', ''DDL_SCRIPT'', 
 			p_set_id, p_script, p_only_on_node);
 end;
 ' language plpgsql;
-comment on function @NAMESPACE at .ddlScript(int4, text, int4) is
-'ddlScript(set_id, script, only_on_node)
 
-Generates a SYNC event, runs the script on the origin, and then
-generates a DDL_SCRIPT event to request it to be run on replicated
-slaves.';
+comment on function @NAMESPACE at .ddlScript_complete(int4, text, int4) is
+'ddlScript_complete(set_id, script, only_on_node)
+
+After script has run on origin, this fixes up relnames, restores
+triggers, and generates a DDL_SCRIPT event to request it to be run on
+replicated slaves.';
 
 -- ----------------------------------------------------------------------
--- FUNCTION ddlScript_int (set_id, script, only_on_node)
+-- FUNCTION ddlScript_prepare_int (set_id, only_on_node)
 --
---	Process the DDL_SCRIPT event
+--	Prepare for the DDL_SCRIPT event
 -- ----------------------------------------------------------------------
-create or replace function @NAMESPACE at .ddlScript_int (int4, text, int4)
+create or replace function @NAMESPACE at .ddlScript_prepare_int (int4, int4)
 returns int4
 as '
 declare
 	p_set_id			alias for $1;
-	p_script			alias for $2;
-	p_only_on_node		alias for $3;
+	p_only_on_node		alias for $2;
 	v_set_origin		int4;
 	v_no_id				int4;
 	v_row				record;
@@ -3704,12 +3724,30 @@
 	loop
 		perform @NAMESPACE at .alterTableRestore(v_row.tab_id);
 	end loop;
+	return p_set_id;
+end;
+' language plpgsql;
+
+comment on function @NAMESPACE at .ddlScript_prepare_int (int4, int4) is
+'ddlScript_prepare_int (set_id, only_on_node)
+
+Do preparatory work for a DDL script, restoring 
+triggers/rules to original state.';
 
-	-- ----
-	-- Run the script
-	-- ----
-	execute p_script;
 
+-- ----------------------------------------------------------------------
+-- FUNCTION ddlScript_complete_int (set_id, only_on_node)
+--
+--	Complete the DDL_SCRIPT event
+-- ----------------------------------------------------------------------
+create or replace function @NAMESPACE at .ddlScript_complete_int (int4, int4)
+returns int4
+as '
+declare
+	p_set_id			alias for $1;
+	p_only_on_node		alias for $2;
+	v_row				record;
+begin
 	-- ----
 	-- Put all tables back into replicated mode
 	-- ----
@@ -3721,12 +3759,11 @@
 	return p_set_id;
 end;
 ' language plpgsql;
-comment on function @NAMESPACE at .ddlScript_int(int4, text, int4) is
-'ddlScript_int(set_id, script, only_on_node)
+comment on function @NAMESPACE at .ddlScript_complete_int(int4, int4) is
+'ddlScript_complete_int(set_id, script, only_on_node)
 
-Processes the DDL_SCRIPT event.  On slave nodes, this restores
-original triggers/rules, runs the script, and then puts tables back
-into replicated mode.';
+Complete processing the DDL_SCRIPT event.  This puts tables back into
+replicated mode.';
 
 -- ----------------------------------------------------------------------
 -- FUNCTION alterTableForReplication (tab_id)
@@ -4196,7 +4233,7 @@
 			where sub_set = p_sub_set
 				and sub_provider = p_sub_receiver)
 	then
-		raise exception ''Slony-I: Cannot unsubscibe set % while being provider'',
+		raise exception ''Slony-I: Cannot unsubscribe set % while being provider'',
 				p_sub_set;
 	end if;
 
@@ -4947,7 +4984,6 @@
 the creation of the serial column. The return an attkind according to
 that.';
 
-
 -- ----------------------------------------------------------------------
 -- FUNCTION RebuildListenEntries ()
 --
Index: remote_worker.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/remote_worker.c,v
retrieving revision 1.108
retrieving revision 1.109
diff -Lsrc/slon/remote_worker.c -Lsrc/slon/remote_worker.c -u -w -r1.108 -r1.109
--- src/slon/remote_worker.c
+++ src/slon/remote_worker.c
@@ -1459,6 +1459,8 @@
 				int			ddl_setid = (int)strtol(event->ev_data1, NULL, 10);
 				char	   *ddl_script = event->ev_data2;
 				int			ddl_only_on_node = (int)strtol(event->ev_data3, NULL, 10);
+				PGresult *res;
+				ExecStatusType rstat;
 
 
 				slon_appendquery(&query1,
@@ -1474,30 +1476,52 @@
 
 				int num_statements = -1, stmtno, startpos;
 				num_statements = scan_for_statements (ddl_script);
+				slon_log(SLON_CONFIG, "remoteWorkerThread_%d: DDL request with %d statements\n",
+					 node->no_id, num_statements);
 				if ((num_statements < 0) || (num_statements >= MAXSTATEMENTS)) {
 					slon_log(SLON_ERROR, "remoteWorkerThread_%d: DDL had invalid number of statements - %d\n", 
 						 node->no_id, num_statements);
 					slon_retry();
 				}
-				for (stmtno=0, startpos=0; stmtno > num_statements; startpos = STMTS[stmtno], stmtno++) {
-					char *dest = (char *) malloc (STMTS[stmtno] - startpos + 1);
+				
+				for (stmtno=0; stmtno < num_statements;  stmtno++) {
+					int startpos, endpos;
+					char *dest;
+					if (stmtno == 0)
+						startpos = 0;
+					else
+						startpos = STMTS[stmtno-1];
+
+					endpos = STMTS[stmtno];
+					dest = (char *) malloc (endpos - startpos + 1);
 					if (dest == 0) {
-						slon_log(SLON_ERROR, "remoteWorkerThread_%d: malloc() failure in DDL_SCRIPT\n");
+						slon_log(SLON_ERROR, "remoteWorkerThread_%d: malloc() failure in DDL_SCRIPT - could not allocate %d bytes of memory\n", 
+							 node->no_id, endpos - startpos + 1);
 						slon_retry();
 					}
-					strncpy(dest, ddl_script + startpos, STMTS[stmtno]-startpos);
-					dest[STMTS[stmtno]-startpos+1] = 0;
+					strncpy(dest, ddl_script + startpos, endpos-startpos);
+					dest[STMTS[stmtno]-startpos] = 0;
 					slon_mkquery(&query1, dest);
+					slon_log(SLON_CONFIG, "remoteWorkerThread_%d: DDL Statement %d: [%s]\n", 
+						 node->no_id, stmtno, dest);						 
 					free(dest);
 
-					if (query_execute(node, local_dbconn, &query1) < 0) {
-						slon_log(SLON_ERROR, "remoteWorkerThread_%d: DDL statement failed - %s\n",
-							 node->no_id, dstring_data(&query1));
+					res = PQexec(local_dbconn, dstring_data(&query1));
+
+					if (PQresultStatus(res) != PGRES_COMMAND_OK && 
+					    PQresultStatus(res) != PGRES_TUPLES_OK &&
+					    PQresultStatus(res) != PGRES_EMPTY_QUERY)
+					{
+						rstat = PQresultStatus(res);
+						slon_log(SLON_ERROR, "DDL Statement failed - %s\n", PQresStatus(rstat));
+						dstring_free(&query1);
 						slon_retry();
 					}
+					rstat = PQresultStatus(res);
+					slon_log (SLON_CONFIG, "DDL success - %s\n", PQresStatus(rstat));
 				}
 	
-				slon_mkquery(&query1, "select \"_%s\".ddlScript_complete_int(%d, %d); ", 
+				slon_mkquery(&query1, "select %s.ddlScript_complete_int(%d, %d); ", 
 					     rtcfg_namespace,
 					     ddl_setid,
 					     ddl_only_on_node);
Index: slonik.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slonik/slonik.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -Lsrc/slonik/slonik.c -Lsrc/slonik/slonik.c -u -w -r1.58 -r1.59
--- src/slonik/slonik.c
+++ src/slonik/slonik.c
@@ -3811,6 +3811,8 @@
 	char		rex1[256];
 	char		rex2[256];
 	char		rex3[256];
+	PGresult *res;
+	ExecStatusType rstat;
 
 	adminfo1 = get_active_adminfo((SlonikStmt *) stmt, stmt->ev_origin);
 	if (adminfo1 == NULL)
@@ -3850,31 +3852,51 @@
 	/* Split the script into a series of SQL statements - each needs to
 	   be submitted separately */
 	int num_statements = -1, stmtno, startpos;
-	num_statements = scan_for_statements (&script);
+	num_statements = scan_for_statements (dstring_data(&script));
+	printf("DDL script consisting of %d SQL statements\n", num_statements);
 
 	/* OOPS!  Something went wrong !!! */
 	if ((num_statements < 0) || (num_statements >= MAXSTATEMENTS)) {
+		printf("DDL - number of statements invalid - %d not between 0 and %d\n", num_statements, MAXSTATEMENTS);
 		return -1;
 	}
-	for (stmtno=0, startpos=0; stmtno > num_statements; startpos = STMTS[stmtno], stmtno++) {
-		char *dest = (char *) malloc (STMTS[stmtno] - startpos + 1);
+	for (stmtno=0; stmtno < num_statements;  stmtno++) {
+		int startpos, endpos;
+		char *dest;
+		if (stmtno == 0)
+			startpos = 0;
+		else
+			startpos = STMTS[stmtno-1];
+		endpos = STMTS[stmtno];
+		dest = (char *) malloc (endpos - startpos + 1);
 		if (dest == 0) {
+			printf("DDL Failure - could not allocate %d bytes of memory\n", endpos - startpos + 1);
 			return -1;
 		}
-		strncpy(dest, dstring_data(&script + startpos), STMTS[stmtno]-startpos);
-		dest[STMTS[stmtno]-startpos+1] = 0;
+		strncpy(dest, dstring_data(&script) + startpos, endpos-startpos);
+		dest[STMTS[stmtno]-startpos] = 0;
 		slon_mkquery(&query, dest);
+		printf("DDL Statement %d: (%d,%d) [%s]\n", stmtno, startpos, endpos, dest);
 		free(dest);
 
-		if (db_exec_evcommand((SlonikStmt *) stmt, adminfo1, &query) < 0)
+		res = PQexec(adminfo1->dbconn, dstring_data(&query));
+
+		if (PQresultStatus(res) != PGRES_COMMAND_OK && 
+		    PQresultStatus(res) != PGRES_TUPLES_OK &&
+		    PQresultStatus(res) != PGRES_EMPTY_QUERY)
 		{
+			rstat = PQresultStatus(res);
+			printf("DDL Statement failed - %s\n", PQresStatus(rstat));
 			dstring_free(&query);
 			return -1;
 		}
+		rstat = PQresultStatus(res);
+		printf ("Success - %s\n", PQresStatus(rstat));
 	}
 	
+	printf("Submitting SQL statements to subscribers...\n");
 
-	slon_mkquery(&query, "select \"_%s\".ddlScript_complete(%d, '%s' %d); ", 
+	slon_mkquery(&query, "select \"_%s\".ddlScript_complete(%d, '%s', %d); ", 
 		     stmt->hdr.script->clustername,
 		     stmt->ddl_setid,  dstring_data(&script),
 		     stmt->only_on_node);



More information about the Slony1-commit mailing list