mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Apply patch from Steven Singer for contrib/dbmirror. Changes:
-It fixes up some bugs with handling setval calls -Adds upgrade instructions from prior versions -Improved the sample config file -Fixed some things in the clean_pending script
This commit is contained in:
@ -1,6 +1,5 @@
|
|||||||
BEGIN;
|
BEGIN;
|
||||||
|
|
||||||
SET autocommit TO 'on';
|
|
||||||
|
|
||||||
CREATE FUNCTION "recordchange" () RETURNS trigger AS
|
CREATE FUNCTION "recordchange" () RETURNS trigger AS
|
||||||
'$libdir/pending.so', 'recordchange' LANGUAGE 'C';
|
'$libdir/pending.so', 'recordchange' LANGUAGE 'C';
|
||||||
@ -25,7 +24,7 @@ XID int4 NOT NULL,
|
|||||||
PRIMARY KEY (SeqId)
|
PRIMARY KEY (SeqId)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX "dbmirror_Pending_XID_Index" ON dbmirror_Pending (XID);
|
CREATE INDEX dbmirror_Pending_XID_Index ON dbmirror_Pending (XID);
|
||||||
|
|
||||||
CREATE TABLE dbmirror_PendingData (
|
CREATE TABLE dbmirror_PendingData (
|
||||||
SeqId int4 NOT NULL,
|
SeqId int4 NOT NULL,
|
||||||
@ -50,12 +49,14 @@ CASCADE ON DELETE CASCADE
|
|||||||
UPDATE pg_proc SET proname='nextval_pg' WHERE proname='nextval';
|
UPDATE pg_proc SET proname='nextval_pg' WHERE proname='nextval';
|
||||||
|
|
||||||
CREATE FUNCTION pg_catalog.nextval(text) RETURNS int8 AS
|
CREATE FUNCTION pg_catalog.nextval(text) RETURNS int8 AS
|
||||||
'/usr/local/postgresql-7.4/lib/pending.so', 'nextval' LANGUAGE 'C' STRICT;
|
'$libdir/pending.so', 'nextval' LANGUAGE 'C' STRICT;
|
||||||
|
|
||||||
|
|
||||||
UPDATE pg_proc set proname='setval_pg' WHERE proname='setval';
|
UPDATE pg_proc set proname='setval_pg' WHERE proname='setval';
|
||||||
|
|
||||||
CREATE FUNCTION pg_catalog.setval(text,int4) RETURNS int8 AS
|
CREATE FUNCTION pg_catalog.setval("unknown",integer,boolean) RETURNS int8 AS
|
||||||
'/usr/local/postgresql-7.4/lib/pending.so', 'setval' LANGUAGE 'C' STRICT;
|
'$libdir/pending.so', 'setval' LANGUAGE 'C' STRICT;
|
||||||
|
CREATE FUNCTION pg_catalog.setval("unknown",integer) RETURNS int8 AS
|
||||||
|
'$libdir/pending.so', 'setval' LANGUAGE 'C' STRICT;
|
||||||
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
@ -61,10 +61,29 @@ Requirments:
|
|||||||
-PgPerl (http://gborg.postgresql.org/project/pgperl/projdisplay.php)
|
-PgPerl (http://gborg.postgresql.org/project/pgperl/projdisplay.php)
|
||||||
|
|
||||||
|
|
||||||
|
Upgrading from versions prior to 8.0
|
||||||
|
---------------------------------------
|
||||||
|
Users upgrading from a version of dbmirror prior to the one shipped with
|
||||||
|
Postgresql 8.0 will need to perform the following steps
|
||||||
|
|
||||||
|
1. Dump the database then drop it (dropdb no not use the -C option)
|
||||||
|
2. Create database with createdb.
|
||||||
|
3. Run psql databasename -f MirrorSetup.sql
|
||||||
|
4. Restore the database(do not use the -C option of pg_dump/pg_restore)
|
||||||
|
5. run the SQL commands: DROP "Pending";DROP "PendingData"; DROP "MirrorHost";
|
||||||
|
DROP "MirroredTransaction";
|
||||||
|
|
||||||
|
The above steps are needed A) Because the names of the tables used by dbmirror
|
||||||
|
to store data have changed and B) In order for sequences to be mirrored properly
|
||||||
|
all serial types must be recreated.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# $PostgreSQL: pgsql/contrib/dbmirror/clean_pending.pl,v 1.4 2003/11/29 22:39:19 pgsql Exp $
|
# $PostgreSQL: pgsql/contrib/dbmirror/clean_pending.pl,v 1.5 2004/09/10 04:31:06 neilc Exp $
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
|
||||||
@ -77,13 +77,13 @@ unless($result->resultStatus == PGRES_COMMAND_OK) {
|
|||||||
|
|
||||||
#delete all transactions that have been sent to all mirrorhosts
|
#delete all transactions that have been sent to all mirrorhosts
|
||||||
#or delete everything if no mirror hosts are defined.
|
#or delete everything if no mirror hosts are defined.
|
||||||
# Postgres takes the "SELECT COUNT(*) FROM "MirrorHost" and makes it into
|
# Postgres takes the "SELECT COUNT(*) FROM dbmirror_MirrorHost and makes it into
|
||||||
# an InitPlan. EXPLAIN show's this.
|
# an InitPlan. EXPLAIN show's this.
|
||||||
my $deletePendingQuery = 'DELETE FROM "Pending" WHERE (SELECT ';
|
my $deletePendingQuery = 'DELETE FROM dbmirror_Pending WHERE (SELECT ';
|
||||||
$deletePendingQuery .= ' COUNT(*) FROM "MirroredTransaction" WHERE ';
|
$deletePendingQuery .= ' COUNT(*) FROM dbmirror_MirroredTransaction WHERE ';
|
||||||
$deletePendingQuery .= ' "XID"="Pending"."XID") = (SELECT COUNT(*) FROM ';
|
$deletePendingQuery .= ' XID=dbmirror_Pending.XID) = (SELECT COUNT(*) FROM ';
|
||||||
$deletePendingQuery .= ' "MirrorHost") OR (SELECT COUNT(*) FROM ';
|
$deletePendingQuery .= ' dbmirror_MirrorHost) OR (SELECT COUNT(*) FROM ';
|
||||||
$deletePendingQuery .= ' "MirrorHost") = 0';
|
$deletePendingQuery .= ' dbmirror_MirrorHost) = 0';
|
||||||
|
|
||||||
my $result = $dbConn->exec($deletePendingQuery);
|
my $result = $dbConn->exec($deletePendingQuery);
|
||||||
unless ($result->resultStatus == PGRES_COMMAND_OK ) {
|
unless ($result->resultStatus == PGRES_COMMAND_OK ) {
|
||||||
@ -91,15 +91,15 @@ unless ($result->resultStatus == PGRES_COMMAND_OK ) {
|
|||||||
die;
|
die;
|
||||||
}
|
}
|
||||||
$dbConn->exec("COMMIT");
|
$dbConn->exec("COMMIT");
|
||||||
$result = $dbConn->exec('VACUUM "Pending"');
|
$result = $dbConn->exec('VACUUM dbmirror_Pending');
|
||||||
unless ($result->resultStatus == PGRES_COMMAND_OK) {
|
unless ($result->resultStatus == PGRES_COMMAND_OK) {
|
||||||
printf($dbConn->errorMessage);
|
printf($dbConn->errorMessage);
|
||||||
}
|
}
|
||||||
$result = $dbConn->exec('VACUUM "PendingData"');
|
$result = $dbConn->exec('VACUUM dbmirror_PendingData');
|
||||||
unless($result->resultStatus == PGRES_COMMAND_OK) {
|
unless($result->resultStatus == PGRES_COMMAND_OK) {
|
||||||
printf($dbConn->errorMessage);
|
printf($dbConn->errorMessage);
|
||||||
}
|
}
|
||||||
$result = $dbConn->exec('VACUUM "MirroredTransaction"');
|
$result = $dbConn->exec('VACUUM dbmirror_MirroredTransaction');
|
||||||
unless($result->resultStatus == PGRES_COMMAND_OK) {
|
unless($result->resultStatus == PGRES_COMMAND_OK) {
|
||||||
printf($dbConn->errorMessage);
|
printf($dbConn->errorMessage);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* pending.c
|
* pending.c
|
||||||
* $Id: pending.c,v 1.19 2004/08/29 05:06:35 momjian Exp $
|
* $Id: pending.c,v 1.20 2004/09/10 04:31:06 neilc Exp $
|
||||||
* $PostgreSQL: pgsql/contrib/dbmirror/pending.c,v 1.19 2004/08/29 05:06:35 momjian Exp $
|
* $PostgreSQL: pgsql/contrib/dbmirror/pending.c,v 1.20 2004/09/10 04:31:06 neilc 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.
|
||||||
@ -63,7 +63,7 @@ char *packageData(HeapTuple tTupleData, TupleDesc tTupleDecs, Oid tableOid,
|
|||||||
|
|
||||||
#define BUFFER_SIZE 256
|
#define BUFFER_SIZE 256
|
||||||
#define MAX_OID_LEN 10
|
#define MAX_OID_LEN 10
|
||||||
#define DEBUG_OUTPUT 1
|
/*#define DEBUG_OUTPUT 1 */
|
||||||
extern Datum recordchange(PG_FUNCTION_ARGS);
|
extern Datum recordchange(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
PG_FUNCTION_INFO_V1(recordchange);
|
PG_FUNCTION_INFO_V1(recordchange);
|
||||||
@ -596,18 +596,28 @@ setval(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
text *sequenceName;
|
text *sequenceName;
|
||||||
|
|
||||||
Oid setvalArgTypes[2] = {TEXTOID, INT4OID};
|
Oid setvalArgTypes[3] = {TEXTOID, INT4OID,BOOLOID};
|
||||||
int nextValue;
|
int nextValue;
|
||||||
void *setvalPlan = NULL;
|
void *setvalPlan = NULL;
|
||||||
Datum setvalData[2];
|
Datum setvalData[3];
|
||||||
const char *setvalQuery = "SELECT setval_pg($1,$2)";
|
const char *setvalQuery = "SELECT setval_pg($1,$2,$3)";
|
||||||
int ret;
|
int ret;
|
||||||
|
char is_called;
|
||||||
|
|
||||||
sequenceName = PG_GETARG_TEXT_P(0);
|
sequenceName = PG_GETARG_TEXT_P(0);
|
||||||
nextValue = PG_GETARG_INT32(1);
|
nextValue = PG_GETARG_INT32(1);
|
||||||
|
is_called = PG_GETARG_BOOL(2);
|
||||||
|
|
||||||
setvalData[0] = PointerGetDatum(sequenceName);
|
setvalData[0] = PointerGetDatum(sequenceName);
|
||||||
setvalData[1] = Int32GetDatum(nextValue);
|
setvalData[1] = Int32GetDatum(nextValue);
|
||||||
|
if(PG_NARGS() > 2)
|
||||||
|
{
|
||||||
|
setvalData[2] = BoolGetDatum(is_called);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setvalData[2]=1;
|
||||||
|
}
|
||||||
|
|
||||||
if (SPI_connect() < 0)
|
if (SPI_connect() < 0)
|
||||||
{
|
{
|
||||||
@ -616,7 +626,7 @@ setval(PG_FUNCTION_ARGS)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
setvalPlan = SPI_prepare(setvalQuery, 2, setvalArgTypes);
|
setvalPlan = SPI_prepare(setvalQuery, 3, setvalArgTypes);
|
||||||
if (setvalPlan == NULL)
|
if (setvalPlan == NULL)
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
|
ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
# It contains configuration information to mirror data from
|
# It contains configuration information to mirror data from
|
||||||
# the master database to a single slave system.
|
# the master database to a single slave system.
|
||||||
#
|
#
|
||||||
# $PostgreSQL: pgsql/contrib/dbmirror/slaveDatabase.conf,v 1.2 2003/11/29 22:39:19 pgsql Exp $
|
# $PostgreSQL: pgsql/contrib/dbmirror/slaveDatabase.conf,v 1.3 2004/09/10 04:31:06 neilc Exp $
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
$masterHost = "masterMachine.mydomain.com";
|
$masterHost = "masterMachine.mydomain.com";
|
||||||
@ -15,8 +15,21 @@ $masterPassword = "postgrespassword";
|
|||||||
# Where to email Error messages to
|
# Where to email Error messages to
|
||||||
# $errorEmailAddr = "me@mydomain.com";
|
# $errorEmailAddr = "me@mydomain.com";
|
||||||
|
|
||||||
|
$slaveInfo->{"slaveName"} = "backupMachine";
|
||||||
$slaveInfo->{"slaveHost"} = "backupMachine.mydomain.com";
|
$slaveInfo->{"slaveHost"} = "backupMachine.mydomain.com";
|
||||||
$slaveInfo->{"slaveDb"} = "myDatabase";
|
$slaveInfo->{"slaveDb"} = "myDatabase";
|
||||||
|
$slaveInfo->{"slavePort"} = 5432;
|
||||||
$slaveInfo->{"slaveUser"} = "postgres";
|
$slaveInfo->{"slaveUser"} = "postgres";
|
||||||
$slaveInfo->{"slavePassword"} = "postgrespassword";
|
$slaveInfo->{"slavePassword"} = "postgrespassword";
|
||||||
|
# If uncommented then text files with SQL statements are generated instead
|
||||||
|
# of connecting to the slave database directly.
|
||||||
|
# slaveDb should then be commented out.
|
||||||
|
# $slaveInfo{"TransactionFileDirectory"} = '/tmp';
|
||||||
|
|
||||||
|
#
|
||||||
|
# The number of seconds dbmirror should sleep for between checking to see
|
||||||
|
# if more data is ready to be mirrored.
|
||||||
|
$sleepInterval = 60;
|
||||||
|
|
||||||
|
#If you want to use syslog
|
||||||
|
# $syslog = 1;
|
||||||
|
Reference in New Issue
Block a user