Jan pointed out that elog(FATAL) out of ReverifyMyDatabase() leaves
shared memory in an un-cleaned-up state (buffer refcounts > 0).
There might also be other unaccounted-for problems, I suspect.
I do not like his fix (heap_endscan before the elog(FATAL)) because
it only plugs this specific hole in the dike, not the whole class of
problems.

The reason that the normal process-exit cleanup doesn't fix this is that
ReverifyMyDatabase() runs before we've entered the main loop in
PostgresMain, and so elog() just goes straight to proc_exit() instead of
longjmp'ing to the error recovery code in PostgresMain.

My feeling is that proc_exit() ought to be prepared to do *everything*
that is needed to shut down a backend, and that in fact elog()'s
behavior for FATAL is bogus even in the post-startup case.  It should
be sufficient to call proc_exit() to exit after a FATAL error.  If it
isn't, then the other half-dozen places that call proc_exit() are broken
too.

Similarly, it's broken that PostgresMain needs to do several things
before calling proc_exit.  Those things ought to be done *by* proc_exit.

Accordingly, I propose registering more cleanup routines with
on_proc_exit so that the right things happen in all exit cases, whether
normal, FATAL, or backend-startup; and removing the extra calls in
elog() and PostgresMain().

Comments, objections?

			regards, tom lane

Fri, 15 Dec 2000 16:25:56 -0500
Tom Lane <tgl@sss.pgh.pa.us>
Cleaning up backend-exit cleanup