databasepostgresqldatabase-replication

Difference between Stream Replication and logical replication


Could anybody tell me more about difference between physical replication and logical replication in PostgreSQL?


Solution

  • TL;DR: Logical replication sends row-by-row changes, physical replication sends disk block changes. Logical replication is better for some tasks, physical replication for others.

    Note that in PostgreSQL 12 (current at time of update) logical replication is stable and reliable, but quite limited. Use physical replication if you are asking this question.


    Streaming replication can be logical replication. It's all a bit complicated.

    WAL-shipping vs streaming

    There are two main ways to send data from master to replica in PostgreSQL:

    Thus, the two methods have different purposes. However, both of them transport physical WAL archives from primary to replica; they differ only in the timing, and whether the WAL segments get archived somewhere else along the way.

    You can and usually should combine the two methods, using streaming replication usually, but with archive_command enabled. Then on the replica, set a restore_command to allow the replica to fall back to restore from WAL archives if there are direct connectivity issues between primary and replica.

    Asynchronous vs synchronous streaming

    On top of that, there's synchronous and asynchronous streaming replication:

    You can't have synchronous log shipping.

    You can actually combine log shipping and asynchronous replication to protect against having to recreate a replica if it falls too far behind, without risking affecting the master. This is an ideal configuration for many deployments, combined with monitoring how far the replica is behind the master to ensure it's within acceptable disaster recovery limits.

    Logical vs physical

    On top of that we have logical vs physical streaming replication, as introduced in PostgreSQL 9.4:

    In exchange, it's simple and efficient to apply the changes on the replica, and the replica is reliably exactly the same as the master. DDL is replicated transparently, just like everything else, so it requires no special handling. It can also stream big transactions as they happen, so there is little delay between commit on the master and commit on the replica even for big changes.

    Physical replication is mature, well tested, and widely adopted.

    It replicates only one database at a time. It sends only row changes and only for committed transactions, and it doesn't have to send vacuum data, index changes, etc. It can selectively send data only for some tables within a database. This makes logical replication much more bandwidth-efficient.

    Operating at a higher level also means that you can do transactions on the replica databases. You can create temporary and unlogged tables. Even normal tables, if you want. You can use foreign data wrappers, views, create functions, whatever you like. There's no need to cancel queries if they run too long either.

    Logical replication can also be used to build multi-master replication in PostgreSQL, which is not possible using physical replication.

    In exchange, though, it can't (currently) stream big transactions as they happen. It has to wait until they commit. So there can be a long delay between a big transaction committing on the master and being applied to the replica.

    It replays transactions strictly in commit order, so small fast transactions can get stuck behind a big transaction and be delayed quite a while.

    DDL isn't handled automatically. You have to keep the table definitions in sync between master and replica yourself, or the application using logical replication has to have its own facilities to do this. It can be complicated to get this right.

    The apply process its self is more complicated than "write some bytes where I'm told to" as well. It also takes more resources on the replica than physical replication does.

    Current logical replication implementations are not mature or widely adopted, or particularly easy to use.

    Too many options, tell me what to do

    Phew. Complicated, huh? And I haven't even got into the details of delayed replication, slots, max_wal_size, timelines, how promotion works, Postgres-XL, BDR and multimaster, etc.

    So what should you do?

    There's no single right answer. Otherwise PostgreSQL would only support that one way. But there are a few common use cases:

    For backup and disaster recovery use pgbarman to make base backups and retain WAL for you, providing easy to manage continuous backup. You should still take periodic pg_dump backups as extra insurance.

    For high availability with zero data loss risk use streaming synchronous replication.

    For high availability with low data loss risk and better performance you should use asynchronous streaming replication. Either have WAL archiving enabled for fallback or use a replication slot. Monitor how far the replica is behind the master using external tools like Icinga.

    References