Thread: BUG #13427: postgres.exe fails to start on Korean Windows Server 2008: cannot perform encoding conversion outsid
BUG #13427: postgres.exe fails to start on Korean Windows Server 2008: cannot perform encoding conversion outsid
From
Dmitri.Bourlatchkov@software.dell.com
Date:
The following bug has been logged on the website: Bug reference: 13427 Logged by: Dmitri Bourlatchkov Email address: Dmitri.Bourlatchkov@software.dell.com PostgreSQL version: 9.4.3 Operating system: Windows Server 2008 (Korean) Description: 0. Log in as a local Administrator into a Korean version of the Windows Server 2008 1. Install PostgreSQL 9.4.3 using the Windows .exe installer from EnterpriseDB 2. Open cmd.exe shell 3. cd to potgresql/bin directory 4. Run postgresql.exe (no args) 5. Observe the following error message: ---- FATAL: XX000: cannot perform encoding conversion outside a transaction LOCATION: pg_do_encoding_conversion, src\backend\utils\mb\mbutils.c:360 ---- A similar message shows up when using pg_ctl.exe to start PostgreSQL. Trouble-shooting attempted: 1. Run set LC_CTYPE=C 2. Run postgresql.exe (no args) 3. The following expected error shows up: ---- Execution of PostgreSQL by a user with administrative permissions is not permitted. The server must be started under an unprivileged user ID to prevent possible system security compromises. See the documentation for more information on how to properly start the server. ---- Note: PostgreSQL _is_ able to run as a Windows Service without any environment modifications. Note: If the LC_CTYPE=C env. variable is set, PosgreSQL can also be started successfully via pg_ctl (under the Administrator user). Thanks, Dmitri.
Re: BUG #13427: postgres.exe fails to start on Korean Windows Server 2008: cannot perform encoding conversion outsid
From
Noah Misch
Date:
On Wed, Jun 10, 2015 at 02:32:35PM +0000, Dmitri.Bourlatchkov@software.dell.com wrote: > PostgreSQL version: 9.4.3 > Operating system: Windows Server 2008 (Korean) > 0. Log in as a local Administrator into a Korean version of the Windows > Server 2008 > 1. Install PostgreSQL 9.4.3 using the Windows .exe installer from > EnterpriseDB > 2. Open cmd.exe shell > 3. cd to potgresql/bin directory > 4. Run postgresql.exe (no args) > 5. Observe the following error message: > > ---- > FATAL: XX000: cannot perform encoding conversion outside a transaction > LOCATION: pg_do_encoding_conversion, src\backend\utils\mb\mbutils.c:360 > ---- > > A similar message shows up when using pg_ctl.exe to start PostgreSQL. Thanks for this report. One can reproduce this without Korean-specific OS configuration by setting LC_CTYPE=Korean in the environment and then, as you say, running postgres without arguments. Stack trace: postgres.exe!errfinish(int dummy, ...) Line 412 postgres.exe!elog_finish(int elevel, const char * fmt, ...) Line 1376 postgres.exe!pg_do_encoding_conversion(unsigned char * src, int len, int src_encoding, int dest_encoding) Line 362 postgres.exe!pgwin32_message_to_UTF16(const char * str, int len, int * utf16len) Line 1081 postgres.exe!write_console(const char * line, int len) Line 2111 postgres.exe!write_stderr(const char * fmt, ...) Line 3592 postgres.exe!SelectConfigFiles(const char * userDoption, const char * progname) Line 4297 postgres.exe!PostmasterMain(int argc, char * * argv) Line 802 Commit 49c817e is the proximate cause. On my Windows Server 2008 system, Korean is the only locale affected. It's affected because pg_enc2name_tbl lacks a UHC <-> CP949 mapping. I'll double check, but adding that mapping should fix this particular test case. That leaves other ways of reaching this error. I think e.g. an LC_CTYPE=C, ENCODING=LATIN9 database will still take this path. Any EmitErrorReport() can run pgwin32_message_to_UTF16(), and those have plenty of ways to run outside a transaction. I am inclined to restore the 9.3 and earlier semantics by having pgwin32_message_to_UTF16() proceed, when outside a transaction, as though the string is already UTF8. A robust fix would be to cache enough information about the message encoding to convert outside a transaction, exactly the way we protect database<->client encoding conversions. That feels more like a master-only change, though it's a borderline case. > Trouble-shooting attempted: > 1. Run set LC_CTYPE=C > 2. Run postgresql.exe (no args) > 3. The following expected error shows up: > > ---- > Execution of PostgreSQL by a user with administrative permissions is not > permitted. > The server must be started under an unprivileged user ID to prevent > possible system security compromises. See the documentation for > more information on how to properly start the server. > ---- > > Note: PostgreSQL _is_ able to run as a Windows Service without any > environment modifications. > > Note: If the LC_CTYPE=C env. variable is set, PosgreSQL can also be started > successfully via pg_ctl (under the Administrator user). That looks normal. pg_ctl has special code in CreateRestrictedProcess() to drop administrative privileges. To run raw postgres without pg_ctl, use an unprivileged account or drop privileges similarly in your own wrapper.
Re: BUG #13427: postgres.exe fails to start on Korean Windows Server 2008: cannot perform encoding conversion outsid
From
Noah Misch
Date:
On Tue, Aug 04, 2015 at 11:32:11PM -0400, Noah Misch wrote: > On Wed, Jun 10, 2015 at 02:32:35PM +0000, Dmitri.Bourlatchkov@software.dell.com wrote: > > 4. Run postgresql.exe (no args) > > 5. Observe the following error message: > > > > ---- > > FATAL: XX000: cannot perform encoding conversion outside a transaction > > LOCATION: pg_do_encoding_conversion, src\backend\utils\mb\mbutils.c:360 > > ---- > Commit 49c817e is the proximate cause. On my Windows Server 2008 system, > Korean is the only locale affected. It's affected because pg_enc2name_tbl > lacks a UHC <-> CP949 mapping. I'll double check, but adding that mapping > should fix this particular test case. > > That leaves other ways of reaching this error. I think e.g. an LC_CTYPE=C, > ENCODING=LATIN9 database will still take this path. LATIN9 does not, but LATIN8 does. Plain 'make check' fails early in Korean locales, and 'make check EXTRA_REGRESS_OPTS="--encoding=LATIN8 --no-locale"' fails in any OS locale. > Any EmitErrorReport() can > run pgwin32_message_to_UTF16(), and those have plenty of ways to run outside a > transaction. I am inclined to restore the 9.3 and earlier semantics by having > pgwin32_message_to_UTF16() proceed, when outside a transaction, as though the > string is already UTF8. I am attaching the two patches I plan to use. Either one by itself fixes the symptom you observed. > A robust fix would be to cache enough information > about the message encoding to convert outside a transaction, exactly the way > we protect database<->client encoding conversions. That feels more like a > master-only change, though it's a borderline case. I propose to add this to https://wiki.postgresql.org/wiki/Todo: * Multi-Language Support ** Windows: Cache MessageEncoding conversion for use outside transactions Thanks, nm