It includes

-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
This commit is contained in:
Bruce Momjian 2002-10-19 02:16:40 +00:00
parent cabad378fc
commit 8e6b5c8b27
4 changed files with 60 additions and 20 deletions

View File

@ -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;

View 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")
);

View 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.
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.
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 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

View 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);