Walsender doesn't process options passed in the startup packet

Started by Fujii Masaoover 15 years ago8 messages
#1Fujii Masao
masao.fujii@gmail.com
1 attachment(s)

Hi,

I found walsender didn't process options (e.g., application_name
in primary_conninfo) passed in the startup packet. The cause is
that walsender doesn't execute process_postgres_switches() and
SetConfigOption() in InitPostgres().

The attached patch fixes this bug.

Regards,

--
Fujii Masao
NIPPON TELEGRAPH AND TELEPHONE CORPORATION
NTT Open Source Software Center

Attachments:

startup_packet_options_and_walsender_v1.patchapplication/octet-stream; name=startup_packet_options_and_walsender_v1.patchDownload
*** a/src/backend/utils/init/postinit.c
--- b/src/backend/utils/init/postinit.c
***************
*** 65,70 **** static void CheckMyDatabase(const char *name, bool am_superuser);
--- 65,71 ----
  static void InitCommunication(void);
  static void ShutdownPostgres(int code, Datum arg);
  static bool ThereIsAtLeastOneRole(void);
+ static void process_startup_options(Port *port, bool am_superuser);
  static void process_settings(Oid databaseid, Oid roleid);
  
  
***************
*** 476,482 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
  {
  	bool		bootstrap = IsBootstrapProcessingMode();
  	bool		am_superuser;
- 	GucContext	gucctx;
  	char	   *fullpath;
  	char		dbname[NAMEDATALEN];
  
--- 477,482 ----
***************
*** 661,666 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
--- 661,668 ----
  			ereport(FATAL,
  					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  					 errmsg("must be superuser to start walsender")));
+ 		/* process any options passed in the startup packet */
+ 		process_startup_options(MyProcPort, am_superuser);
  		/* report this backend in the PgBackendStatus array */
  		pgstat_bestart();
  		/* close the transaction we started above */
***************
*** 811,843 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
  		CheckMyDatabase(dbname, am_superuser);
  
  	/*
! 	 * Now process any command-line switches that were included in the startup
! 	 * packet, if we are in a regular backend.	We couldn't do this before
  	 * because we didn't know if client is a superuser.
  	 */
  	gucctx = am_superuser ? PGC_SUSET : PGC_BACKEND;
  
