Under a heavy load of NOTIFY events, entries in the pg_listener table
for some events are deleted, effectively acting as though UNLISTEN were
called.
I have only been able to make this occur on a PostgreSQL server running
on Windows. I cannot reproduce under Linux.
PostgreSQL version: 8.3.4
Operating System: Windows XP
I have provided some shell script that can reproduce the problem. It
helps to use three psql sessions.
First start a session that listens for two events ("first" and
"second"), then periodically polls for notifications:
check_for_events | psql -h windows_server -U postgres postgres
Second, start an interactive session and execute the command "SELECT *
from pg_listener". You should see the events "first" and "second" listed.
Third, start a session to do repeated notification. The script produces
"NOTIFY first" and "NOTIFY second" in separate transactions repeatedly.
generate_events | psql -h windows_server -U postgres postgres
Continue to check the pg_listener table in the interactive session.
Very quickly one of the two events will disappear from the table.
Strangely, when I execute the same scripts against a database server on
a CentOS Linux system, this problem does not occur.
#!/bin/sh
poll_sec=15
imax=`expr 10000 / ${poll_sec}`
if [ $# -ge 1 ]; then
imax=$1
fi
echo "LISTEN first;"
echo "LISTEN second;"
i=0
while [ $i -lt $imax ]; do
echo "SELECT pg_sleep(${poll_sec});"
i=`expr $i + 1`
done
#!/bin/sh
imax=100000
autocommit=1
if [ $# -ge 1 ]; then
imax=$1
fi
echo "BEGIN;"
i=0
while [ $i -lt $imax ]; do
#echo "NOTIFY \"a_fairly_long_event_name_followed_by_colon:INSERT\";"
#echo "NOTIFY \"a_fairly_long_event_name_followed_by_colon:UPDATE\";"
#echo "NOTIFY \"a_fairly_long_event_name_followed_by_colon:INSERT\";"
#echo "NOTIFY \"a_very_different_event_name\";"
echo "NOTIFY first;"
echo "NOTIFY second;"
if [ "${autocommit}" ]; then
echo "COMMIT;"
echo "BEGIN;"
fi
i=`expr $i + 1`
done
echo "COMMIT;"