]> granicus.if.org Git - postgresql/commitdiff
It includes
authorBruce Momjian <bruce@momjian.us>
Sat, 19 Oct 2002 02:16:40 +0000 (02:16 +0000)
committerBruce Momjian <bruce@momjian.us>
Sat, 19 Oct 2002 02:16:40 +0000 (02:16 +0000)
-Support for mirroring tables in different Schema's
-Improved documentation for compiling with 7.1.x and 7.2.x
-Fixes a buffer overrun bug.

Steven Singer

contrib/dbmirror/DBMirror.pl
contrib/dbmirror/MirrorSetup.sql
contrib/dbmirror/README.dbmirror
contrib/dbmirror/pending.c

index 9c9f197e9196fdd0bba4de1861c2194fc8ada250..a7c836704576f6fc22b03f605b349d198d7ff293 100755 (executable)
@@ -19,7 +19,7 @@
 #    GNU General Public License for more details.
 #
 ##############################################################################
-# $Id: DBMirror.pl,v 1.2 2002/10/18 18:41:19 momjian Exp $ 
+# $Id: DBMirror.pl,v 1.3 2002/10/19 02:16:40 momjian Exp $ 
 #
 ##############################################################################
 
@@ -387,7 +387,7 @@ sub mirrorInsert($$$$$) {
 
         
     #Now build the insert query.
-    my $insertQuery = "INSERT INTO \"$tableName\" (";
+    my $insertQuery = "INSERT INTO $tableName (";
     my $valuesQuery = ") VALUES (";
     foreach $column (keys (%recordValues)) {
        if($firstIteration==0) {
@@ -468,7 +468,7 @@ sub mirrorDelete($$$$$) {
     %dataHash = extractData($pendingResult,$currentTuple);
 
     my $counter=0;
-    my $deleteQuery = "DELETE FROM \"$tableName\" WHERE ";
+    my $deleteQuery = "DELETE FROM $tableName WHERE ";
     foreach $currentField (keys %dataHash) {
       if($firstField==0) {
        $deleteQuery .= " AND ";
@@ -553,7 +553,7 @@ sub mirrorUpdate($$$$$) {
 
     my $counter;
     my $quotedValue;
-    my $updateQuery = "UPDATE \"$tableName\" SET ";
+    my $updateQuery = "UPDATE $tableName SET ";
     my $currentField;
 
 
index 7597318411bbdbbb92282cceac6f35420fb515c1..7f54fa29672761c2dc2353a2c507e0f6326fcc60 100644 (file)
@@ -6,7 +6,8 @@ CREATE FUNCTION "recordchange" () RETURNS trigger AS
 
 CREATE TABLE "MirrorHost" (
 "MirrorHostId" serial,
-"HostName" varchar NOT NULL
+"HostName" varchar NOT NULL,
+PRIMARY KEY("MirrorHostId")
 );
 
 
index 32eb7842764119dd0249f9ae97c3804b6f695dde..397bc08ad7d6a4a9581af4fd6ff288d7ed9f544d 100644 (file)
@@ -46,6 +46,7 @@ Pending tables.
 Installation Instructions
 ------------------------------------------------------------------------
 
+
 1) Compile pending.c
 
 The file pending.c contains the recordchange trigger.  This runs every
@@ -54,20 +55,35 @@ time a row inside of a table being mirrored changes.
 
 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.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 Makefile to reflect this.
+  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.
 
-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.
+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).
 
@@ -93,6 +109,15 @@ To execute the script use psql as follows
 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,6 +224,7 @@ RedHat Linux 7.1 & 6.2
 
 Mandrake Linux 8.0(Limited Testing)
  -Postgres 7.2
+ -Postgres 7.3
  -Perl 5.6
 
 
index 911cd7ab47fc42e5c7d451a97aa738d96e8c3a20..e8d2346f783b85cd39dda082e45cbb6f7e6be474 100644 (file)
@@ -1,6 +1,6 @@
 /****************************************************************************
  * pending.c
- * $Id: pending.c,v 1.5 2002/09/26 05:24:30 momjian Exp $
+ * $Id: pending.c,v 1.6 2002/10/19 02:16:40 momjian Exp $
  *
  * This file contains a trigger for Postgresql-7.x to record changes to tables
  * to a pending table for mirroring.
@@ -22,7 +22,7 @@
 
 #include <executor/spi.h>
 #include <commands/trigger.h>
-
+#include <utils/lsyscache.h>
 enum FieldUsage
 {
        PRIMARY = 0, NONPRIMARY, ALL, NUM_FIELDUSAGE
@@ -46,7 +46,7 @@ char *packageData(HeapTuple tTupleData, TupleDesc tTupleDecs,
 
 #define BUFFER_SIZE 256
 #define MAX_OID_LEN 10
-
+#define DEBUG_OUTPUT
 
 extern Datum recordchange(PG_FUNCTION_ARGS);
 
@@ -69,7 +69,8 @@ recordchange(PG_FUNCTION_ARGS)
        HeapTuple       retTuple = NULL;
        char       *tblname;
        char            op = 0;
-
+       char       *schemaname;
+       char       *fullyqualtblname;
        if (fcinfo->context != NULL)
        {
 
@@ -81,6 +82,16 @@ recordchange(PG_FUNCTION_ARGS)
                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,7 +114,7 @@ recordchange(PG_FUNCTION_ARGS)
                        op = 'd';
                }
 
-               if (storePending(tblname, beforeTuple, afterTuple, tupdesc, trigdata, op))
+               if (storePending(fullyqualtblname, beforeTuple, afterTuple, tupdesc, trigdata, op))
                {
                        /* An error occoured. Skip the operation. */
                        elog(ERROR, "Operation could not be mirrored");
@@ -113,6 +124,7 @@ recordchange(PG_FUNCTION_ARGS)
 #if defined DEBUG_OUTPUT
                elog(NOTICE, "Returning on success");
 #endif
+               SPI_pfree(fullyqualtblname);
                SPI_finish();
                return PointerGetDatum(retTuple);
        }
@@ -417,7 +429,7 @@ packageData(HeapTuple tTupleData, TupleDesc tTupleDesc,
 #if defined DEBUG_OUTPUT
                elog(NOTICE, cpFieldName);
 #endif
-               while (iDataBlockSize - iUsedDataBlock < strlen(cpFieldName) + 4)
+               while (iDataBlockSize - iUsedDataBlock < strlen(cpFieldName) + 6)
                {
                        cpDataBlock = SPI_repalloc(cpDataBlock, iDataBlockSize + BUFFER_SIZE);
                        iDataBlockSize = iDataBlockSize + BUFFER_SIZE;
@@ -436,7 +448,7 @@ packageData(HeapTuple tTupleData, TupleDesc tTupleDesc,
                }
                else
                {
-                       *cpFormatedPtr = ' ';
+                       sprintf(cpFormatedPtr," ");
                        iUsedDataBlock++;
                        cpFormatedPtr++;
                        continue;
@@ -484,7 +496,8 @@ packageData(HeapTuple tTupleData, TupleDesc tTupleDesc,
        if (tpPKeys != NULL)
                SPI_pfree(tpPKeys);
 #if defined DEBUG_OUTPUT
-       elog(NOTICE, "Returning");
+       elog(NOTICE, "Returning: DataBlockSize:%d iUsedDataBlock:%d",iDataBlockSize,
+                       iUsedDataBlock);
 #endif
        memset(cpDataBlock + iUsedDataBlock, 0, iDataBlockSize - iUsedDataBlock);