To create a new preamble.sk replication cluster, you execute an init cluster command targeted at number 1. An init cluster command looks like this:
init cluster ( id = node-number, comment = string-literal );
The init cluster command connects to the node (which, by the way, must always be node number 1), creates the cluster namespace, and loads a number of tables, sequences, functions, and views into that namespace.
To create the branches replication cluster, you would execute a slonik script that contains the commands shown in Listing 24.2.
Listing 24.2. initCluster.sk
#!/usr/local/bin/slonik # File: initCluster.sk include ; init cluster ( id = @SPRINGFIELD, comment = 'primary node - springfield' );
Notice that the script (like every slonik script) must include<> (or begin with) the preamble. After executing this script, you'll find a new schema named _branches in the movies database on host springfield.
Once you've created the replication cluster, you can add the other nodes to the cluster by executing a store node command targeted at each node. The syntax for a store node command is:
store node ( id = node-number, comment = string-literal [ spoolnode = {TRUE|FALSE}, ] [event node = node-number ] );
The spoolnode parameter is optional and, if missing, is assumed to be FALSE. (I'll explain spool nodes and log shipping in a moment.) The event node parameter is also optional and, if missing, is assumed to specify node 1. When you execute a store node command, slonik connects to the node; creates the cluster namespace; loads the same set of tables, sequences, functions, and views that the init cluster command stored on the primary node; and then copies the cluster configuration tables from the event node (usually node 1).
To add the boomtown and snoozeville nodes to the branches cluster, you would execute the script shown in Listing 24.3.
Listing 24.3. addNodes.sk
#!/usr/local/bin/slonik # File: addNodes.sk include ; store node ( id = @BOOMTOWN, comment = 'boomtown' ); store node ( id = @SNOOZEVILLE, comment = 'snoozeville' );
After executing the addNodes.sk script, you'll find a schema named _branches (in the movies database) on all three nodes.
At this point, each node in the replication cluster knows about every other node, but they don't know how to communicate with each other. You may be thinking that the Slony would use the preamble to connect one node to another, but that's not the case. The preamble (which is part of a slonik script) tells the slonik administration console how to connect to each nodeit does not tell the nodes how to connect to each other once the replication servers begin exchanging messages.
To configure node-to-node connection paths, you execute a series of store path commands. A store path command looks like this:
store path ( server = node-number, client = node-number, conninfo = 'connection-string' );
Each store path command tells the replication daemon how to connect to the given server node starting from the client node. The connection-string parameter is a libpq connection string of the same form that you write in a slonik preamble. You typically define connection paths in pairs; the second store path command describes the reverse path. (That is, if the first store path command defines how to connect to node 2 starting from node 1, the second command describes how to connect to node 1 starting from node 2.) In fact, it's not a bad idea to define a set of paths that describe how to connect every node to every other node. For example, Listing 24.4 shows the commands necessary to connect all of the nodes in the branches replication cluster.
Listing 24.4. addPaths.sk
#!/usr/local/bin/slonik # File: addPaths.sk include ; store path ( server = @SPRINGFIELD, client = @BOOMTOWN, conninfo = 'service=springfield-replication' ); store path ( server = @BOOMTOWN, client = @SPRINGFIELD, conninfo = 'service=boomtown-replication' ); store path ( server = @SPRINGFIELD, client = @SNOOZEVILLE, conninfo = 'service=springfield-replication' ); store path ( server = @SNOOZEVILLE, client = @SPRINGFIELD, conninfo = 'service=snoozeville-replication' ); store path ( server = @BOOMTOWN, client = @SNOOZEVILLE, conninfo = 'service=boomtown-replication' ); store path ( server = @SNOOZEVILLE, client = @BOOMTOWN, conninfo = 'service=snoozeville-replication' );
It's important to remember that the connection string describes how the client replication daemon should connect to the appropriate database on the server node. If you specify a service name in the connection string, that service must be defined in the client's pg_service.conf file.
Part I: General PostgreSQL Use
Introduction to PostgreSQL and SQL
Working with Data in PostgreSQL
PostgreSQL SQL Syntax and Use
Performance
Part II: Programming with PostgreSQL
Introduction to PostgreSQL Programming
Extending PostgreSQL
PL/pgSQL
The PostgreSQL C APIlibpq
A Simpler C APIlibpgeasy
The New PostgreSQL C++ APIlibpqxx
Embedding SQL Commands in C Programsecpg
Using PostgreSQL from an ODBC Client Application
Using PostgreSQL from a Java Client Application
Using PostgreSQL with Perl
Using PostgreSQL with PHP
Using PostgreSQL with Tcl and Tcl/Tk
Using PostgreSQL with Python
Npgsql: The .NET Data Provider
Other Useful Programming Tools
Part III: PostgreSQL Administration
Introduction to PostgreSQL Administration
PostgreSQL Administration
Internationalization and Localization
Security
Replicating PostgreSQL Data with Slony
Contributed Modules
Index