author: Ian Burrell company: ianburrell@gmail.com title: Slony Slony ===== Slony ----- * * Replication for PostgreSQL * Master-slave * Asynchronous * Extension-based Usage ----- * [Rentrak Corp](http://www.rentrak.com) * Video OnDemand reporting system - 4 billion transactions - 8 million/day * Master - 1\.5 TB - Imports and website * 2 slaves - 700 GB - Reporting Why Slony? ---------- * Disaster recovery * Read-only copies * Remote sites * Upgrades Why Not? -------- * Complicated * Need writes on copies * Preserve transactions * Disconnected operation * No schema replication Components ---------- * Database extensions - C triggers - PL/pgSQL management functions * slon daemon * slonik configuration processor Basic Operation --------------- * Triggers save changes in log table * slon polls for events * slon on master periodically generates SYNC events * Slave slon copies changes from master * slonik runs management functions and inserts events Terms ----- * Cluster * Node * Replication set * Origin * Provider * Subscriber Topology -------- * Only master is writable * Slaves are read-only * Table sets can have different topology * Slave can forward to other slaves Slonik ------ cluster name = example; node 1 admin conninfo = 'dbname=master host=masterdb user=slony'; node 2 admin conninfo = 'dbname=slave host=slavedb user=slony'; * Preamble goes in every slonik script * Connection info from management machine Init Cluster ---------- init cluster (id = 1, comment = 'Master Node'); create set (id = 1, origin = 1, comment = 'All pgbench tables'); Tables & Sequences ------------------ set add table (set id = 1, origin = 1, id = 1, fully qualified name = 'public.accounts', comment = 'accounts table'); set add sequence (set id = 1, origin = 1, id = 2, fully qualified name = 'public.account_no_seq', comment = 'accounts seqeunce'); * Tables must have primary key Nodes & Paths ------------- store node (id = 2, comment = 'Slave node'); store path (server = 1, client = 2, conninfo='dbname=master host=masterdb user=slony'); store path (server = 2, client = 1, conninfo='dbname=slave host=slavedb user=slony'); store listen (origin = 1, provider = 1, receiver = 2); store listen (origin = 2, provider = 2, receiver = 1); Slon Daemon ----------- slon example "dbname=master user=slony host=masterdb" slon example "dbname=slave user=slony host=slavedb" * Best practice to run slon on master machine * Need watchdog scripts Subscribe --------- subscribe set (id = 1, provider = 1, receiver = 2, forward = no); * Truncate on slaves * Copy table * Create indexes * Other changes must wait to finish Adding Tables ------------- create set (id = 99, origin = 1, comment = 'Temporary set'); set add table (set id = 99, origin = 1, id = 2, fully qualified name = 'public.branches', comment = 'branches table'); subscribe set (id = 99, provider = 1, receiver = 2, forward = no); wait for event (origin = 2, confirmed = 1); sync (id = 1); wait for event (origin = 1, confirmed = 2); merge set (id = 1, add id = 99, origin = 1); * Can't add tables to subscribed set * Create new set, subscribe to same nodes, and merge together Schema Changes -------------- execute script (set id = 1, event node = 1, filename='add_column.sql'); * Required when change to structure of table * Serialized with transactions * Disables triggers on slaves Switchover -------- lock set (id = 1, origin = 1); wait for event (origin = 1, confirmed = 2); move set (id = 1, old origin = 1, new origin = 2); wait for event (origin = 1, confirmed = 2); * Slave becomes master * Master becomes slave * Must be connected Failover -------- failover (id = 1, backup node = 2); * Only use when master is unavailable * Master must be rebuilt Problems -------- * Vacuum * Locking * Schema installs Vacuum ------ * Long-running transactions * Tables with growth problems - pg\_listener - sl\_log\_1 * Better in Slony 1.2 Locking ------- * Exclusive locks - execute script: on set - set add table: on table - move set: on old and new origin - lock set: on origin - subscribe set: on subscriber Schema Install -------------- * Plan your changes * Test your scripts * Take downtime * Move set trick Alternatives ------------ * [PITR Replication](http://pgpitrha.projects.postgresql.org/) - WAL shipping - Hot standby * [PGCluster](http://www.pgcluster.org/) - Multi-master synchronous - Query replication * [Postgres-R](http://gborg.postgresql.org/project/pgreplication/) - Multi-master synchronous - Spread group communication library - Modified old version