Make sure you have set the application_name on each standby node. Decide the order of servers to be listed in the synchronous_standby_names parameter. Note that the standbys named must be directly attached standby nodes or else their names will be ignored. Synchronous replication is not possible for cascaded nodes, though cascaded standbys may be connected downstream. An example for a simple four node config of nodeA (master), nodeB, nodeC, and nodeD (standbys) would be set on nodeA as follows:
synchronous_standby_names = 'nodeB, nodeC, nodeD'
If you want to receive replies from the first two of the nodes in a list then we would specify this using the following special syntax:
synchronous_standby_names = '2 (nodeB, nodeC, nodeD)'
If you want to receive replies from any two nodes, known as quorum commit, then:
synchronous_standby_names = 'any 2 (nodeB, nodeC, nodeD)'
Set synchronous_standby_names on all of the nodes, not just the master.
You can see the sync_state of connected standbys using this query on the master:
SELECT
application_name
,state /* startup, backup, catchup or streaming */
,sync_priority /* 0, 1 or more */
,sync_state /* async, sync or potential */
FROM pg_stat_replication
ORDER BY sync_priority;
There are a few columns here with similar names, so be careful not to confuse them.
The sync_state column is just a human-readable form of sync_priority. When sync_state is async, the sync_priority value will be zero (0). Standby nodes mentioned in the synchronous_standby_names parameter will have a nonzero priority that corresponds to the order in which they are listed. The standby node with a priority of one (1) will be listed as having a sync_state value of sync. We refer to this node as the sync standby. Other standby nodes configured to provide feedback are shown with a sync_state value of potential and a sync_priority value more than 1.
If a server is listed in the synchronous_standby_names parameter, but is not currently connected, then it will not be shown at all by the preceding query, so it is possible that the node is shown with a lower actual priority value than the stated ordering in the parameter. Setting wal_receiver_status_interval to 0 on the standby will disable status messages completely, and the node will show as an async node, even if it is named in the synchronous_standby_names parameter. You may wish to do this when you are completely certain that a standby will never need to be a failover target, such as a test server.
The state for each server is shown as one of startup, catchup, or streaming. When another node connects, it will first show as startup, though only briefly before it moves to catchup. Once the node has caught up with the master, it will move to streaming, and only then will sync_priority be set to a nonzero value.
Catch-up typically occurs quickly after a disconnection or reconnection, such as when a standby node is restarted. When performing an initial base backup, the server will show as backup. After this, it will stay for an extended period at catchup. The delay at this point will vary according to the size of the database, so it could be a long period. Bear this in mind when configuring sync rep.
When a new standby node moves to the streaming mode, you'll see a message like this in the master node log:
LOG standby $APPLICATION_NAME is now the synchronous
standby with priority N