Add GUC to enable logging of replication commands.
authorFujii Masao <fujii@postgresql.org>
Fri, 12 Sep 2014 17:55:45 +0000 (02:55 +0900)
committerFujii Masao <fujii@postgresql.org>
Fri, 12 Sep 2014 17:55:45 +0000 (02:55 +0900)
Previously replication commands like IDENTIFY_COMMAND were not logged
even when log_statements is set to all. Some users who want to audit
all types of statements were not satisfied with this situation. To
address the problem, this commit adds new GUC log_replication_commands.
If it's enabled, all replication commands are logged in the server log.

There are many ways to allow us to enable that logging. For example,
we can extend log_statement so that replication commands are logged
when it's set to all. But per discussion in the community, we reached
the consensus to add separate GUC for that.

Reviewed by Ian Barwick, Robert Haas and Heikki Linnakangas.

doc/src/sgml/config.sgml
doc/src/sgml/protocol.sgml
src/backend/replication/walsender.c
src/backend/utils/misc/guc.c
src/backend/utils/misc/postgresql.conf.sample
src/include/replication/walsender.h

index 1e5c328d80402b7da4be575b408c1ecc86d12da6..74110f077226a0546ef84aca7c0f245f0ea7975e 100644 (file)
@@ -4672,6 +4672,22 @@ FROM pg_stat_activity;
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-log-replication-commands" xreflabel="log_replication_commands">
+      <term><varname>log_replication_commands</varname> (<type>boolean</type>)
+      <indexterm>
+       <primary><varname>log_replication_commands</> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Causes each replication command to be logged in the server log.
+        See <xref linkend="protocol-replication"> for more information about
+        replication command. The default value is <literal>off</>.
+        Only superusers can change this setting.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-log-temp-files" xreflabel="log_temp_files">
       <term><varname>log_temp_files</varname> (<type>integer</type>)
       <indexterm>
index a8a09e4f0ec63f5fe586ccfc1f4caaa996e54baa..5f6ad6b5fb4bc0befa56d38e6806bbf40e213253 100644 (file)
@@ -1306,6 +1306,8 @@ To initiate streaming replication, the frontend sends the
 of <literal>true</> tells the backend to go into walsender mode, wherein a
 small set of replication commands can be issued instead of SQL statements. Only
 the simple query protocol can be used in walsender mode.
+Replication commands are logged in the server log when
+<xref linkend="guc-log-replication-commands"> is enabled.
 Passing <literal>database</> as the value instructs walsender to connect to
 the database specified in the <literal>dbname</> parameter, which will allow
 the connection to be used for logical replication from that database.
index 844a5dea1def123b6a9c8a75e2bd311c775bd92b..384c9b61ce1bfc13f4e60d417600ee343d8254e1 100644 (file)
@@ -108,6 +108,7 @@ bool        am_db_walsender = false;    /* Connected to a database? */
 int            max_wal_senders = 0;    /* the maximum number of concurrent walsenders */
 int            wal_sender_timeout = 60 * 1000;     /* maximum time to send one
                                                 * WAL data message */
+bool       log_replication_commands = false;
 
 /*
  * State for WalSndWakeupRequest
@@ -1267,14 +1268,20 @@ exec_replication_command(const char *cmd_string)
    MemoryContext cmd_context;
    MemoryContext old_context;
 
+   /*
+    * Log replication command if log_replication_commands is enabled.
+    * Even when it's disabled, log the command with DEBUG1 level for
+    * backward compatibility.
+    */
+   ereport(log_replication_commands ? LOG : DEBUG1,
+           (errmsg("received replication command: %s", cmd_string)));
+
    /*
     * CREATE_REPLICATION_SLOT ... LOGICAL exports a snapshot until the next
     * command arrives. Clean up the old stuff if there's anything.
     */
    SnapBuildClearExportedSnapshot();
 
-   elog(DEBUG1, "received replication command: %s", cmd_string);
-
    CHECK_FOR_INTERRUPTS();
 
    cmd_context = AllocSetContextCreate(CurrentMemoryContext,
index af667f54ada520db97d45b8929458dba0c6c96d2..0192def17a5b202ec49510a7f5b5b7e1b6d3d57a 100644 (file)
@@ -924,6 +924,15 @@ static struct config_bool ConfigureNamesBool[] =
        false,
        NULL, NULL, NULL
    },
+   {
+       {"log_replication_commands", PGC_SUSET, LOGGING_WHAT,
+           gettext_noop("Logs each replication command."),
+           NULL
+       },
+       &log_replication_commands,
+       false,
+       NULL, NULL, NULL
+   },
    {
        {"debug_assertions", PGC_INTERNAL, PRESET_OPTIONS,
            gettext_noop("Shows whether the running server has assertion checks enabled."),
index df98b02d788b6e70d5b71010bd8d0d25223f129c..1b5f39fa6c1f94a127e5ea09fdfb97be8e622cb9 100644 (file)
                    # e.g. '<%u%%%d> '
 #log_lock_waits = off          # log lock waits >= deadlock_timeout
 #log_statement = 'none'            # none, ddl, mod, all
+#log_replication_commands = off
 #log_temp_files = -1           # log temporary files equal or larger
                    # than the specified size in kilobytes;
                    # -1 disables, 0 logs all temp files
index cff2be6d8f6eec0b857d025c5c7c7332c4d72d33..d091e0f6d081a8e9d721c31a08581baa85a49ba3 100644 (file)
@@ -25,6 +25,7 @@ extern bool wake_wal_senders;
 /* user-settable parameters */
 extern int max_wal_senders;
 extern int wal_sender_timeout;
+extern bool    log_replication_commands;
 
 extern void InitWalSender(void);
 extern void exec_replication_command(const char *query_string);