aboutsummaryrefslogtreecommitdiff
path: root/src/backend/tcop/postgres.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2012-10-05 17:13:07 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2012-10-05 17:21:12 +0300
commitfd5942c18f977a36fec66a8d1281092805f2a55e (patch)
tree722501422b9f52f412729096be8f49688212474c /src/backend/tcop/postgres.c
parent1997f34db4687e671690ed054c8f30bb501b1168 (diff)
downloadpostgresql-fd5942c18f977a36fec66a8d1281092805f2a55e.tar.gz
postgresql-fd5942c18f977a36fec66a8d1281092805f2a55e.zip
Use the regular main processing loop also in walsenders.
The regular backend's main loop handles signal handling and error recovery better than the current WAL sender command loop does. For example, if the client hangs and a SIGTERM is received before starting streaming, the walsender will now terminate immediately, rather than hang until the connection times out.
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r--src/backend/tcop/postgres.c51
1 files changed, 45 insertions, 6 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index f1248a851bf..585db1af89c 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -192,6 +192,7 @@ static int InteractiveBackend(StringInfo inBuf);
static int interactive_getc(void);
static int SocketBackend(StringInfo inBuf);
static int ReadCommand(StringInfo inBuf);
+static void forbidden_in_wal_sender(char firstchar);
static List *pg_rewrite_query(Query *query);
static bool check_log_statement(List *stmt_list);
static int errdetail_execute(List *raw_parsetree_list);
@@ -3720,12 +3721,9 @@ PostgresMain(int argc, char *argv[], const char *username)
if (IsUnderPostmaster && Log_disconnections)
on_proc_exit(log_disconnections, 0);
- /* If this is a WAL sender process, we're done with initialization. */
+ /* Perform initialization specific to a WAL sender process. */
if (am_walsender)
- {
- WalSenderMain(); /* does not return */
- abort();
- }
+ InitWalSender();
/*
* process any libraries that should be preloaded at backend start (this
@@ -3835,6 +3833,9 @@ PostgresMain(int argc, char *argv[], const char *username)
*/
AbortCurrentTransaction();
+ if (am_walsender)
+ WalSndErrorCleanup();
+
/*
* Now return to normal top-level context and clear ErrorContext for
* next time.
@@ -3969,7 +3970,10 @@ PostgresMain(int argc, char *argv[], const char *username)
query_string = pq_getmsgstring(&input_message);
pq_getmsgend(&input_message);
- exec_simple_query(query_string);
+ if (am_walsender)
+ exec_replication_command(query_string);
+ else
+ exec_simple_query(query_string);
send_ready_for_query = true;
}
@@ -3982,6 +3986,8 @@ PostgresMain(int argc, char *argv[], const char *username)
int numParams;
Oid *paramTypes = NULL;
+ forbidden_in_wal_sender(firstchar);
+
/* Set statement_timestamp() */
SetCurrentStatementStartTimestamp();
@@ -4004,6 +4010,8 @@ PostgresMain(int argc, char *argv[], const char *username)
break;
case 'B': /* bind */
+ forbidden_in_wal_sender(firstchar);
+
/* Set statement_timestamp() */
SetCurrentStatementStartTimestamp();
@@ -4019,6 +4027,8 @@ PostgresMain(int argc, char *argv[], const char *username)
const char *portal_name;
int max_rows;
+ forbidden_in_wal_sender(firstchar);
+
/* Set statement_timestamp() */
SetCurrentStatementStartTimestamp();
@@ -4031,6 +4041,8 @@ PostgresMain(int argc, char *argv[], const char *username)
break;
case 'F': /* fastpath function call */
+ forbidden_in_wal_sender(firstchar);
+
/* Set statement_timestamp() */
SetCurrentStatementStartTimestamp();
@@ -4078,6 +4090,8 @@ PostgresMain(int argc, char *argv[], const char *username)
int close_type;
const char *close_target;
+ forbidden_in_wal_sender(firstchar);
+
close_type = pq_getmsgbyte(&input_message);
close_target = pq_getmsgstring(&input_message);
pq_getmsgend(&input_message);
@@ -4120,6 +4134,8 @@ PostgresMain(int argc, char *argv[], const char *username)
int describe_type;
const char *describe_target;
+ forbidden_in_wal_sender(firstchar);
+
/* Set statement_timestamp() (needed for xact) */
SetCurrentStatementStartTimestamp();
@@ -4201,6 +4217,29 @@ PostgresMain(int argc, char *argv[], const char *username)
} /* end of input-reading loop */
}
+/*
+ * Throw an error if we're a WAL sender process.
+ *
+ * This is used to forbid anything else than simple query protocol messages
+ * in a WAL sender process. 'firstchar' specifies what kind of a forbidden
+ * message was received, and is used to construct the error message.
+ */
+static void
+forbidden_in_wal_sender(char firstchar)
+{
+ if (am_walsender)
+ {
+ if (firstchar == 'F')
+ ereport(ERROR,
+ (errcode(ERRCODE_PROTOCOL_VIOLATION),
+ errmsg("fastpath function calls not supported in a replication connection")));
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_PROTOCOL_VIOLATION),
+ errmsg("extended query protocol not supported in a replication connection")));
+ }
+}
+
/*
* Obtain platform stack depth limit (in bytes)