57 |
{ |
{ |
58 |
my ($mconn, $sconn, $outf, $mserver, $sserver, $onlytables) = @_; |
my ($mconn, $sconn, $outf, $mserver, $sserver, $onlytables) = @_; |
59 |
|
|
|
print STDERR "## d: $debug v: $verbose q: $quiet\n"; |
|
|
|
|
60 |
if ($mserver == $sserver) { |
if ($mserver == $sserver) { |
61 |
print STDERR "master and slave numbers are same [$mserver] !\n"; |
print STDERR "master and slave numbers are same [$mserver] !\n"; |
62 |
return(-1); |
return(-1); |
65 |
print "PrepareSnapshot master: $mserver slave: $sserver\n" if ($debug); |
print "PrepareSnapshot master: $mserver slave: $sserver\n" if ($debug); |
66 |
|
|
67 |
# first, we must know for wich tables the slave subscribed |
# first, we must know for wich tables the slave subscribed |
68 |
my $result = $sconn->exec("SELECT tname FROM _RSERV_SLAVE_TABLES_"); |
my $result = Exec($sconn,"SELECT tname FROM _RSERV_SLAVE_TABLES_", -1); |
69 |
if ($result->resultStatus ne PGRES_TUPLES_OK) |
return (-1) if ($result == -1); |
70 |
{ |
|
|
print STDERR $mconn->errorMessage unless ($quiet); |
|
|
return(-1); |
|
|
} |
|
|
|
|
71 |
my @row; |
my @row; |
72 |
while (@row = $result->fetchrow) { |
while (@row = $result->fetchrow) { |
73 |
$Stables{$row[0]} = 1; |
$Stables{$row[0]} = 1; |
75 |
|
|
76 |
print "Prepare snapshot for tables: ",join(",",keys %Stables),"\n" if ($debug); |
print "Prepare snapshot for tables: ",join(",",keys %Stables),"\n" if ($debug); |
77 |
|
|
78 |
$result = $mconn->exec("BEGIN"); |
Exec($mconn,"BEGIN"); |
79 |
if ($result->resultStatus ne PGRES_COMMAND_OK) |
Exec($mconn,"set transaction isolation level serializable"); |
|
{ |
|
|
print STDERR $mconn->errorMessage unless ($quiet); |
|
|
$mconn->exec("ROLLBACK"); |
|
|
return(-1); |
|
|
} |
|
|
$result = $mconn->exec("set transaction isolation level serializable"); |
|
|
if ($result->resultStatus ne PGRES_COMMAND_OK) |
|
|
{ |
|
|
print STDERR $mconn->errorMessage unless ($quiet); |
|
|
$mconn->exec("ROLLBACK"); |
|
|
return(-1); |
|
|
} |
|
80 |
|
|
81 |
# MAP oid --> tabname, keyname, key_type |
# MAP oid --> tabname, keyname, key_type |
82 |
$result = $mconn->exec("select pgc.oid, pgc.relname, pga.attname, pgt.typname" . |
my $sql = qq{ |
83 |
" from _RSERV_TABLES_ rt, pg_class pgc, pg_attribute pga" . |
select pgc.oid, pgc.relname, pga.attname, pgt.typname |
84 |
", pg_type pgt". |
from _RSERV_TABLES_ rt, pg_class pgc, pg_attribute pga, |
85 |
" where pgc.oid = rt.reloid AND pga.attrelid = rt.reloid" . |
pg_type pgt |
86 |
" AND pga.attnum = rt.key AND pga.atttypid=pgt.oid"); |
where pgc.oid = rt.reloid AND pga.attrelid = rt.reloid |
87 |
if ($result->resultStatus ne PGRES_TUPLES_OK) |
AND pga.attnum = rt.key AND pga.atttypid=pgt.oid |
88 |
{ |
}; |
89 |
print STDERR $mconn->errorMessage unless ($quiet); |
$result = Exec($mconn,$sql); |
90 |
$mconn->exec("ROLLBACK"); |
|
|
return(-1); |
|
|
} |
|
|
|
|
91 |
while (@row = $result->fetchrow) |
while (@row = $result->fetchrow) |
92 |
{ |
{ |
93 |
# printf "$row[0], $row[1], $row[2]\n"; |
# printf "$row[0], $row[1], $row[2]\n"; |
99 |
} |
} |
100 |
|
|
101 |
print "Master database table oids: ",join(",",keys %Mtables),"\n" if ($debug); |
print "Master database table oids: ",join(",",keys %Mtables),"\n" if ($debug); |
102 |
|
if (! %Mtables) { |
103 |
|
print STDERR "FATAL: can't find oids for tables in master! Did you run SlaveAddTable?\n"; |
104 |
|
RollbackAndQuit($mconn); |
105 |
|
} |
106 |
|
|
107 |
# Read last succeeded sync |
# Read last succeeded sync |
108 |
my $sql = "select syncid, synctime, minid, maxid, active from _RSERV_SYNC_" . |
$sql = qq{ |
109 |
" where server = $sserver AND syncid = (select max(syncid) from" . |
select syncid, synctime, minid, maxid, active from _RSERV_SYNC_ |
110 |
" _RSERV_SYNC_ where server = $sserver AND status > 0)"; |
where server = $sserver AND syncid = |
111 |
|
(select max(syncid) from _RSERV_SYNC_ |
112 |
|
where server = $sserver AND status > 0) |
113 |
|
}; |
114 |
|
|
115 |
printf "$sql\n" if $debug; |
$result = Exec($mconn,$sql); |
|
|
|
|
$result = $mconn->exec($sql); |
|
|
if ($result->resultStatus ne PGRES_TUPLES_OK) |
|
|
{ |
|
|
print STDERR $mconn->errorMessage unless ($quiet); |
|
|
$mconn->exec("ROLLBACK"); |
|
|
return(-1); |
|
|
} |
|
116 |
|
|
117 |
my @lastsync = $result->fetchrow; |
my @lastsync = $result->fetchrow; |
118 |
print "lastsync: ",join(",",@lastsync),"\n" if ($debug); |
print "lastsync: ",join(",",@lastsync),"\n" if ($debug); |
995 |
sub Rollback { |
sub Rollback { |
996 |
my $conn = shift @_; |
my $conn = shift @_; |
997 |
|
|
998 |
print STDERR $conn->errorMessage; |
print STDERR $conn->errorMessage unless ($quiet); |
999 |
$conn->exec("ROLLBACK"); |
$conn->exec("ROLLBACK"); |
1000 |
} |
} |
1001 |
|
|
1019 |
} |
} |
1020 |
|
|
1021 |
sub Exec { |
sub Exec { |
1022 |
my $conn = shift @_; |
my $conn = shift || die "Exec needs connection!"; |
1023 |
my $sql = shift @_; |
my $sql = shift || die "Exec needs SQL statement!"; |
1024 |
|
# used to return error code if no tuples are retured |
1025 |
|
my $return_code = shift; |
1026 |
|
|
1027 |
|
if ($debug) { |
1028 |
|
# re-format SQL in one line (for nicer output) |
1029 |
|
$sql =~ s/[\s\n\r]+/ /gs; |
1030 |
|
print STDERR "Exec: $sql\n"; |
1031 |
|
} |
1032 |
my $result = $conn->exec($sql); |
my $result = $conn->exec($sql); |
1033 |
print STDERR "$sql\n" if ($debug); |
if ($result->resultStatus eq PGRES_COMMAND_OK) { |
1034 |
RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); |
return; |
1035 |
|
} elsif ($result->resultStatus eq PGRES_TUPLES_OK) { |
1036 |
|
print STDERR "Returned ",$result->ntuples," tuples\n" if ($debug); |
1037 |
|
return $result; |
1038 |
|
} else { |
1039 |
|
if (defined($return_code)) { |
1040 |
|
print STDERR "ERROR: ",$conn->errorMessage,"\n" unless ($quiet); |
1041 |
|
return($return_code); |
1042 |
|
} else { |
1043 |
|
RollbackAndQuit($conn) |
1044 |
|
} |
1045 |
|
} |
1046 |
} |
} |
1047 |
|
|
1048 |
sub Exec2 { |
sub Exec2 { |
1054 |
RollbackAndQuit($mconn) if ($result->resultStatus ne PGRES_COMMAND_OK); |
RollbackAndQuit($mconn) if ($result->resultStatus ne PGRES_COMMAND_OK); |
1055 |
$result = $sconn->exec($sql); |
$result = $sconn->exec($sql); |
1056 |
RollbackAndQuit($sconn) if ($result->resultStatus ne PGRES_COMMAND_OK); |
RollbackAndQuit($sconn) if ($result->resultStatus ne PGRES_COMMAND_OK); |
1057 |
|
# XXX TODO: return results?! |
1058 |
} |
} |
1059 |
|
|
1060 |
sub MkInfo { |
sub MkInfo { |