CVS User Account cvsuser
Tue Feb 22 04:14:07 PST 2005
Log Message:
-----------
Purge out slonspool area that is obsolete

Removed Files:
-------------
    slony1-engine/src/slonspool:
        NOTES
        README
        Tasks
        gen_output.pm
        init.pm
        slonspool.pl
        subscribe.pm

-------------- next part --------------
--- src/slonspool/Tasks
+++ /dev/null
@@ -1,45 +0,0 @@
-1.  Modifications to DB Schema
-
-sl_node needs a new boolean field, no_spool
-
-  alter table @NAMESPACE at .sl_node add column no_spool boolean default 'f';
-
-  comment on column @NAMESPACE at .sl_node.no_spool is
-    'Value is t if this node is a Log Shipping/Spooling node which does not communicate with other nodes.';
-
-2.  Modifications to stored functions
-
-  Numerous functions that do node-based things need to reject updates on nodes where no_spool = 't':
-
-  - moveset() and moveset_int() cannot move set to a node where no_spool = 't'
-
-  - storepath() and storepath_int() must fail when given a node where
-    no_spool = 't'; there is no path to that node
-
-  - storeset() and storeset_int() must reject an origin where no_spool = 't'
-
-  - subscribeset(set,provider,receiver,forward) and subscribeset_int(set,provider,receiver,forward)
-    should reject both provider and receiver where no_spool = 't'
-
-  - unsubscribeset() and unsubscribeset_int() rejects where receiver has no_spool = 't'
-
-  Add in function nodespool(node) and nodespool_int(node):
-
-   - These verify that the node hasn't got any subscribers or paths or
-     listens, and then modify sl_node.no_spool to 't'.
-
-3. Slonik
-
-  Need an extra boolean option, "spooler", which, if set to 'TRUE'
-  causes slonik to call nodespool(node).
-
-4. slon
-
-  Should be pretty oblivious of "log shipping."
-
-5. slon_spool
-
-  This is an alternative to slon, which gets used to generate "log shipper" output
-
-  It's a script/program that is passed information allowing it to
-  connect to Slony-I, along with a node number.
--- src/slonspool/subscribe.pm
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/usr/bin/perl
-# $Id: subscribe.pm,v 1.1 2004/11/30 23:38:41 cbbrowne Exp $
-# Author: Christopher Browne
-# Copyright 2004 Afilias Canada
-
-sub subscribe_to_node {
-  open(SUBSCRIBE, ">$spoolpath/subscription.log");
-  foreach $set (@SETS) {
-
-    # Create namespaces
-    print SUBSCRIBE "-- Subscribing node $node to set $set on $host - $port/$database/$user\n";
-    my $sth = $dbh->exec("select distinct nspname from pg_class p, pg_namespace n, _oxrsorg.sl_table t where t.tab_reloid = p.oid and p.relnamespace = n.oid and tab_set = $set;");
-    while ( @row = $sth->fetchrow ) {
-      my ($namespace) = @row;
-      print SUBSCRIBE "create schema $namespace;\n";
-    }
-    close(SUBSCRIBE);
-
-    # Create tables
-    $sth = $dbh->exec("select nspname || '.' || relname from pg_class p, pg_namespace n, _oxrsorg.sl_table t where t.tab_reloid = p.oid and p.relnamespace = n.oid and tab_set = $set;");
-    while ( @row = $sth->fetchrow ) {
-      my ($table) = @row;
-      `$pgbins/pg_dump -p $port -h $host -U $user -t $table -s $database >> $spoolpath/subscription.log`;
-    }
-    open(SUBSCRIBE, ">>$spoolpath/subscription.log");
-
-    # Pull data, as in copy_set (remote_worker.c)
-    my $query = "begin transaction; set transaction isolation level serializable;";
-    $sth = $dbh->exec($query);
-    my $tquery = qq{
-		    select T.tab_id,
-		    "pg_catalog".quote_ident(PGN.nspname) || '.' ||
-		    "pg_catalog".quote_ident(PGC.relname) as tab_fqname,
-		    T.tab_idxname, T.tab_comment
-		    from "$cluster".sl_table T,
-		    "pg_catalog".pg_class PGC,
-		    "pg_catalog".pg_namespace PGN
-		    where T.tab_set = $set
-		    and T.tab_reloid = PGC.oid
-		    and PGC.relnamespace = PGN.oid
-		    order by tab_id;
-		   };
-  }
-  $sth=$dbh->exec($tquery);
-  while (@row=$sth->fetchrow) {
-    my ($table) = @row;
-    print SUBSCRIBE qq{copy "$table" from stdin;\n};
-    my $query = qq{copy "$table" to stdout;};
-    $res = $dbh->exec($query);
-    my $line = "*" x 16384;
-    $ret = $dbh->getline($line, 16384);
-    while ($line ne "\\.") {
-      print SUBSCRIBE line, "\n";
-      $ret = $dbh->getline($line, 16384);
-    }
-    print SUBSCRIBE "\.\n";
-  }
-  close SUBSCRIBE;
-  my $seqquery = qq{
-    select n.nspname, c.relname
-    from "pg_catalog".pg_class c, "pg_catalog".pg_namespace, "$cluster".sl_sequence s
-    where
-      n.oid = c.relnamespace and
-      c.oid = s.seq_reloid and
-      s.seq_set = $set;};
-  $sth=$dbh->exec($seqquery);
-  while (my @row=$sth->fetchrow) {
-    my ($nsp, $seqname) = @row;
-    `$pgbins/pg_dump -p $port -h $host -U $user -n $nsp -t $seqname $database >> $spoolpath/subscription.log`;
-  }
-  # Next, populate Sync information
-  # Use the last SYNC's snapshot information and set
-  # the action sequence list to all actions after
-  # that.
-
-  my $squery = qq{
-    select ssy_seqno, ssy_minxid, ssy_maxxid,
-           ssy_xip, ssy_action_list
-    from "$cluster".sl_setsync
-    where ssy_setid = $set; };
-  $sth=$dbh->exec($squery);
-  while (my @row=$sth->fetchrow) {
-    my ($seqno, $minxid, $maxxid, $xip, $actionlist) = @row;
-  }
-  my $createsync = qq{
-    insert into "_$cluster".sl_setsync
-	   (ssy_setid, ssy_origin, ssy_seqno, ssy_minxid, ssy_maxxid, ssy_xip, ssy_action_list)
-    values ($set, $node, $seqno, $minxid, $maxxid, '$xip', '$actionlist');};
-  print SUBSCRIBE $createsync, "\n";
-}
-
-1;
--- src/slonspool/slonspool.pl
+++ /dev/null
@@ -1,185 +0,0 @@
-#!/usr/bin/perl
-# $Id: slonspool.pl,v 1.1 2004/11/30 23:38:41 cbbrowne Exp $
-# Author: Christopher Browne
-# Copyright 2004 Afilias Canada
-
-use Pg;
-use Getopt::Long;
-require "subscribe.pm";
-require "gen_output.pm";
-require "init.pm";
-
-my($database,$user, $host, $cluster, $password, $port, $spoolpath, $spoolname,
-   $maxsize, $maxage, $subnode, $node);
-
-my @SETS;
-my $dbh;
-process_options();
-initialize_configuration();
-#subscribe_to_node();
-
-while (1) {
-  listen_to_node();
-}
-
-sub listen_to_node {
-  while (1) {
-    process_event();
-    die -1;
-  }
-}
-
-sub process_event {
-  my $dsn = "dbname=$database host=$host port=$port user=$user";
-  if ($password) {
-    $dsn .= " password=$password";
-  }
-  print "DSN: $dsn\n";
-  my $dbh = Pg::connectdb($dsn);
-  print "Last err:", $dbh->errorMessage, "\n";
-  my $sync_event;
-  my $last_seq = qq{select con_seqno from "_$cluster".sl_confirm
-                    where con_origin = $node order by con_seqno desc limit 1;};
-  print $last_seq, "\n";
-  my $res = $dbh->exec($last_seq);
-  while (my @row = $res->fetchrow) {
-    ($sync_event) = @row;
-    print "Last sync: $sync_event\n";
-  }
-  print "Last err:", $dbh->errorMessage, "\n";
-  $sync_event++;
-  print "Next sync: $sync_event\n";
-
-  my @ORIGINS;
-  my $origin_query = qq{ select set_origin from "_$cluster".sl_set where set_id in ($opt_sets); };
-  $res = $dbh->exec($origin_query);
-  while (my @row = $res->fetchrow) {
-    my ($origin) = @row;
-    push @ORIGINS, $origin;
-  }
-  $origin_qualification = " (log_origin in (" . join(',', @ORIGINS) . ")) ";
-
-
-  my $table_qualification = " (log_tableid in (" . join(',', @TABLES) . ")) ";
-
-  print "Table qualification: $table_qualification\n";
-  my $qualification .= " $origin_qualification and $table_qualification ";
-
-  my $cursor_query = qq{
-  declare LOG cursor for
-    select log_origin, log_xid, log_tableid, log_actionseq, log_cmdtype, log_cmddata
-    from "_$cluster".sl_log_1
-    where $origin_qualification and $table_qualification
-    order by log_xid, log_actionseq;};
-
-  print "Cursor query: $cursor_query\n";
-
-  my $lastxid = "";
-  my $syncname=sprintf("log-%08d", $sync);
-  open(LOGOUTPUT, ">$spoolpath/$syncname");
-  print LOGOUTPUT "-- Data for sync $sync_event\n";
-  print LOGOUTPUT "-- ", `date`;
-  my $begin = $dbh->exec("begin;");
-  my $cursorexec = $dbh->exec($cursor_query);
-  print "Last err:", $dbh->errorMessage, "\n";
-  my $foundsome = "YES";
-  while ($foundsome eq "YES") {
-    $foundsome = "NO";
-    my $res = $dbh->exec("fetch forward 100 in LOG;");
-    while (my @row = $res->fetchrow) {
-      $foundsome = "YES";
-      my ($origin, $xid, $tableid, $actionseq, $cmdtype, $cmddata) = @row;
-      if ($xid ne $lastxid) { # changed xid - report that...
-	if ($lastxid ne "") {  # Do nothing first time around...
-	  printf LOGOUTPUT "COMMIT; -- Done xid $lastxid\n";
-	}
-	print LOGOUTPUT "BEGIN;\nselect fail_if_xid_applied($xid);\n";
-	$lastxid = $xid;
-      }
-      if ($cmdtype eq "I") {
-	printf LOGOUTPUT "insert into %s %s;\n", $TABLENAME[$tableid], $cmddata;
-      } elsif ($cmdtype eq "U") {
-	printf LOGOUTPUT "update only %s set %s;\n", $TABLENAME[$tableid], $cmddata;
-      } elsif ($cmdtype eq "D") {
-	printf LOGOUTPUT "delete from only %s where %s;\n", $TABLENAME[$tableid], $cmddata;
-      } else {
-	print LOGOUTPUT "problem: cmddata not in (I,U,D) = [$cmdtype]\n";
-      }
-    }
-  }
-  if ($lastxid ne "") {
-    print LOGOUTPUT "COMMIT; -- Done xid $lastxid\n";
-  }
-  close LOGOUTPUT;
-  $dbh->exec("rollback;");
-  my $confirmation = qq{ insert into "_$cluster".sl_confirm (con_origin,con_received,con_seqno,con_timestamp)
-                         values ($node, $subnode, $sync_event, CURRENT_TIMESTAMP); };
-  print "Confirm: $confirmation\n";
-  my $cursorexec = $dbh->exec($confirmation);
-}
-
-sub connect_to_node {
-  my $dsn = "dbname=$database host=$host port=$port user=$user";
-  if ($password) {
-    $dsn .= " password=$password";
-  }
-  $dbh = Pg::connectdb($dsn);
-}
-
-sub process_options {
-
-  $goodopts = GetOptions("help", "database=s", "host=s", "user=s",
-			 "cluster=s", "password=s", "port=s", "sets=s",
-			 "spoolpath=s", "spoolname=s", "pgbins=s",
-			 "maxsize=i", "maxage=i", "node=i", "subnode=i");
-
-  if (defined ($opt_help)) {
-    show_usage();
-  }
-
-  $cluster=$opt_cluster if (defined($opt_cluster));
-  $subnode = $opt_subnode if (defined ($opt_subnode));
-  $node = $opt_node if (defined($opt_node));
-  $database=$opt_database if (defined ($opt_database));
-  $user = $opt_user if (defined ($opt_user));
-  $host = $opt_host if (defined($opt_host));
-  $password = $opt_password if (defined($opt_password));
-  $port = $opt_port if (defined($opt_port));
-  $pgbins = $opt_pgbins if (defined($opt_pgbins));
-  $spoolpath = $opt_spoolpath if (defined($opt_spoolpath));
-  $spoolname   = $opt_spoolname   if (defined($opt_spoolname));
-  if (defined($opt_sets)) {
-    @SETS=split (/,/, $opt_sets);
-  }
-  if (defined($opt_maxsize)){
-    $maxsize = $opt_maxsize;
-  } else {
-    $maxsize = 10000;
-  }
-  if (defined($opt_maxage)){
-    $maxsize = $opt_maxage;
-  } else {
-    $maxage = 300;
-  }
-}
-
-sub show_usage {
-  print qq{slonspool:
-     --help                get help
-     --cluster=s           Slony-I cluster name
-     --subnode=s   Node number subscribed through
-     --node=i              Node number to use to request
-     --pgbins=s            Location of PostgreSQL binaries including slonik and pg_dump
-     --database=s          database to connect to
-     --host=s              host for database
-     --user=s              user for database
-     --password=s          password for database (you should probably use .pgpass instead)
-     --port=i              port number to connect to
-     --sets=s              Sets to replicate (comma-delimited) - e.g --sets=1,2,4 
-     --spoolpath=s         directory in which to spool output
-     --spoolname=s         naming convention for spoolfiles
-     --maxsize=i           maximum size of spool files, in kB - default =10000KB
-     --maxage=i            maximum age of spool files in seconds - default 300
-};
-  die -1;
-}
--- src/slonspool/gen_output.pm
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/perl
-
-1;
--- src/slonspool/init.pm
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/perl
-# $Id: init.pm,v 1.1 2004/11/30 23:38:40 cbbrowne Exp $
-
-# Data structures...
-# %NODES{}{}
-# Fields:
-#  $NODE{$i}{last_event} - Last event processed for node
-#
-# %SET{}{}
-# Fields:
-#  $SET{$i}{origin}  - origin node
-#  $SET{$i}{comment} - Comment about set
-#  $SET{$i}{provider} - node that provides data to our favorite node
-#
-# %TABLES
-#  $TABLES{$i}{name}
-#  $TABLES{$i}{namespace}
-#  $TABLES{$i}{set}
-
-# Populate latest information about subscription providers and such...
-sub load_configuration {
-  my $dsn = "dbname=$database host=$host port=$port user=$user";
-  if ($password) {
-    $dsn .= " password=$password";
-  }
-  $dbh = Pg::connectdb($dsn);
-
-  # Populate %NODE with confirmation information
-  my $confirm_query = qq{ select con_origin, con_seqno from "_$cluster".sl_confirm where received = $node; };
-  my $res = $dbh->exec($confirm_query);
-  while (my @row = $res->fetchrow) {
-    my ($origin, $sync) = @row;
-    if ($NODE{$origin}{last_event} < $sync) {
-      $NODE{$origin}{last_event} = $sync;
-    }
-  }
-
-  # Populate %SET with set info for the sets being handled
-  my $sub_set_query = qq{ select set_id, set_origin from "_$cluster".sl_set where set_id in ($opt_sets);};
-  my $res = $dbh->exec($confirm_query);
-  while (my @row = $res->fetchrow) {
-    my ($set, $origin) = @row;
-    $SET{$set}{origin} = $origin;
-  }
-
-  my $tables_query = qq{select t.tab_id, t.tab_set, n.nspname, r.relname from "_$cluster".sl_table t, pg_catalog.pg_namespace n, pg_catalog.pg_class r where r.oid = t.tab_reloid and n.oid = r.relnamespace and tab_set in ($opt_sets) ;};
-  $res = $dbh->exec($tables_query);
-  while (my @row = $res->fetchrow) {
-    my ($id, $set, $namespace, $tname) = @row;
-    $TABLES{$id}{name} = $tname;
-    $TABLES{$id}{namespace} = $namespace;
-    $TABLES{$id}{set} = $set;
-  }
-}
-
-sub storeNode {
-  my ($id, $comment) = @_;
-  $NODES[$id] = $comment;
-}
-
-1;
--- src/slonspool/NOTES
+++ /dev/null
@@ -1,153 +0,0 @@
-Slony-I Log Shipping
-==========================================
-
-One of the features intended for 1.1 is the ability to serialize the
-updates to go out into files that can be kept in a spool directory.
-
-The spool files could then be transferred via whatever means was
-desired to a "slave system," whether that be via FTP, rsync, or
-perhaps even by pushing them onto a 1GB "USB key" to be sent to the
-destination by clipping it to the ankle of some sort of "avian
-transport" system  ;-) .
-
-There are plenty of neat things you can do with a data stream in this
-form, including:
-
-  -> Using it to replicate to nodes that _aren't_ securable
-  -> Supporting a different form of PITR
-  -> If disaster strikes, you can look at the logs of queries
-     themselves
-  -> This is a neat scheme for building load for tests...
-  -> We have a data "escrow" system that would become incredibly
-     cheaper given 'log shipping'
-
-But we need to start thinking about how to implement it to be usable.
-I'm at the stage of starting to think about questions; this will be
-WAY richer on questions than on answers...
-
-Q1: Where should the "spool files" for a subscription set be generated?
-
- Several thoughts come to mind:
-
-  A1 -> The slon for the origin node generates them
-
-  A2 -> Any slon node participating in the subscription set can generate
-        them
-
-  A3 -> A special "pseudo-node" generates spool files rather than applying
-        changes to a database
-
- Answer tentatively seems to be A3.
-
-Q2: What takes place when a failover/MOVE SET takes place?
-
-   -> If we picked, for Q1, A2 or A3, then the answer is "nothing."
-
-   -> If Q1's answer was A1, then it becomes necessary for the new
-      origin to start generating spool files.  
-
-      What do we do if it that slon hasn't got suitable configuration?
-      Simply stop spooling?
-
- Given Q1:A3, nothing special happens when failover/MOVE SET takes
- place, except that if the "spool node" is subscribed to a node that
- is somehow orphaned, it might get disconnected :-(.
-
-Q3: What if we run out of "spool space"?
-
-   -> It's forced to stop writing out logs; this should _prevent_
-      purging sl_log_1/sl_log_2 entries in the affected range so 
-      that "log shipping" isn't corrupted.
-
-      In effect, "log shipping" is a sort of 'virtual destination'
-      that Slony-I's existing data structures need to know something
-      about.  It's not a "true" node, but it needs to have a
-      subscription and set up
-      sl_confirm entries.
-
-Q4: How do we configure it?
-
-   Things that need to be configured include:
-
-   a) Path in which to put "spool files"
-
-      SPOOLPATH
-
-      -p "/var/spool/slony1/something"
-
-   b) Naming convention for the spool files, likely using a
-      strftime()-conformant name string, also with the option of
-      having it use the starting and/or ending SYNC ids.
-
-      -n "something"      
-
-   c) There needs to be some sort of "subscribe" notion...
-
-      This is implemented _inside_ the spooler.
-
-      --> For each table, run pg_dump -s -t on the table
-
-      --> Then do a "copy from" on each table
-
-   d) How often to split between files???
-
-      --> Combo of time, number of syncs, size
-
-Q5: What should the logs consist of?
-
-  -> Should they simply consist of the updates on the tables Slony-I
-     is to replicate?
-
-  -> Should there also be some information stored concerning what
-     SYNCS are processed?
-
-     Yes, there should be.  There shouldn't merely be comments; the
-     structure should be something like:
-
-     BEGIN;
-       @NAMESPACE at .start_spool(23451);  -- SYNC 23451
-       insert this
-       delete that
-       update other thing
-       @NAMESPACE at .end_spool(23451);  -- SYNC 23451
-     COMMIT;
-     BEGIN;
-       @NAMESPACE at .start_spool(23452);  -- SYNC 23452
-       insert this
-       delete that
-       update other thing
-       @NAMESPACE at .end_spool(23452);
-     COMMIT;
-     BEGIN;
-       @NAMESPACE at .start_spool(23454);  -- SYNC 23454
-       insert this
-       delete that
-       update other thing
-       @NAMESPACE at .end_spool(23454);
-     COMMIT;
-     BEGIN;
-       @NAMESPACE at .start_spool(23453);  -- SYNC 23453
-       insert this
-       delete that
-       update other thing
-       @NAMESPACE at .end_spool(23453);
-     COMMIT;
-
-  -> Would the log-shipped-subscribers also operate in a
-     "mostly-read-only" mode as is the case for 'direct' subscribers?
-
-     start_spool() could alter tables to turn on and off the
-     ability to update the data...
-
-  -> How much metadata should get added in?  E.g. - comments about
-     SYNCs, when data was added in, data about events that aren't
-     directly updating data
-
-     For this to be overly voluminous would be irritating, but having
-     some metadata to search through would be handy...
-
-  -> Would it be a useful notion to try to make it possible for a
-     resulting "node" to join a replication set?
-
-I'm sure there are some "oughtn't try to do that" answers to be had
-here, but we might as well start somewhere...
\ No newline at end of file
--- src/slonspool/README
+++ /dev/null
@@ -1,2 +0,0 @@
-Here begins the code for a "log shipping" slon...
-


More information about the Slony1-commit mailing list