! 	if (MyProcPort != NULL &&
! 		MyProcPort->cmdline_options != NULL)
  	{
  		/*
  		 * The maximum possible number of commandline arguments that could
! 		 * come from MyProcPort->cmdline_options is (strlen + 1) / 2; see
  		 * pg_split_opts().
  		 */
  		char	  **av;
  		int			maxac;
  		int			ac;
  
! 		maxac = 2 + (strlen(MyProcPort->cmdline_options) + 1) / 2;
  
  		av = (char **) palloc(maxac * sizeof(char *));
  		ac = 0;
  
  		av[ac++] = "postgres";
  
! 		/* Note this mangles MyProcPort->cmdline_options */
! 		pg_split_opts(av, &ac, MyProcPort->cmdline_options);
  
  		av[ac] = NULL;
  
--- 813,887 ----
  		CheckMyDatabase(dbname, am_superuser);
  
  	/*
! 	 * Now process any command-line switches and any additional GUC variable
! 	 * settings passed in the startup packet.	We couldn't do this before
  	 * because we didn't know if client is a superuser.
  	 */
+ 	process_startup_options(MyProcPort, am_superuser);
+ 
+ 	/* Process pg_db_role_setting options */
+ 	process_settings(MyDatabaseId, GetSessionUserId());
+ 
+ 	/* Apply PostAuthDelay as soon as we've read all options */
+ 	if (PostAuthDelay > 0)
+ 		pg_usleep(PostAuthDelay * 1000000L);
+ 
+ 	/*
+ 	 * Initialize various default states that can't be set up until we've
+ 	 * selected the active user and gotten the right GUC settings.
+ 	 */
+ 
+ 	/* set default namespace search path */
+ 	InitializeSearchPath();
+ 
+ 	/* initialize client encoding */
+ 	InitializeClientEncoding();
+ 
+ 	/* report this backend in the PgBackendStatus array */
+ 	if (!bootstrap)
+ 		pgstat_bestart();
+ 
+ 	/* close the transaction we started above */
+ 	if (!bootstrap)
+ 		CommitTransactionCommand();
+ }
+ 
+ /*
+  * Process any command-line switches and any additional GUC variable
+  * settings passed in the startup packet.
+  */
+ static void
+ process_startup_options(Port *port, bool am_superuser)
+ {
+ 	GucContext	gucctx;
+ 
+ 	/*
+ 	 * Now process any command-line switches that were included in the startup
+ 	 * packet, if we are in a regular backend.
+ 	 */
  	gucctx = am_superuser ? PGC_SUSET : PGC_BACKEND;
  
! 	if (port != NULL &&
! 		port->cmdline_options != NULL)
  	{
  		/*
  		 * The maximum possible number of commandline arguments that could
! 		 * come from port->cmdline_options is (strlen + 1) / 2; see
  		 * pg_split_opts().
  		 */
  		char	  **av;
  		int			maxac;
  		int			ac;
  
! 		maxac = 2 + (strlen(port->cmdline_options) + 1) / 2;
  
  		av = (char **) palloc(maxac * sizeof(char *));
  		ac = 0;
  
  		av[ac++] = "postgres";
  
! 		/* Note this mangles port->cmdline_options */
! 		pg_split_opts(av, &ac, port->cmdline_options);
  
  		av[ac] = NULL;
  
***************
*** 850,858 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
  	 * Process any additional GUC variable settings passed in startup packet.
  	 * These are handled exactly like command-line variables.
  	 */
! 	if (MyProcPort != NULL)
  	{
! 		ListCell   *gucopts = list_head(MyProcPort->guc_options);
  
  		while (gucopts)
  		{
--- 894,902 ----
  	 * Process any additional GUC variable settings passed in startup packet.
  	 * These are handled exactly like command-line variables.
  	 */
! 	if (port != NULL)
  	{
! 		ListCell   *gucopts = list_head(port->guc_options);
  
  		while (gucopts)
  		{
***************
*** 868,899 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
  			SetConfigOption(name, value, gucctx, PGC_S_CLIENT);
  		}
  	}
- 
- 	/* Process pg_db_role_setting options */
- 	process_settings(MyDatabaseId, GetSessionUserId());
- 
- 	/* Apply PostAuthDelay as soon as we've read all options */
- 	if (PostAuthDelay > 0)
- 		pg_usleep(PostAuthDelay * 1000000L);
- 
- 	/*
- 	 * Initialize various default states that can't be set up until we've
- 	 * selected the active user and gotten the right GUC settings.
- 	 */
- 
- 	/* set default namespace search path */
- 	InitializeSearchPath();
- 
- 	/* initialize client encoding */
- 	InitializeClientEncoding();
- 
- 	/* report this backend in the PgBackendStatus array */
- 	if (!bootstrap)
- 		pgstat_bestart();
- 
- 	/* close the transaction we started above */
- 	if (!bootstrap)
- 		CommitTransactionCommand();
  }
  
  /*
--- 912,917 ----
#2Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Fujii Masao (#1)
Re: Walsender doesn't process options passed in the startup packet

On 10/09/10 13:17, Fujii Masao wrote:

Hi,

I found walsender didn't process options (e.g., application_name
in primary_conninfo) passed in the startup packet. The cause is
that walsender doesn't execute process_postgres_switches() and
SetConfigOption() in InitPostgres().

The attached patch fixes this bug.

Hmm, should walsender call InitializeClientEncoding too? It affects
error messages. And what about per-user settings in pg_db_role_setting?

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com

#3Fujii Masao
masao.fujii@gmail.com
In reply to: Heikki Linnakangas (#2)
1 attachment(s)
Re: Walsender doesn't process options passed in the startup packet

On Fri, Sep 10, 2010 at 7:54 PM, Heikki Linnakangas
<heikki.linnakangas@enterprisedb.com> wrote:

I found walsender didn't process options (e.g., application_name
in primary_conninfo) passed in the startup packet. The cause is
that walsender doesn't execute process_postgres_switches() and
SetConfigOption() in InitPostgres().

The attached patch fixes this bug.

Hmm, should walsender call InitializeClientEncoding too? It affects error
messages. And what about per-user settings in pg_db_role_setting?

Yes, we should do both. SetDatabasePath() and RelationCacheInitializePhase3()
need to be called before accessing to pg_db_role_setting. And we should apply
PostAuthDelay. I attached the updated patch.

BTW, this issue seems to derive from the following commit.
http://archives.postgresql.org/pgsql-committers/2010-04/msg00175.php

Regards,

--
Fujii Masao
NIPPON TELEGRAPH AND TELEPHONE CORPORATION
NTT Open Source Software Center

Attachments:

startup_packet_options_and_walsender_v2.patchapplication/octet-stream; name=startup_packet_options_and_walsender_v2.patchDownload
*** a/src/backend/utils/init/postinit.c
--- b/src/backend/utils/init/postinit.c
***************
*** 65,70 **** static void CheckMyDatabase(const char *name, bool am_superuser);
--- 65,71 ----
  static void InitCommunication(void);
  static void ShutdownPostgres(int code, Datum arg);
  static bool ThereIsAtLeastOneRole(void);
+ static void process_startup_options(Port *port, bool am_superuser);
  static void process_settings(Oid databaseid, Oid roleid);
  
  
***************
*** 476,482 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
  {
  	bool		bootstrap = IsBootstrapProcessingMode();
  	bool		am_superuser;
- 	GucContext	gucctx;
  	char	   *fullpath;
  	char		dbname[NAMEDATALEN];
  
--- 477,482 ----
***************
*** 656,670 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
--- 656,697 ----
  	if (am_walsender)
  	{
  		Assert(!bootstrap);
+ 
  		/* must have authenticated as a superuser */
  		if (!am_superuser)
  			ereport(FATAL,
  					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  					 errmsg("must be superuser to start walsender")));
+ 
+ 		/* process any options passed in the startup packet */
+ 		process_startup_options(MyProcPort, am_superuser);
+ 
+ 		/*
+ 		 * Process pg_db_role_setting options. We use default template
+ 		 * database and default tablespace temporarily for accessing
+ 		 * to the system catalogs.
+ 		 */
+ 		MyDatabaseId = TemplateDbOid;
+ 		MyDatabaseTableSpace = DEFAULTTABLESPACE_OID;
+ 		fullpath = GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace);
+ 		SetDatabasePath(fullpath);
+ 		RelationCacheInitializePhase3();
+ 		process_settings(MyDatabaseId, GetSessionUserId());
+ 		MyDatabaseId = MyDatabaseTableSpace = InvalidOid;
+ 
+ 		/* Apply PostAuthDelay as soon as we've read all options */
+ 		if (PostAuthDelay > 0)
+ 			pg_usleep(PostAuthDelay * 1000000L);
+ 
+ 		/* initialize client encoding */
+ 		InitializeClientEncoding();
+ 
  		/* report this backend in the PgBackendStatus array */
  		pgstat_bestart();
+ 
  		/* close the transaction we started above */
  		CommitTransactionCommand();
+ 
  		return;
  	}
  
