CVS User Account cvsuser
Thu Nov 10 23:40:15 PST 2005
Log Message:
-----------
Disable indexes by setting pg_class.relhasindex to false during the
initial COPY on subscribing to a set. The indexes are rebuild via
REINDEX at the end of the copy operation.

Also try to truncate the relation before the copy on 8.0 and later.
Catch an eventual exception (foreign keys) and fallback to a delete.

Jan

Tags:
----
REL_1_1_STABLE

Modified Files:
--------------
    slony1-engine/src/backend:
        Makefile (r1.19 -> r1.19.2.1)
        slony1_funcs.sql (r1.64.2.12 -> r1.64.2.13)
        slony1_funcs.v73.sql (r1.7.2.1 -> r1.7.2.2)
        slony1_funcs.v74.sql (r1.6.2.1 -> r1.6.2.2)
    slony1-engine/src/slon:
        remote_worker.c (r1.86.2.9 -> r1.86.2.10)
    slony1-engine/src/slonik:
        slonik.c (r1.42.2.2 -> r1.42.2.3)
    slony1-engine/src/xxid:
        Makefile (r1.17 -> r1.17.2.1)

Added Files:
-----------
    slony1-engine/src/backend:
        slony1_base.v80.sql (r1.1.2.1)
        slony1_funcs.v80.sql (r1.1.2.1)

-------------- next part --------------
Index: slonik.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slonik/slonik.c,v
retrieving revision 1.42.2.2
retrieving revision 1.42.2.3
diff -Lsrc/slonik/slonik.c -Lsrc/slonik/slonik.c -u -w -r1.42.2.2 -r1.42.2.3
--- src/slonik/slonik.c
+++ src/slonik/slonik.c
@@ -1804,18 +1804,18 @@
 			}
 			break;
 		case 8:
