PL/TCL Patch to prevent postgres from becoming multithreaded

From: "Marshall, Steve" <smarshall(at)wsi(dot)com>
To: pgsql-patches(at)postgresql(dot)org
Subject: PL/TCL Patch to prevent postgres from becoming multithreaded
Date: 2007-09-11 19:43:10
Message-ID: 46E6EFCE.1030809@wsi.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers pgsql-patches

There is a problem in PL/TCL that can cause the postgres backend to
become multithreaded. Postgres is not designed to be multithreaded, so
this causes downstream errors in signal handling. We have seen this
cause a number of "unexpected state" errors associated with notification
handling; however, unpredictable signal handling would be likely to
cause other errors as well.

Some sample scripts are attached which will reproduce this problem when
running against a multithreaded version of TCL, but will work without
error with single-threaded TCL library. The scripts are a combination
of Unix shell, perl DBI, and SQL commands. The postgres process can be
seen to have multiple threads using the Linux command "ps -Lwfu
postgres". In this command the NLWP columns will be 2 for multithreaded
backend processes. The threaded/non-threaded state of the TCL library
can be ascertained on Linux using ldd to determine if libpthread.so is
linked to the TCL library (e.g. "ldd /usr/lib/libtcl8.4.so").

The multithreaded behavior occurs the first time PL/TCL is used in a
postgres backend, but only when postgres is linked against a
multithread-enabled version of libtcl. Thus, this problem can be
side-stepped by linking against the proper TCL library. However
multithreaded TCL libraries are becoming the norm in Linux distributions
and seems ubiquitous in the Windows world. Therefore a fix to the
PL/TCL code is warrented.

We determined that postgres became multithreaded during the creation of
the TCL interpreter in a function called tcl_InitNotifier. This
function is part of TCL's Notifier subsystem, which is used to monitor
for events asynchronously from the TCL event loop. Although initialized
when an interpreter is created, the Notifier subsystem is not used until
a process enters the TCL event loop. This never happens within a
postgres process, because postgres implements its own event loop.
Therefore the initialization of the Notifier subsystem is not necessary
within the context of PL/TCL.

Our solution was to disable the Notifier subsystem by overriding the
functions associated with it using the Tcl_SetNotifier function. This
allows 8 functions related to the Notifier to overriden. Even though we
found only two of the functions were ever called within postgres, we
overrode 8 functions with no-op versions, just for completeness. A
patch file containing the changes to pltcl.c from its 8.2.4 version is
also attached.

We tested this patch with PostgreSQL 8.2.4 on both RedHat Enterprise 4.0
usingTCL 8.4 (single threaded) and RHE 5.0 using TCL 8.4.13
(multithreaded). We expect this solution to work with Windows as well,
although we have not tested it. There may be some problems using this
solution with old versions of TCL that pre-date the Tcl_SetNotifier
function. However this function has been around for quite a while; it
was added in in the TCL 8.2 release, circa 2000.

We hope this patch will be considered for a future PostgreSQL release.

Steve Marshall
Paul Bayer
Doug Knight
WSI Corporation

Attachment Content-Type Size
pltcl_multithread_bug_test.tar.gz application/x-gzip 936 bytes
pltcl.c.8.2.4.patch text/plain 4.2 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2007-09-11 20:12:54 Re: invalidly encoded strings
Previous Message Tom Lane 2007-09-11 19:41:54 Re: pg_dump and money type

Browse pgsql-patches by date

  From Date Subject
Next Message Tom Lane 2007-09-11 20:10:49 Re: HOT patch - version 15
Previous Message Tom Lane 2007-09-11 19:31:15 Re: invalidly encoded strings