I have a process (for backup and replication using binary logs) that works in MySQL that I want to replicate for Postgres databases (using WAL):
- Lock database (
FLUSH TABLES WITH READ LOCK;
) - Disable binary logging (
SET sql_log_bin = 0;
) - Flush binary logs (
FLUSH BINARY LOGS;
) - Copy binary logs and apply to a remote database for replication purposes
- Enable binary logging (
SET sql_log_bin = 1;
) - Unlock database (
UNLOCK TABLES;
)
This process works and I'm trying to do the same for Postgres. I was able to find that CHECKPOINT
is what I need to flush the binary logs for Postgres but locking and unlocking the database isn't as straightforward as I hoped it would be.
Here's what I found so far:
LOCK DATABASE
is a database-level locking mechanism but is not implementedBEGIN; LOCK TABLE users IN ACCESS EXCLUSIVE MODE NOWAIT;
seems to be able to lock the tables individually but apparently there is noUNLOCK TABLE
command because locks are always released at transaction enddefault_transaction_read_only
- I tried to look for the equivalent ofFLUSH TABLES WITH READ LOCK;
in Postgres and found this question
I tried the default_transaction_read_only
solution and it does prevent new records from being added but I'm a little worried about what the answer in there said:
This takes effect for new sessions, not for sessions that are already connected.
Also when I tried to revert the read-only mode: BEGIN read write; ALTER DATABASE my_database SET default_transaction_read_only to OFF;
it appears to have succeeded but when I try to add a new record, I get the following error:
ERROR: cannot execute INSERT in a read-only transaction
Any ideas on how I could perform the same process as I am doing for MySQL but for Postgres?
-
1So, why you want the same process? None of this is needed in postgresql. Just pg_basebackup or more specific tools to manage pitr backups (pgbackrest, wal-g).Melkij– Melkij2024年02月12日 19:01:40 +00:00Commented Feb 12, 2024 at 19:01
-
@Melkij we have a remote database meant for replication but it isn't always connected. So instead we have another layer of technology where we would ideally upload the WAL files to and when the remote does get connected, that extra layer of tech would sync it up to the remote and perform the replication there.dokgu– dokgu2024年02月12日 19:37:54 +00:00Commented Feb 12, 2024 at 19:37
-
reasonable wal_keep_size, or replication slot with reasonable max_slot_wal_keep_size, or archive_command + restore_command + archive_cleanup_command. It depends on how long the replica may be disconnected.Melkij– Melkij2024年02月12日 19:50:07 +00:00Commented Feb 12, 2024 at 19:50
-
2There is no reason to lock the database for this. Well, if you really want to, you can even stop it. But this is not needed. In fact, there are only two points: somehow save the WAL that the replica has not yet received and somehow transfer them to the replica. archive_command (primary saves WAL file using this command) + restore_command (replica receives new WAL using this command) + archive_cleanup_command (the replica calls this command and indicates a position that is no longer needed for recovery) completely solve this task even if the databases have no direct connection at all.Melkij– Melkij2024年02月12日 20:36:37 +00:00Commented Feb 12, 2024 at 20:36
-
1@dokgu "I was just under the impression that it's generally a good idea to lock the database so that the primary is in a stable state and no new records etc are made until the maintenance is done. Isn't that a common practice?" - Nope.J.D.– J.D.2024年02月13日 04:18:30 +00:00Commented Feb 13, 2024 at 4:18
1 Answer 1
Setting up a streaming replication standby server in PostgreSQL is much easier than that. Follow the documentation. MySQL is quite different from PostgreSQL when it comes to replication.
A simple setup could be as follows:
on the primary server, create a user with
LOGIN
andREPLICATION
, add an entry topg_hba.conf
that allows the standby server to connect with that user and reload the primaryon the standby server, perform a base backup with
pg_basebackup -h primary.server.com -U repuser -C -S slotname -D /data/directory -P
on the standby, edit
postgresql.conf
and setprimary_conninfo
to a connection string for the primary andprimary_slotname
to the name of the replication slot you just createdcreate an empty file called
standby.signal
in the standby's data directorystart the standby server
Explore related questions
See similar questions with these tags.