-			use_major = 7;
+			use_major = 8;
 
 			switch (adminfo->version_minor)
 			{
 				case 0:
-					use_minor = 4;
+					use_minor = 0;
 					break;
 				case 1:
-					use_minor = 4;
+					use_minor = 0;
 					break;
 				default:
-					use_minor = 4;
+					use_minor = 0;
 					printf("%s:%d: Possible unsupported PostgreSQL "
 						   "version %d.%d\n",
 						   stmt->stmt_filename, stmt->stmt_lno,
@@ -1905,20 +1905,22 @@
 			}
 			break;
 		case 8:
-			use_major = 7;
+			use_major = 8;
 			switch (adminfo->version_minor)
 			{
 				case 0:
-					use_minor = 4;
+					use_minor = 0;
 					break;
 				case 1:
-					use_minor = 4;
+					use_minor = 0;
 					break;
 				default:
+					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;
 
Index: slony1_funcs.sql
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/backend/slony1_funcs.sql,v
retrieving revision 1.64.2.12
retrieving revision 1.64.2.13
diff -Lsrc/backend/slony1_funcs.sql -Lsrc/backend/slony1_funcs.sql -u -w -r1.64.2.12 -r1.64.2.13
--- src/backend/slony1_funcs.sql
+++ src/backend/slony1_funcs.sql
@@ -5197,6 +5197,7 @@
 		-- Drop obsolete functions
 		execute ''drop function @NAMESPACE at .terminateNodeConnections(name)'';
 		execute ''drop function @NAMESPACE at .cleanupListener()'';
+		execute ''drop function @NAMESPACE at .truncateTable(text)'';
 	end if;
 
 	return p_old;
--- /dev/null
+++ src/backend/slony1_funcs.v80.sql
@@ -0,0 +1,115 @@
+-- ----------------------------------------------------------------------
+-- slony1_funcs.v80.sql
+--
+--    Version 8.0 specific part of the replication support functions.
+--
+--	Copyright (c) 2003-2004, PostgreSQL Global Development Group
+--	Author: Jan Wieck, Afilias USA INC.
+--
+-- $Id: slony1_funcs.v80.sql,v 1.1.2.1 2005/11/10 23:39:33 wieck Exp $
+-- ----------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------
+-- FUNCTION prepareTableForCopy(tab_id)
+--
+--	Remove all content from a table before the subscription
+--	content is loaded via COPY and disable index maintenance.
+-- ----------------------------------------------------------------------
+create or replace function @NAMESPACE at .prepareTableForCopy(int4)
+returns int4
+as '
+declare
+	p_tab_id		alias for $1;
+	v_tab_oid		oid;
+	v_tab_fqname	text;
+begin
+	-- ----
+	-- Get the tables OID and fully qualified name
+	-- ---
+	select	PGC.oid,
+			@NAMESPACE at .slon_quote_brute(PGN.nspname) || ''.'' ||
+			@NAMESPACE at .slon_quote_brute(PGC.relname) as tab_fqname
+		into v_tab_oid, v_tab_fqname
+			from @NAMESPACE at .sl_table T,   
+				"pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN
+				where T.tab_id = p_tab_id
+				and T.tab_reloid = PGC.oid
+				and PGC.relnamespace = PGN.oid;
+	if not found then
+		raise exception ''Table with ID % not found in sl_table'', p_tab_id;
+	end if;
+
+	-- ----
+	-- Setting pg_class.relhasindex to false will cause copy not to
+	-- maintain any indexes. At the end of the copy we will reenable
+	-- them and reindex the table. This bulk creating of indexes is
+	-- faster.
+	-- ----
+	update pg_class set relhasindex = ''f'' where oid = v_tab_oid;
+
+	-- ----
+	-- Try using truncate to empty the table and fallback to
+	-- delete on error.
+	-- ----
+	execute ''truncate '' || @NAMESPACE at .slon_quote_input(v_tab_fqname);
+	raise notice ''truncate of % succeeded'', v_tab_fqname;
+	return 1;
+	exception when others then
+		raise notice ''truncate of % failed - doing delete'', v_tab_fqname;
+		execute ''delete from only '' || @NAMESPACE at .slon_quote_input(v_tab_fqname);
+		return 0;
+end;
+' language plpgsql;
+
+comment on function @NAMESPACE at .prepareTableForCopy(int4) is
+'Delete all data and suppress index maintenance';
+
+-- ----------------------------------------------------------------------
+-- FUNCTION finishTableAfterCopy(tab_id)
+--
+--	Reenable index maintenance and reindex the table after COPY.
+-- ----------------------------------------------------------------------
+create or replace function @NAMESPACE at .finishTableAfterCopy(int4)
+returns int4
+as '
+declare
+	p_tab_id		alias for $1;
+	v_tab_oid		oid;
+	v_tab_fqname	text;
+begin
+	-- ----
+	-- Get the tables OID and fully qualified name
+	-- ---
+	select	PGC.oid,
+			@NAMESPACE at .slon_quote_brute(PGN.nspname) || ''.'' ||
+			@NAMESPACE at .slon_quote_brute(PGC.relname) as tab_fqname
+		into v_tab_oid, v_tab_fqname
+			from @NAMESPACE at .sl_table T,   
+				"pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN
+				where T.tab_id = p_tab_id
+				and T.tab_reloid = PGC.oid
+				and PGC.relnamespace = PGN.oid;
+	if not found then
+		raise exception ''Table with ID % not found in sl_table'', p_tab_id;
+	end if;
+
+	-- ----
+	-- Reenable indexes and reindex the table.
+	-- ----
+	update pg_class set relhasindex = ''t'' where oid = v_tab_oid;
+	execute ''reindex table '' || @NAMESPACE at .slon_quote_input(v_tab_fqname);
+
+	return 1;
+end;
+' language plpgsql;
+
+comment on function @NAMESPACE at .finishTableAfterCopy(int4) is
+'Reenable index maintenance and reindex the table';
+
+create or replace function @NAMESPACE at .pre74()
+returns integer
+as 'select 0' language sql;
+
+comment on function @NAMESPACE at .pre74() is 
+'Returns 1/0 based on whether or not the DB is running a
+version earlier than 7.4';
Index: slony1_funcs.v74.sql
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/backend/slony1_funcs.v74.sql,v
retrieving revision 1.6.2.1
retrieving revision 1.6.2.2
diff -Lsrc/backend/slony1_funcs.v74.sql -Lsrc/backend/slony1_funcs.v74.sql -u -w -r1.6.2.1 -r1.6.2.2
--- src/backend/slony1_funcs.v74.sql
+++ src/backend/slony1_funcs.v74.sql
@@ -10,24 +10,90 @@
 -- ----------------------------------------------------------------------
 
 -- ----------------------------------------------------------------------
--- FUNCTION truncateTable(tab_fqname)
+-- FUNCTION prepareTableForCopy(tab_id)
 --
 --	Remove all content from a table before the subscription
---	content is loaded via COPY.
+--	content is loaded via COPY and disable index maintenance.
 -- ----------------------------------------------------------------------
-create or replace function @NAMESPACE at .truncateTable(text)
+create or replace function @NAMESPACE at .prepareTableForCopy(int4)
 returns int4
 as '
 declare
-	p_tab_fqname		alias for $1;
+	p_tab_id		alias for $1;
+	v_tab_oid		oid;
+	v_tab_fqname	text;
 begin
-	execute ''delete from only '' || p_tab_fqname;
+	-- ----
+	-- Get the tables OID and fully qualified name
+	-- ---
+	select	PGC.oid,
+			@NAMESPACE at .slon_quote_brute(PGN.nspname) || ''.'' ||
+			@NAMESPACE at .slon_quote_brute(PGC.relname) as tab_fqname
+		into v_tab_oid, v_tab_fqname
+			from @NAMESPACE at .sl_table T,   
+				"pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN
+				where T.tab_id = p_tab_id
+				and T.tab_reloid = PGC.oid
+				and PGC.relnamespace = PGN.oid;
+	if not found then
+		raise exception ''Table with ID % not found in sl_table'', p_tab_id;
+	end if;
+
+	-- ----
+	-- Setting pg_class.relhasindex to false will cause copy not to
+	-- maintain any indexes. At the end of the copy we will reenable
+	-- them and reindex the table. This bulk creating of indexes is
+	-- faster.
+	-- ----
+	update pg_class set relhasindex = ''f'' where oid = v_tab_oid;
+	execute ''delete from only '' || @NAMESPACE at .slon_quote_input(v_tab_fqname);
+	return 1;
+end;
+' language plpgsql;
+
+comment on function @NAMESPACE at .prepareTableForCopy(int4) is
+'Delete all data and suppress index maintenance';
+
+-- ----------------------------------------------------------------------
+-- FUNCTION finishTableAfterCopy(tab_id)
+--
+--	Reenable index maintenance and reindex the table after COPY.
+-- ----------------------------------------------------------------------
+create or replace function @NAMESPACE at .finishTableAfterCopy(int4)
+returns int4
+as '
+declare
+	p_tab_id		alias for $1;
+	v_tab_oid		oid;
+	v_tab_fqname	text;
+begin
+	-- ----
+	-- Get the tables OID and fully qualified name
+	-- ---
+	select	PGC.oid,
+			@NAMESPACE at .slon_quote_brute(PGN.nspname) || ''.'' ||
+			@NAMESPACE at .slon_quote_brute(PGC.relname) as tab_fqname
+		into v_tab_oid, v_tab_fqname
+			from @NAMESPACE at .sl_table T,   
+				"pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN
+				where T.tab_id = p_tab_id
+				and T.tab_reloid = PGC.oid
+				and PGC.relnamespace = PGN.oid;
+	if not found then
+		raise exception ''Table with ID % not found in sl_table'', p_tab_id;
+	end if;
+
+	-- ----
+	-- Reenable indexes and reindex the table.
+	-- ----
+	update pg_class set relhasindex = ''t'' where oid = v_tab_oid;
+	execute ''reindex table '' || @NAMESPACE at .slon_quote_input(v_tab_fqname);
 	return 1;
 end;
 ' language plpgsql;
 
-comment on function @NAMESPACE at .truncateTable(text) is
-'Delete all data from specified table';
+comment on function @NAMESPACE at .finishTableAfterCopy(int4) is
+'Reenable index maintenance and reindex the table';
 
 create or replace function @NAMESPACE at .pre74()
 returns integer
Index: slony1_funcs.v73.sql
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/backend/slony1_funcs.v73.sql,v
retrieving revision 1.7.2.1
retrieving revision 1.7.2.2
diff -Lsrc/backend/slony1_funcs.v73.sql -Lsrc/backend/slony1_funcs.v73.sql -u -w -r1.7.2.1 -r1.7.2.2
--- src/backend/slony1_funcs.v73.sql
+++ src/backend/slony1_funcs.v73.sql
@@ -10,24 +10,90 @@
 -- ----------------------------------------------------------------------
 
 -- ----------------------------------------------------------------------
--- FUNCTION truncateTable(tab_fqname)
+-- FUNCTION prepareTableForCopy(tab_id)
 --
 --	Remove all content from a table before the subscription
---	content is loaded via COPY.
+--	content is loaded via COPY and disable index maintenance.
 -- ----------------------------------------------------------------------
-create or replace function @NAMESPACE at .truncateTable(text)
+create or replace function @NAMESPACE at .prepareTableForCopy(int4)
 returns int4
 as '
 declare
-	p_tab_fqname		alias for $1;
+	p_tab_id		alias for $1;
+	v_tab_oid		oid;
+	v_tab_fqname	text;
 begin
-	execute ''delete from only '' || @NAMESPACE at .slon_quote_input(p_tab_fqname);
+	-- ----
+	-- Get the tables OID and fully qualified name
+	-- ---
+	select	PGC.oid,
+			@NAMESPACE at .slon_quote_brute(PGN.nspname) || ''.'' ||
+			@NAMESPACE at .slon_quote_brute(PGC.relname) as tab_fqname
+		into v_tab_oid, v_tab_fqname
+			from @NAMESPACE at .sl_table T,   
+				"pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN
+				where T.tab_id = p_tab_id
+				and T.tab_reloid = PGC.oid
+				and PGC.relnamespace = PGN.oid;
+	if not found then
+		raise exception ''Table with ID % not found in sl_table'', p_tab_id;
+	end if;
+
+	-- ----
+	-- Setting pg_class.relhasindex to false will cause copy not to
+	-- maintain any indexes. At the end of the copy we will reenable
+	-- them and reindex the table. This bulk creating of indexes is
+	-- faster.
+	-- ----
+	update pg_class set relhasindex = ''f'' where oid = v_tab_oid;
+	execute ''delete from only '' || @NAMESPACE at .slon_quote_input(v_tab_fqname);
+	return 1;
+end;
+' language plpgsql;
+
+comment on function @NAMESPACE at .prepareTableForCopy(int4) is
+'Delete all data and suppress index maintenance';
+
+-- ----------------------------------------------------------------------
+-- FUNCTION finishTableAfterCopy(tab_id)
+--
+--	Reenable index maintenance and reindex the table after COPY.
+-- ----------------------------------------------------------------------
+create or replace function @NAMESPACE at .finishTableAfterCopy(int4)
+returns int4
+as '
+declare
+	p_tab_id		alias for $1;
+	v_tab_oid		oid;
+	v_tab_fqname	text;
+begin
+	-- ----
+	-- Get the tables OID and fully qualified name
+	-- ---
+	select	PGC.oid,
+			@NAMESPACE at .slon_quote_brute(PGN.nspname) || ''.'' ||
+			@NAMESPACE at .slon_quote_brute(PGC.relname) as tab_fqname
+		into v_tab_oid, v_tab_fqname
+			from @NAMESPACE at .sl_table T,   
+				"pg_catalog".pg_class PGC, "pg_catalog".pg_namespace PGN
+				where T.tab_id = p_tab_id
+				and T.tab_reloid = PGC.oid
+				and PGC.relnamespace = PGN.oid;
+	if not found then
+		raise exception ''Table with ID % not found in sl_table'', p_tab_id;
+	end if;
+
+	-- ----
+	-- Reenable indexes and reindex the table.
+	-- ----
+	update pg_class set relhasindex = ''t'' where oid = v_tab_oid;
+	execute ''reindex table '' || @NAMESPACE at .slon_quote_input(v_tab_fqname);
 	return 1;
 end;
 ' language plpgsql;
 
-comment comment on function @NAMESPACE at .truncateTable(text) is
-'Delete all data from specified table';
+comment on function @NAMESPACE at .finishTableAfterCopy(int4) is
+'Reenable index maintenance and reindex the table';
 
 create or replace function @NAMESPACE at .pre74()
 returns integer
--- /dev/null
+++ src/backend/slony1_base.v80.sql
@@ -0,0 +1,12 @@
+-- ----------------------------------------------------------------------
+-- slony1_base.v80.sql
+--
+--    Version 8.0 specific parts of the basic replication schema.
+--
+--	Copyright (c) 2003-2004, PostgreSQL Global Development Group
+--	Author: Jan Wieck, Afilias USA INC.
+--
+-- $Id: slony1_base.v80.sql,v 1.1.2.1 2005/11/10 23:39:33 wieck Exp $
+-- ----------------------------------------------------------------------
+
+
Index: Makefile
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/backend/Makefile,v
retrieving revision 1.19
retrieving revision 1.19.2.1
diff -Lsrc/backend/Makefile -Lsrc/backend/Makefile -u -w -r1.19 -r1.19.2.1
--- src/backend/Makefile
+++ src/backend/Makefile
@@ -26,13 +26,18 @@
 BASE_74			= slony1_base.v74.sql
 FUNCS_74		= slony1_funcs.v74.sql
 
+BASE_80			= slony1_base.v80.sql
+FUNCS_80		= slony1_funcs.v80.sql
+
 SQL_NAMES =				\
 	$(BASE_COMMON)		\
 	$(FUNCS_COMMON)		\
 	$(BASE_73)			\
 	$(FUNCS_73)			\
 	$(BASE_74)			\
-	$(FUNCS_74)
+	$(FUNCS_74)			\
+	$(BASE_80)			\
+	$(FUNCS_80)
 
 DISTFILES = Makefile README README.events $(wildcard *.sql) $(wildcard *.in) $(wildcard *.c)
 
Index: remote_worker.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/remote_worker.c,v
retrieving revision 1.86.2.9
retrieving revision 1.86.2.10
diff -Lsrc/slon/remote_worker.c -Lsrc/slon/remote_worker.c -u -w -r1.86.2.9 -r1.86.2.10
--- src/slon/remote_worker.c
+++ src/slon/remote_worker.c
@@ -2853,10 +2853,10 @@
 		nodeon73 = atoi(PQgetvalue(res4, 0, 0));
 
 		slon_mkquery(&query1,
-			     "select %s.truncateTable('%s'); "
+			     "select %s.prepareTableForCopy(%d); "
 			     "copy %s %s from stdin; ",
 			     rtcfg_namespace,
-			     tab_fqname, tab_fqname,
+			     tab_id, tab_fqname,
 			     nodeon73 ? "" : PQgetvalue(res3, 0, 0)
 			);
 		res2 = PQexec(loc_dbconn, dstring_data(&query1));
@@ -3159,7 +3159,10 @@
 		/*
 		 * Analyze the table to update statistics
 		 */
-		slon_mkquery(&query1, "analyze %s; ", tab_fqname);
+		slon_mkquery(&query1, "select %s.finishTableAfterCopy(%d); "
+							"analyze %s; ",
+							rtcfg_namespace, tab_id,
+							tab_fqname);
 		if (query_execute(node, loc_dbconn, &query1) < 0)
 		{
 			PQclear(res1);
Index: Makefile
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/xxid/Makefile,v
retrieving revision 1.17
retrieving revision 1.17.2.1
diff -Lsrc/xxid/Makefile -Lsrc/xxid/Makefile -u -w -r1.17 -r1.17.2.1
--- src/xxid/Makefile
+++ src/xxid/Makefile
@@ -18,7 +18,8 @@
 SO_NAME		= $(NAME)$(DLSUFFIX)
 SQL_NAME73	= $(NAME).v73.sql
 SQL_NAME74	= $(NAME).v74.sql
-SQL_NAMES	= $(SQL_NAME73) $(SQL_NAME74)
+SQL_NAME80	= $(NAME).v80.sql
+SQL_NAMES	= $(SQL_NAME73) $(SQL_NAME74) $(SQL_NAME80)
 
 SO_OBJS		= xxid.o
 
@@ -33,11 +34,14 @@
 $(SQL_NAME74):	$(SQL_NAME73)
 	cp $< $@
 
+$(SQL_NAME80):	$(SQL_NAME73)
+	cp $< $@
+
 $(SO_NAME):     $(SO_OBJS) $(POSTGRES_IMP)
 
 clean distclean maintainer-clean:
 	rm -f $(SO_NAME) $(SO_OBJS)
-	rm -f $(SQL_NAME74)
+	rm -f $(SQL_NAME74) $(SQL_NAME80)
 
 install: all installdirs
 	$(INSTALL_SCRIPT) $(SO_NAME) $(DESTDIR)$(pgpkglibdir)


More information about the Slony1-commit mailing list