]> begriffs open source - pg_scribe/blob - doc/tutorial.md
Clean up some cruft in the tutorial
[pg_scribe] / doc / tutorial.md
1 # pg_scribe Tutorial
2
3 Watch database changes become plain SQL in real-time. Three terminals recommended.
4
5 ## Prerequisites
6
7 ```bash
8 # Install the extension
9 cd wal2sql && make && make install
10
11 # Configure PostgreSQL
12 echo "wal_level = logical" >> ~/.pgenv/pgsql/data/postgresql.conf
13 pgenv restart
14 ```
15
16 ## Terminal 1: Initialize and start streaming
17
18 ```bash
19 # Create a test database
20 createdb -U postgres demo
21
22 # Initialize backup system (creates extension, slot, base backup)
23 pg_scribe --init -d demo -f /tmp/demo_backup -U postgres
24
25 # Start streaming changes to active.sql
26 pg_scribe --start -d demo -f /tmp/demo_backup -U postgres
27 ```
28
29 Leave this running. Every database change now becomes SQL.
30
31 ## Terminal 2: Make changes
32
33 ```bash
34 psql -U postgres demo
35 ```
36
37 ```sql
38 CREATE TABLE users (
39     id SERIAL PRIMARY KEY,
40     email TEXT UNIQUE,
41     created_at TIMESTAMP DEFAULT now()
42 );
43
44 INSERT INTO users (email) VALUES ('alice@example.com'), ('bob@example.com');
45
46 UPDATE users SET email = 'alice@newdomain.com' WHERE id = 1;
47
48 ALTER TABLE users ADD COLUMN status TEXT DEFAULT 'active';
49
50 CREATE TABLE posts (
51     id SERIAL PRIMARY KEY,
52     user_id INTEGER REFERENCES users(id),
53     title TEXT
54 );
55
56 INSERT INTO posts (user_id, title) VALUES (1, 'Hello World');
57
58 DELETE FROM users WHERE id = 2;
59
60 DROP TABLE posts;
61 ```
62
63 ## Terminal 3: Watch the backup
64
65 Every change appears as executable SQL:
66
67 ```bash
68 # View streamed SQL
69 cat /tmp/demo_backup/chain-*/active.sql
70 ```
71
72 Check status:
73
74 ```bash
75 pg_scribe --status -d demo -f /tmp/demo_backup -U postgres
76 ```
77
78 ## Restore to a new database
79
80 ```bash
81 # Seal the differential (while Terminal 1 is still streaming)
82 pg_scribe --rotate-diff -f /tmp/demo_backup
83
84 # Stop streaming gracefully
85 pg_scribe --stop -f /tmp/demo_backup
86
87 # Restore to a new database
88 pg_scribe --restore -d demo_restored -f /tmp/demo_backup -C -U postgres
89
90 # Verify
91 psql -U postgres demo_restored -c "SELECT * FROM users;"
92 ```
93
94 ## Cleanup
95
96 ```bash
97 dropdb -U postgres demo_restored
98 dropdb -U postgres demo
99 rm -rf /tmp/demo_backup
100 ```
101
102 ## What just happened
103
104 - `--init` created the wal2sql extension, replication slot, and base backup
105 - `--start` streamed every change to active.sql as plain SQL
106 - DDL (CREATE, ALTER, DROP) and DML (INSERT, UPDATE, DELETE) captured in order
107 - `--rotate-diff` sealed active.sql into a timestamped differential file
108 - `--restore` replayed base backup + sealed differentials into a new database
109 - No binary formats, no version lock-in, readable with `less`
110
111 ## Production usage
112
113 ```bash
114 # Initialize once
115 pg_scribe --init -d mydb -f /backups/mydb -S mydb_slot -U postgres
116
117 # Run continuously (use systemd or supervisor)
118 pg_scribe --start -d mydb -f /backups/mydb -S mydb_slot -U postgres
119
120 # Rotate differentials daily
121 pg_scribe --rotate-diff -f /backups/mydb
122
123 # Create new chain weekly with compressed base backup and auto-transition
124 # This stops the old streaming process and starts streaming to the new chain
125 pg_scribe --new-chain --start -d mydb -f /backups/mydb -S mydb_slot -Z gzip:6 -U postgres
126
127 # Or manually transition (if you prefer separate steps):
128 # 1. Create new chain
129 pg_scribe --new-chain -d mydb -f /backups/mydb -S mydb_slot -Z gzip:6 -U postgres
130 # 2. Stop old streaming
131 pg_scribe --stop -f /backups/mydb
132 # 3. Start streaming to new chain
133 pg_scribe --start -d mydb -f /backups/mydb -S mydb_slot -U postgres
134
135 # Monitor replication lag
136 pg_scribe --status -d mydb -f /backups/mydb -S mydb_slot -U postgres
137 ```