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:
parent
cabad378fc
commit
8e6b5c8b27
@ -19,7 +19,7 @@
|
|||||||
# GNU General Public License for more details.
|
# 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.
|
#Now build the insert query.
|
||||||
my $insertQuery = "INSERT INTO \"$tableName\" (";
|
my $insertQuery = "INSERT INTO $tableName (";
|
||||||
my $valuesQuery = ") VALUES (";
|
my $valuesQuery = ") VALUES (";
|
||||||
foreach $column (keys (%recordValues)) {
|
foreach $column (keys (%recordValues)) {
|
||||||
if($firstIteration==0) {
|
if($firstIteration==0) {
|
||||||
@ -468,7 +468,7 @@ sub mirrorDelete($$$$$) {
|
|||||||
%dataHash = extractData($pendingResult,$currentTuple);
|
%dataHash = extractData($pendingResult,$currentTuple);
|
||||||
|
|
||||||
my $counter=0;
|
my $counter=0;
|
||||||
my $deleteQuery = "DELETE FROM \"$tableName\" WHERE ";
|
my $deleteQuery = "DELETE FROM $tableName WHERE ";
|
||||||
foreach $currentField (keys %dataHash) {
|
foreach $currentField (keys %dataHash) {
|
||||||
if($firstField==0) {
|
if($firstField==0) {
|
||||||
$deleteQuery .= " AND ";
|
$deleteQuery .= " AND ";
|
||||||
@ -553,7 +553,7 @@ sub mirrorUpdate($$$$$) {
|
|||||||
|
|
||||||
my $counter;
|
my $counter;
|
||||||
my $quotedValue;
|
my $quotedValue;
|
||||||
my $updateQuery = "UPDATE \"$tableName\" SET ";
|
my $updateQuery = "UPDATE $tableName SET ";
|
||||||
my $currentField;
|
my $currentField;
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,8 @@ CREATE FUNCTION "recordchange" () RETURNS trigger AS
|
|||||||
|
|
||||||
CREATE TABLE "MirrorHost" (
|
CREATE TABLE "MirrorHost" (
|
||||||
"MirrorHostId" serial,
|
"MirrorHostId" serial,
|
||||||
"HostName" varchar NOT NULL
|
"HostName" varchar NOT NULL,
|
||||||
|
PRIMARY KEY("MirrorHostId")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ Pending tables.
|
|||||||
Installation Instructions
|
Installation Instructions
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
1) Compile pending.c
|
1) Compile pending.c
|
||||||
|
|
||||||
The file pending.c contains the recordchange trigger. This runs every
|
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.
|
To build the trigger run make on the "Makefile" in the DBMirror directory.
|
||||||
|
|
||||||
The Makefile supplied assumes that the postgres include files are in
|
Postgres-7.3 Make Instructions:
|
||||||
/usr/local/pgsql/include/server.
|
|
||||||
|
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
|
Postgres-7.1.x installations should change this to
|
||||||
/usr/local/pgsql/include (The server part is for 7.2+)
|
/usr/local/pgsql/include (The server part is for 7.2+)
|
||||||
|
|
||||||
If you have installed the postgres include files to another location then
|
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
|
Compiling the trigger by hand requires that all postgres headers be installed
|
||||||
accomplished in postgresql(7.1 or 7.2) by running "make install-all-headers"
|
,this is accomplished in postgresql(7.1 or 7.2) by running
|
||||||
in the postgres source directory.
|
"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).
|
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
|
where MyDatabaseName is the name of the database you wish to install mirroring
|
||||||
on(Your master).
|
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.
|
3) Create slaveDatabase.conf files.
|
||||||
|
|
||||||
@ -199,6 +224,7 @@ RedHat Linux 7.1 & 6.2
|
|||||||
|
|
||||||
Mandrake Linux 8.0(Limited Testing)
|
Mandrake Linux 8.0(Limited Testing)
|
||||||
-Postgres 7.2
|
-Postgres 7.2
|
||||||
|
-Postgres 7.3
|
||||||
-Perl 5.6
|
-Perl 5.6
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* pending.c
|
* 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
|
* This file contains a trigger for Postgresql-7.x to record changes to tables
|
||||||
* to a pending table for mirroring.
|
* to a pending table for mirroring.
|
||||||
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include <executor/spi.h>
|
#include <executor/spi.h>
|
||||||
#include <commands/trigger.h>
|
#include <commands/trigger.h>
|
||||||
|
#include <utils/lsyscache.h>
|
||||||
enum FieldUsage
|
enum FieldUsage
|
||||||
{
|
{
|
||||||
PRIMARY = 0, NONPRIMARY, ALL, NUM_FIELDUSAGE
|
PRIMARY = 0, NONPRIMARY, ALL, NUM_FIELDUSAGE
|
||||||
@ -46,7 +46,7 @@ char *packageData(HeapTuple tTupleData, TupleDesc tTupleDecs,
|
|||||||
|
|
||||||
#define BUFFER_SIZE 256
|
#define BUFFER_SIZE 256
|
||||||
#define MAX_OID_LEN 10
|
#define MAX_OID_LEN 10
|
||||||
|
#define DEBUG_OUTPUT
|
||||||
|
|
||||||
extern Datum recordchange(PG_FUNCTION_ARGS);
|
extern Datum recordchange(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
@ -69,7 +69,8 @@ recordchange(PG_FUNCTION_ARGS)
|
|||||||
HeapTuple retTuple = NULL;
|
HeapTuple retTuple = NULL;
|
||||||
char *tblname;
|
char *tblname;
|
||||||
char op = 0;
|
char op = 0;
|
||||||
|
char *schemaname;
|
||||||
|
char *fullyqualtblname;
|
||||||
if (fcinfo->context != NULL)
|
if (fcinfo->context != NULL)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -81,6 +82,16 @@ recordchange(PG_FUNCTION_ARGS)
|
|||||||
trigdata = (TriggerData *) fcinfo->context;
|
trigdata = (TriggerData *) fcinfo->context;
|
||||||
/* Extract the table name */
|
/* Extract the table name */
|
||||||
tblname = SPI_getrelname(trigdata->tg_relation);
|
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;
|
tupdesc = trigdata->tg_relation->rd_att;
|
||||||
if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
|
if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
|
||||||
{
|
{
|
||||||
@ -103,7 +114,7 @@ recordchange(PG_FUNCTION_ARGS)
|
|||||||
op = 'd';
|
op = 'd';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (storePending(tblname, beforeTuple, afterTuple, tupdesc, trigdata, op))
|
if (storePending(fullyqualtblname, beforeTuple, afterTuple, tupdesc, trigdata, op))
|
||||||
{
|
{
|
||||||
/* An error occoured. Skip the operation. */
|
/* An error occoured. Skip the operation. */
|
||||||
elog(ERROR, "Operation could not be mirrored");
|
elog(ERROR, "Operation could not be mirrored");
|
||||||
@ -113,6 +124,7 @@ recordchange(PG_FUNCTION_ARGS)
|
|||||||
#if defined DEBUG_OUTPUT
|
#if defined DEBUG_OUTPUT
|
||||||
elog(NOTICE, "Returning on success");
|
elog(NOTICE, "Returning on success");
|
||||||
#endif
|
#endif
|
||||||
|
SPI_pfree(fullyqualtblname);
|
||||||
SPI_finish();
|
SPI_finish();
|
||||||
return PointerGetDatum(retTuple);
|
return PointerGetDatum(retTuple);
|
||||||
}
|
}
|
||||||
@ -417,7 +429,7 @@ packageData(HeapTuple tTupleData, TupleDesc tTupleDesc,
|
|||||||
#if defined DEBUG_OUTPUT
|
#if defined DEBUG_OUTPUT
|
||||||
elog(NOTICE, cpFieldName);
|
elog(NOTICE, cpFieldName);
|
||||||
#endif
|
#endif
|
||||||
while (iDataBlockSize - iUsedDataBlock < strlen(cpFieldName) + 4)
|
while (iDataBlockSize - iUsedDataBlock < strlen(cpFieldName) + 6)
|
||||||
{
|
{
|
||||||
cpDataBlock = SPI_repalloc(cpDataBlock, iDataBlockSize + BUFFER_SIZE);
|
cpDataBlock = SPI_repalloc(cpDataBlock, iDataBlockSize + BUFFER_SIZE);
|
||||||
iDataBlockSize = iDataBlockSize + BUFFER_SIZE;
|
iDataBlockSize = iDataBlockSize + BUFFER_SIZE;
|
||||||
@ -436,7 +448,7 @@ packageData(HeapTuple tTupleData, TupleDesc tTupleDesc,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*cpFormatedPtr = ' ';
|
sprintf(cpFormatedPtr," ");
|
||||||
iUsedDataBlock++;
|
iUsedDataBlock++;
|
||||||
cpFormatedPtr++;
|
cpFormatedPtr++;
|
||||||
continue;
|
continue;
|
||||||
@ -484,7 +496,8 @@ packageData(HeapTuple tTupleData, TupleDesc tTupleDesc,
|
|||||||
if (tpPKeys != NULL)
|
if (tpPKeys != NULL)
|
||||||
SPI_pfree(tpPKeys);
|
SPI_pfree(tpPKeys);
|
||||||
#if defined DEBUG_OUTPUT
|
#if defined DEBUG_OUTPUT
|
||||||
elog(NOTICE, "Returning");
|
elog(NOTICE, "Returning: DataBlockSize:%d iUsedDataBlock:%d",iDataBlockSize,
|
||||||
|
iUsedDataBlock);
|
||||||
#endif
|
#endif
|
||||||
memset(cpDataBlock + iUsedDataBlock, 0, iDataBlockSize - iUsedDataBlock);
|
memset(cpDataBlock + iUsedDataBlock, 0, iDataBlockSize - iUsedDataBlock);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user