diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2012-10-05 17:13:07 +0300 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2012-10-05 17:21:12 +0300 |
commit | fd5942c18f977a36fec66a8d1281092805f2a55e (patch) | |
tree | 722501422b9f52f412729096be8f49688212474c /src/backend/tcop/postgres.c | |
parent | 1997f34db4687e671690ed054c8f30bb501b1168 (diff) | |
download | postgresql-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.c | 51 |
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) |