***************
*** 811,843 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
  		CheckMyDatabase(dbname, am_superuser);
  
  	/*
! 	 * Now process any command-line switches that were included in the startup
! 	 * packet, if we are in a regular backend.	We couldn't do this before
  	 * because we didn't know if client is a superuser.
  	 */
  	gucctx = am_superuser ? PGC_SUSET : PGC_BACKEND;
  
! 	if (MyProcPort != NULL &&
! 		MyProcPort->cmdline_options != NULL)
  	{
  		/*
  		 * The maximum possible number of commandline arguments that could
! 		 * come from MyProcPort->cmdline_options is (strlen + 1) / 2; see
  		 * pg_split_opts().
  		 */
  		char	  **av;
  		int			maxac;
  		int			ac;
  
! 		maxac = 2 + (strlen(MyProcPort->cmdline_options) + 1) / 2;
  
  		av = (char **) palloc(maxac * sizeof(char *));
  		ac = 0;
  
  		av[ac++] = "postgres";
  
! 		/* Note this mangles MyProcPort->cmdline_options */
! 		pg_split_opts(av, &ac, MyProcPort->cmdline_options);
  
  		av[ac] = NULL;
  
--- 838,912 ----
  		CheckMyDatabase(dbname, am_superuser);
  
  	/*
! 	 * Now process any command-line switches and any additional GUC variable
! 	 * settings passed in the startup packet.	We couldn't do this before
  	 * because we didn't know if client is a superuser.
  	 */
+ 	process_startup_options(MyProcPort, am_superuser);
+ 
+ 	/* Process pg_db_role_setting options */
+ 	process_settings(MyDatabaseId, GetSessionUserId());
+ 
+ 	/* Apply PostAuthDelay as soon as we've read all options */
+ 	if (PostAuthDelay > 0)
+ 		pg_usleep(PostAuthDelay * 1000000L);
+ 
+ 	/*
+ 	 * Initialize various default states that can't be set up until we've
+ 	 * selected the active user and gotten the right GUC settings.
+ 	 */
+ 
+ 	/* set default namespace search path */
+ 	InitializeSearchPath();
+ 
+ 	/* initialize client encoding */
+ 	InitializeClientEncoding();
+ 
+ 	/* report this backend in the PgBackendStatus array */
+ 	if (!bootstrap)
+ 		pgstat_bestart();
+ 
+ 	/* close the transaction we started above */
+ 	if (!bootstrap)
+ 		CommitTransactionCommand();
+ }
+ 
+ /*
+  * Process any command-line switches and any additional GUC variable
+  * settings passed in the startup packet.
+  */
+ static void
+ process_startup_options(Port *port, bool am_superuser)
+ {
+ 	GucContext	gucctx;
+ 
+ 	/*
+ 	 * Now process any command-line switches that were included in the startup
+ 	 * packet, if we are in a regular backend.
+ 	 */
  	gucctx = am_superuser ? PGC_SUSET : PGC_BACKEND;
  
! 	if (port != NULL &&
! 		port->cmdline_options != NULL)
  	{
  		/*
  		 * The maximum possible number of commandline arguments that could
! 		 * come from port->cmdline_options is (strlen + 1) / 2; see
  		 * pg_split_opts().
  		 */
  		char	  **av;
  		int			maxac;
  		int			ac;
  
! 		maxac = 2 + (strlen(port->cmdline_options) + 1) / 2;
  
  		av = (char **) palloc(maxac * sizeof(char *));
  		ac = 0;
  
  		av[ac++] = "postgres";
  
! 		/* Note this mangles port->cmdline_options */
! 		pg_split_opts(av, &ac, port->cmdline_options);
  
  		av[ac] = NULL;
  
***************
*** 850,858 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
  	 * Process any additional GUC variable settings passed in startup packet.
  	 * These are handled exactly like command-line variables.
  	 */
! 	if (MyProcPort != NULL)
  	{
! 		ListCell   *gucopts = list_head(MyProcPort->guc_options);
  
  		while (gucopts)
  		{
--- 919,927 ----
  	 * Process any additional GUC variable settings passed in startup packet.
  	 * These are handled exactly like command-line variables.
  	 */
! 	if (port != NULL)
  	{
! 		ListCell   *gucopts = list_head(port->guc_options);
  
  		while (gucopts)
  		{
***************
*** 868,899 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
  			SetConfigOption(name, value, gucctx, PGC_S_CLIENT);
  		}
  	}
- 
- 	/* Process pg_db_role_setting options */
- 	process_settings(MyDatabaseId, GetSessionUserId());
- 
- 	/* Apply PostAuthDelay as soon as we've read all options */
- 	if (PostAuthDelay > 0)
- 		pg_usleep(PostAuthDelay * 1000000L);
- 
- 	/*
- 	 * Initialize various default states that can't be set up until we've
- 	 * selected the active user and gotten the right GUC settings.
- 	 */
- 
- 	/* set default namespace search path */
- 	InitializeSearchPath();
- 
- 	/* initialize client encoding */
- 	InitializeClientEncoding();
- 
- 	/* report this backend in the PgBackendStatus array */
- 	if (!bootstrap)
- 		pgstat_bestart();
- 
- 	/* close the transaction we started above */
- 	if (!bootstrap)
- 		CommitTransactionCommand();
  }
  
  /*
--- 937,942 ----
#4Fujii Masao
masao.fujii@gmail.com
In reply to: Fujii Masao (#3)
Re: Walsender doesn't process options passed in the startup packet

On Fri, Sep 10, 2010 at 9:56 PM, Fujii Masao <masao.fujii@gmail.com> wrote:

BTW, this issue seems to derive from the following commit.
http://archives.postgresql.org/pgsql-committers/2010-04/msg00175.php

it was previously using an untenable assumption that template1 would
always be available to connect to

The above commit message shows that the updated patch is untenable too
since it assumes the existence of the template1.

Is there way to access to pg_db_role_setting without connecting to the
specific database? If not, it's difficult for walsender to process the
per-user settings since it's tied to no database.

Regards,

--
Fujii Masao
NIPPON TELEGRAPH AND TELEPHONE CORPORATION
NTT Open Source Software Center

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Fujii Masao (#4)
Re: Walsender doesn't process options passed in the startup packet

Fujii Masao <masao.fujii@gmail.com> writes:

On Fri, Sep 10, 2010 at 9:56 PM, Fujii Masao <masao.fujii@gmail.com> wrote:

BTW, this issue seems to derive from the following commit.
http://archives.postgresql.org/pgsql-committers/2010-04/msg00175.php

it was previously using an untenable assumption that template1 would
always be available to connect to

The above commit message shows that the updated patch is untenable too
since it assumes the existence of the template1.

Is there way to access to pg_db_role_setting without connecting to the
specific database? If not, it's difficult for walsender to process the
per-user settings since it's tied to no database.

Huh? walsender has no business applying any per-user or per-database
settings.

regards, tom lane

#6Fujii Masao
masao.fujii@gmail.com
In reply to: Tom Lane (#5)
1 attachment(s)
Re: Walsender doesn't process options passed in the startup packet

On Mon, Sep 13, 2010 at 12:32 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Huh?  walsender has no business applying any per-user or per-database
settings.

Okay. I got rid of the access to pg_db_role_setting from the patch.
I attached the updated version, which makes walsender process the
options passed in the startup packet, apply PostAuthDelay and initialize
client encoding.

OTOH, I can believe that some people would create a dedicated role for
replication and configure the parameters for replication on the role.
What about leaving the capability to apply per-role settings as a TODO
item?

Regards,

--
Fujii Masao
NIPPON TELEGRAPH AND TELEPHONE CORPORATION
NTT Open Source Software Center

Attachments:

startup_packet_options_and_walsender_v3.patchapplication/octet-stream; name=startup_packet_options_and_walsender_v3.patchDownload
*** a/src/backend/utils/init/postinit.c
--- b/src/backend/utils/init/postinit.c
***************
*** 65,70 **** static void CheckMyDatabase(const char *name, bool am_superuser);
--- 65,71 ----
  static void InitCommunication(void);
  static void ShutdownPostgres(int code, Datum arg);
  static bool ThereIsAtLeastOneRole(void);
+ static void process_startup_options(Port *port, bool am_superuser);
  static void process_settings(Oid databaseid, Oid roleid);
  
  
***************
*** 476,482 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
  {
  	bool		bootstrap = IsBootstrapProcessingMode();
  	bool		am_superuser;
- 	GucContext	gucctx;
  	char	   *fullpath;
  	char		dbname[NAMEDATALEN];
  
--- 477,482 ----
***************
*** 656,670 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
--- 656,684 ----
  	if (am_walsender)
  	{
  		Assert(!bootstrap);
+ 
  		/* must have authenticated as a superuser */
  		if (!am_superuser)
  			ereport(FATAL,
  					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  					 errmsg("must be superuser to start walsender")));
+ 
+ 		/* process any options passed in the startup packet */
+ 		process_startup_options(MyProcPort, am_superuser);
+ 
+ 		/* Apply PostAuthDelay as soon as we've read all options */
+ 		if (PostAuthDelay > 0)
+ 			pg_usleep(PostAuthDelay * 1000000L);
+ 
+ 		/* initialize client encoding */
+ 		InitializeClientEncoding();
+ 
  		/* report this backend in the PgBackendStatus array */
  		pgstat_bestart();
+ 
  		/* close the transaction we started above */
  		CommitTransactionCommand();
+ 
  		return;
  	}
  
***************
*** 811,843 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
  		CheckMyDatabase(dbname, am_superuser);
  
  	/*
! 	 * Now process any command-line switches that were included in the startup
! 	 * packet, if we are in a regular backend.	We couldn't do this before
  	 * because we didn't know if client is a superuser.
  	 */
  	gucctx = am_superuser ? PGC_SUSET : PGC_BACKEND;
  
! 	if (MyProcPort != NULL &&
! 		MyProcPort->cmdline_options != NULL)
  	{
  		/*
  		 * The maximum possible number of commandline arguments that could
! 		 * come from MyProcPort->cmdline_options is (strlen + 1) / 2; see
  		 * pg_split_opts().
  		 */
  		char	  **av;
  		int			maxac;
  		int			ac;
  
! 		maxac = 2 + (strlen(MyProcPort->cmdline_options) + 1) / 2;
  
  		av = (char **) palloc(maxac * sizeof(char *));
  		ac = 0;
  
  		av[ac++] = "postgres";
  
! 		/* Note this mangles MyProcPort->cmdline_options */
! 		pg_split_opts(av, &ac, MyProcPort->cmdline_options);
  
  		av[ac] = NULL;
  
--- 825,899 ----
  		CheckMyDatabase(dbname, am_superuser);
  
  	/*
! 	 * Now process any command-line switches and any additional GUC variable
! 	 * settings passed in the startup packet.	We couldn't do this before
  	 * because we didn't know if client is a superuser.
  	 */
+ 	process_startup_options(MyProcPort, am_superuser);
+ 
+ 	/* Process pg_db_role_setting options */
+ 	process_settings(MyDatabaseId, GetSessionUserId());
+ 
+ 	/* Apply PostAuthDelay as soon as we've read all options */
+ 	if (PostAuthDelay > 0)
+ 		pg_usleep(PostAuthDelay * 1000000L);
+ 
+ 	/*
+ 	 * Initialize various default states that can't be set up until we've
+ 	 * selected the active user and gotten the right GUC settings.
+ 	 */
+ 
+ 	/* set default namespace search path */
+ 	InitializeSearchPath();
+ 
+ 	/* initialize client encoding */
+ 	InitializeClientEncoding();
+ 
+ 	/* report this backend in the PgBackendStatus array */
+ 	if (!bootstrap)
+ 		pgstat_bestart();
+ 
+ 	/* close the transaction we started above */
+ 	if (!bootstrap)
+ 		CommitTransactionCommand();
+ }
+ 
+ /*
+  * Process any command-line switches and any additional GUC variable
+  * settings passed in the startup packet.
+  */
+ static void
+ process_startup_options(Port *port, bool am_superuser)
+ {
+ 	GucContext	gucctx;
+ 
+ 	/*
+ 	 * Now process any command-line switches that were included in the startup
+ 	 * packet, if we are in a regular backend.
+ 	 */
  	gucctx = am_superuser ? PGC_SUSET : PGC_BACKEND;
  
! 	if (port != NULL &&
! 		port->cmdline_options != NULL)
  	{
  		/*
  		 * The maximum possible number of commandline arguments that could
! 		 * come from port->cmdline_options is (strlen + 1) / 2; see
  		 * pg_split_opts().
  		 */
  		char	  **av;
  		int			maxac;
  		int			ac;
  
! 		maxac = 2 + (strlen(port->cmdline_options) + 1) / 2;
  
  		av = (char **) palloc(maxac * sizeof(char *));
  		ac = 0;
  
  		av[ac++] = "postgres";
  
! 		/* Note this mangles port->cmdline_options */
! 		pg_split_opts(av, &ac, port->cmdline_options);
  
  		av[ac] = NULL;
  
***************
*** 850,858 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
  	 * Process any additional GUC variable settings passed in startup packet.
  	 * These are handled exactly like command-line variables.
  	 */
! 	if (MyProcPort != NULL)
  	{
! 		ListCell   *gucopts = list_head(MyProcPort->guc_options);
  
  		while (gucopts)
  		{
--- 906,914 ----
  	 * Process any additional GUC variable settings passed in startup packet.
  	 * These are handled exactly like command-line variables.
  	 */
! 	if (port != NULL)
  	{
! 		ListCell   *gucopts = list_head(port->guc_options);
  
  		while (gucopts)
  		{
***************
*** 868,899 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
  			SetConfigOption(name, value, gucctx, PGC_S_CLIENT);
  		}
  	}
- 
- 	/* Process pg_db_role_setting options */
- 	process_settings(MyDatabaseId, GetSessionUserId());
- 
- 	/* Apply PostAuthDelay as soon as we've read all options */
- 	if (PostAuthDelay > 0)
- 		pg_usleep(PostAuthDelay * 1000000L);
- 
- 	/*
- 	 * Initialize various default states that can't be set up until we've
- 	 * selected the active user and gotten the right GUC settings.
- 	 */
- 
- 	/* set default namespace search path */
- 	InitializeSearchPath();
- 
- 	/* initialize client encoding */
- 	InitializeClientEncoding();
- 
- 	/* report this backend in the PgBackendStatus array */
- 	if (!bootstrap)
- 		pgstat_bestart();
- 
- 	/* close the transaction we started above */
- 	if (!bootstrap)
- 		CommitTransactionCommand();
  }
  
  /*
--- 924,929 ----
#7Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Fujii Masao (#6)
Re: Walsender doesn't process options passed in the startup packet

On 13/09/10 08:10, Fujii Masao wrote:

On Mon, Sep 13, 2010 at 12:32 PM, Tom Lane<tgl@sss.pgh.pa.us> wrote:

Huh? walsender has no business applying any per-user or per-database
settings.

Okay. I got rid of the access to pg_db_role_setting from the patch.
I attached the updated version, which makes walsender process the
options passed in the startup packet, apply PostAuthDelay and initialize
client encoding.

OTOH, I can believe that some people would create a dedicated role for
replication and configure the parameters for replication on the role.

Right, per-database settings clearly make no sense, but per-role
settings do. There isn't very many settings that make sense for
walsender, but client_encoding is one example. I agree it's not terribly
useful, but would be nice for the sake of completeness.

What about leaving the capability to apply per-role settings as a TODO
item?

Yeah, seems best at this point.

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com

#8Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Fujii Masao (#6)
Re: Walsender doesn't process options passed in the startup packet

On 13/09/10 08:10, Fujii Masao wrote:

Okay. I got rid of the access to pg_db_role_setting from the patch.
I attached the updated version, which makes walsender process the
options passed in the startup packet, apply PostAuthDelay and initialize
client encoding.

Thanks, committed.

I moved the check for "MyProcPort == NULL" case to the callers of
process_startup_packet(), it seems more logical to me.

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com