Skip to content

Commit 2db3d94

Browse files
committed
Mason's additions to the documentation and error handling
1 parent 5e7d410 commit 2db3d94

File tree

2 files changed

+56
-22
lines changed

2 files changed

+56
-22
lines changed

docs/managing/read_only.md

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,82 @@
11
# Using Spock in Read-Only Mode
22

3-
Spock supports operating a cluster in read-only mode. Read-only status is managed using a GUC (Grand Unified Configuration) parameter named `spock.readonly`. This parameter can be set to enable or disable the read-only mode. Read-only mode restricts non-superusers to read-only operations, while superusers can still perform both read and write operations regardless of the setting.
3+
Spock supports operating a node in read-only mode. Read-only status is managed using a GUC parameter named `spock.readonly`, which can be set to one of three values:
44

5-
The flag is at cluster level: either all databases are read-only or all databases
6-
are read-write (the usual setting).
5+
| Value | Description |
6+
|---------|-------------|
7+
| `off` | No restrictions. All users may write. This is the default. |
8+
| `local` | Non-superuser local sessions are read-only. Replicated writes from apply workers are still permitted, so inbound replication continues normally. Superusers may still perform write operations. (The legacy alias `user` is accepted for backward compatibility.) |
9+
| `all` | Non-superuser local sessions and apply workers are blocked from writing. Superusers may still perform write operations. Use this mode when you need to stop both local application writes and inbound replication. |
710

8-
Read-only mode is implemented by filtering SQL statements:
11+
The setting is at cluster level: either all databases are read-only or all
12+
databases are read-write (the usual setting).
913

10-
- `SELECT` statements are allowed if they don't call functions that write.
11-
- DML (`INSERT`, `UPDATE`, `DELETE`) and DDL statements including `TRUNCATE` are forbidden entirely.
12-
- DCL statements `GRANT` and `REVOKE` are also forbidden.
14+
Read-only mode is enforced by setting PostgreSQL's `transaction_read_only` flag for affected sessions. This means that any statement that would modify data — including DML (`INSERT`, `UPDATE`, `DELETE`), DDL, `TRUNCATE`, and DCL (`GRANT`, `REVOKE`) — will be rejected by PostgreSQL's standard read-only transaction checks.
1315

14-
This means that the databases are in read-only mode at SQL level: however, the
15-
checkpointer, background writer, walwriter, and the autovacuum launcher are still
16-
running. This means that the database files are not read-only and that in some
17-
cases the database may still write to disk.
16+
The databases are in read-only mode at the SQL level: however, the checkpointer,
17+
background writer, walwriter, and the autovacuum launcher are still running. This
18+
means that the database files are not read-only and that in some cases the
19+
database may still write to disk.
1820

1921
## Setting Read-Only Mode
2022

21-
You can control read-only mode with the Spock parameter `spock.readonly`; only a superuser can modify this setting. When the cluster is set to read-only mode, non-superusers will be restricted to read-only operations, while superusers will still be able to perform read and write operations regardless of the setting.
22-
23-
This value can be changed using the `ALTER SYSTEM` command.
23+
Only a superuser can modify the `spock.readonly` parameter. The value can be changed using the `ALTER SYSTEM` command:
2424

2525
```sql
26-
ALTER SYSTEM SET spock.readonly = 'on';
26+
-- Block non-superuser local writes; inbound replication continues
27+
ALTER SYSTEM SET spock.readonly = 'local';
28+
SELECT pg_reload_conf();
29+
30+
-- Block all non-superuser writes including replication
31+
ALTER SYSTEM SET spock.readonly = 'all';
32+
SELECT pg_reload_conf();
33+
34+
-- Restore normal operation
35+
ALTER SYSTEM SET spock.readonly = 'off';
2736
SELECT pg_reload_conf();
2837
```
2938

30-
To set the cluster to read-only mode for a session, use the `SET` command. Here are the steps:
39+
To set the mode for the current session only:
3140

3241
```sql
33-
SET spock.readonly TO on;
42+
SET spock.readonly TO local;
3443
```
3544

36-
To query the current status of the cluster, you can use the following SQL command:
45+
To query the current status:
3746

3847
```sql
3948
SHOW spock.readonly;
4049
```
4150

42-
This command will return on if the cluster is in read-only mode and off if it is not.
51+
## Superuser writes and outbound replication
52+
53+
In both `local` and `all` modes, superusers are exempt from the read-only
54+
restriction and may perform write operations. **The readonly setting has no
55+
effect on the walsender (outbound replication).** Any writes made by a
56+
superuser are captured in WAL and will be replicated outbound to other nodes
57+
in the cluster, regardless of the readonly mode.
58+
59+
To perform repair operations that should **not** replicate to other nodes, use
60+
[`spock.repair_mode()`](../spock_functions/index.md) to suppress outbound
61+
replication of DML/DDL statements:
62+
63+
```sql
64+
BEGIN;
65+
SELECT spock.repair_mode(true);
66+
67+
-- Perform repair DML/DDL here...
68+
69+
SELECT spock.repair_mode(false);
70+
COMMIT;
71+
```
72+
73+
## Behavior of `all` mode
74+
75+
In `all` mode, apply workers detect the setting and stop consuming inbound WAL.
76+
When the mode is switched back to `off` or `local`, replication resumes from
77+
where it left off — no data is lost.
4378

4479
Notes:
4580
- Only superusers can set and unset the `spock.readonly` parameter.
46-
- When the cluster is in read-only mode, only non-superusers are restricted to read-only operations. Superusers can continue to perform both read and write operations.
47-
- By using a GUC parameter, you can easily manage the cluster's read-only status through standard PostgreSQL configuration mechanisms.
81+
- By using a GUC parameter, you can easily manage the node's read-only status through standard PostgreSQL configuration mechanisms.
4882

src/spock_apply.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2434,7 +2434,7 @@ replication_handler(StringInfo s)
24342434
char action = pq_getmsgbyte(s);
24352435

24362436
if (spock_readonly == READONLY_ALL)
2437-
elog(PANIC, "SPOCK %s: cluster is in read-only mode, not performing replication",
2437+
elog(FATAL, "SPOCK %s: cluster is in read-only mode, not performing replication",
24382438
MySubscription->name);
24392439

24402440
memset(&errcallback_arg, 0, sizeof(struct ActionErrCallbackArg));

0 commit comments

Comments
 (0)