? tst.conf Index: DBMirror.pl =================================================================== RCS file: /projects/cvsroot/pgsql-server/contrib/dbmirror/DBMirror.pl,v retrieving revision 1.1 diff -w -c -r1.1 DBMirror.pl *** DBMirror.pl 2002/06/23 21:58:07 1.1 --- DBMirror.pl 2002/10/16 23:35:18 *************** *** 369,375 **** #Now build the insert query. ! my $insertQuery = "INSERT INTO \"$tableName\" ("; my $valuesQuery = ") VALUES ("; foreach $column (keys (%recordValues)) { if($firstIteration==0) { --- 369,375 ---- #Now build the insert query. ! my $insertQuery = "INSERT INTO $tableName ("; my $valuesQuery = ") VALUES ("; foreach $column (keys (%recordValues)) { if($firstIteration==0) { *************** *** 450,456 **** %dataHash = extractData($pendingResult,$currentTuple); my $counter=0; ! my $deleteQuery = "DELETE FROM \"$tableName\" WHERE "; foreach $currentField (keys %dataHash) { if($firstField==0) { $deleteQuery .= " AND "; --- 450,456 ---- %dataHash = extractData($pendingResult,$currentTuple); my $counter=0; ! my $deleteQuery = "DELETE FROM $tableName WHERE "; foreach $currentField (keys %dataHash) { if($firstField==0) { $deleteQuery .= " AND "; *************** *** 535,541 **** my $counter; my $quotedValue; ! my $updateQuery = "UPDATE \"$tableName\" SET "; my $currentField; --- 535,541 ---- my $counter; my $quotedValue; ! my $updateQuery = "UPDATE $tableName SET "; my $currentField; Index: MirrorSetup.sql =================================================================== RCS file: /projects/cvsroot/pgsql-server/contrib/dbmirror/MirrorSetup.sql,v retrieving revision 1.2 diff -w -c -r1.2 MirrorSetup.sql *** MirrorSetup.sql 2002/08/22 00:01:38 1.2 --- MirrorSetup.sql 2002/10/16 23:35:19 *************** *** 4,10 **** CREATE TABLE "MirrorHost" ( "MirrorHostId" serial, ! "HostName" varchar NOT NULL ); --- 4,11 ---- CREATE TABLE "MirrorHost" ( "MirrorHostId" serial, ! "HostName" varchar NOT NULL, ! PRIMARY KEY("MirrorHostId") ); Index: README.dbmirror =================================================================== RCS file: /projects/cvsroot/pgsql-server/contrib/dbmirror/README.dbmirror,v retrieving revision 1.2 diff -w -c -r1.2 README.dbmirror *** README.dbmirror 2002/09/26 05:24:30 1.2 --- README.dbmirror 2002/10/16 23:35:19 *************** *** 46,51 **** --- 46,52 ---- Installation Instructions ------------------------------------------------------------------------ + 1) Compile pending.c The file pending.c contains the recordchange trigger. This runs every *************** *** 53,73 **** To build the trigger run make on the "Makefile" in the DBMirror directory. ! The Makefile supplied assumes that the postgres include files are in ! /usr/local/pgsql/include/server. Postgres-7.1.x installations should change this to /usr/local/pgsql/include (The server part is for 7.2+) If you have installed the postgres include files to another location then ! modify the Makefile to reflect this. - The trigger requires that all postgres headers be installed, this is - accomplished in postgresql(7.1 or 7.2) by running "make install-all-headers" - in the postgres source directory. ! The Makefile should create a file named pending.so that contains the trigger. Install this file in /usr/local/pgsql/lib (or another suitable location). --- 54,89 ---- To build the trigger run make on the "Makefile" in the DBMirror directory. + + Postgres-7.3 Make Instructions: + + If you have already run "configure" in the pgsql-server directory + then run "make" in the dbmirror directory to compile the trigger. + + Postgres-7.1 & Postgres-7.2 Make Instructions: + + The included Makefile is not compatible with postgres 7.1 and 7.2 + The trigger will need to be built by hand. + + Run the following commands ! gcc -fpic -I/usr/local/pgsql/include/server -c pending.c -DNOSCHEMAS ! ld -shared -o pending.so pending.o + Assuming the postgres include files are in /usr/local/pgsql/include/server. + Postgres-7.1.x installations should change this to /usr/local/pgsql/include (The server part is for 7.2+) If you have installed the postgres include files to another location then ! modify the include path to reflect this. ! ! Compiling the trigger by hand requires that all postgres headers be installed ! ,this is accomplished in postgresql(7.1 or 7.2) by running ! "make install-all-headers" in the postgres source directory. ! You should now have a file named pending.so that contains the trigger. Install this file in /usr/local/pgsql/lib (or another suitable location). *************** *** 77,83 **** pending.so shared library. Modify the arguments to this command if you choose to install the trigger elsewhere. ! 2) Run MirroSetup.sql This file contains SQL commands to setup the Mirroring environment. This includes --- 93,99 ---- pending.so shared library. Modify the arguments to this command if you choose to install the trigger elsewhere. ! 2) Run MirrorSetup.sql This file contains SQL commands to setup the Mirroring environment. This includes *************** *** 93,98 **** --- 109,123 ---- where MyDatabaseName is the name of the database you wish to install mirroring on(Your master). + Postgres-7.1 and 7.2 Notes: + -The syntax for creating a trigger function changed in Postgres-7.3. + Change the line in MirrorSetup.sql from + + CREATE FUNCTION "recordchange" () RETURNS trigger AS + + to + CREATE FUNCTION "recordchange" () RETURNS OPAQUE AS + 3) Create slaveDatabase.conf files. *************** *** 199,204 **** --- 224,230 ---- Mandrake Linux 8.0(Limited Testing) -Postgres 7.2 + -Postgres 7.3 -Perl 5.6 Index: pending.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/contrib/dbmirror/pending.c,v retrieving revision 1.5 diff -w -c -r1.5 pending.c *** pending.c 2002/09/26 05:24:30 1.5 --- pending.c 2002/10/16 23:35:20 *************** *** 22,28 **** #include #include ! enum FieldUsage { PRIMARY = 0, NONPRIMARY, ALL, NUM_FIELDUSAGE --- 22,28 ---- #include #include ! #include enum FieldUsage { PRIMARY = 0, NONPRIMARY, ALL, NUM_FIELDUSAGE *************** *** 46,52 **** #define BUFFER_SIZE 256 #define MAX_OID_LEN 10 ! extern Datum recordchange(PG_FUNCTION_ARGS); --- 46,52 ---- #define BUFFER_SIZE 256 #define MAX_OID_LEN 10 ! #define DEBUG_OUTPUT extern Datum recordchange(PG_FUNCTION_ARGS); *************** *** 69,75 **** HeapTuple retTuple = NULL; char *tblname; char op = 0; ! if (fcinfo->context != NULL) { --- 69,76 ---- HeapTuple retTuple = NULL; char *tblname; char op = 0; ! char *schemaname; ! char *fullyqualtblname; if (fcinfo->context != NULL) { *************** *** 81,86 **** --- 82,97 ---- trigdata = (TriggerData *) fcinfo->context; /* Extract the table name */ tblname = SPI_getrelname(trigdata->tg_relation); + #ifndef NOSCHEMAS + schemaname = get_namespace_name(RelationGetNamespace(trigdata->tg_relation)); + fullyqualtblname = SPI_palloc(strlen(tblname) + + strlen(schemaname) + 4); + sprintf(fullyqualtblname,"\"%s\".\"%s\"", + schemaname,tblname); + #else + fullyqualtblname = SPI_palloc(strlen(tblname+3)); + sprintf(fullyqualtblname,"\"%s\"",tblname); + #endif tupdesc = trigdata->tg_relation->rd_att; if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) { *************** *** 103,109 **** op = 'd'; } ! if (storePending(tblname, beforeTuple, afterTuple, tupdesc, trigdata, op)) { /* An error occoured. Skip the operation. */ elog(ERROR, "Operation could not be mirrored"); --- 114,120 ---- op = 'd'; } ! if (storePending(fullyqualtblname, beforeTuple, afterTuple, tupdesc, trigdata, op)) { /* An error occoured. Skip the operation. */ elog(ERROR, "Operation could not be mirrored"); *************** *** 113,118 **** --- 124,130 ---- #if defined DEBUG_OUTPUT elog(NOTICE, "Returning on success"); #endif + SPI_pfree(fullyqualtblname); SPI_finish(); return PointerGetDatum(retTuple); } *************** *** 417,423 **** #if defined DEBUG_OUTPUT elog(NOTICE, cpFieldName); #endif ! while (iDataBlockSize - iUsedDataBlock < strlen(cpFieldName) + 4) { cpDataBlock = SPI_repalloc(cpDataBlock, iDataBlockSize + BUFFER_SIZE); iDataBlockSize = iDataBlockSize + BUFFER_SIZE; --- 429,435 ---- #if defined DEBUG_OUTPUT elog(NOTICE, cpFieldName); #endif ! while (iDataBlockSize - iUsedDataBlock < strlen(cpFieldName) + 6) { cpDataBlock = SPI_repalloc(cpDataBlock, iDataBlockSize + BUFFER_SIZE); iDataBlockSize = iDataBlockSize + BUFFER_SIZE; *************** *** 436,442 **** } else { ! *cpFormatedPtr = ' '; iUsedDataBlock++; cpFormatedPtr++; continue; --- 448,454 ---- } else { ! sprintf(cpFormatedPtr," "); iUsedDataBlock++; cpFormatedPtr++; continue; *************** *** 484,490 **** if (tpPKeys != NULL) SPI_pfree(tpPKeys); #if defined DEBUG_OUTPUT ! elog(NOTICE, "Returning"); #endif memset(cpDataBlock + iUsedDataBlock, 0, iDataBlockSize - iUsedDataBlock); --- 496,503 ---- if (tpPKeys != NULL) SPI_pfree(tpPKeys); #if defined DEBUG_OUTPUT ! elog(NOTICE, "Returning: DataBlockSize:%d iUsedDataBlock:%d",iDataBlockSize, ! iUsedDataBlock); #endif memset(cpDataBlock + iUsedDataBlock, 0, iDataBlockSize - iUsedDataBlock);