Rod Taylor <pg@rbt.ca> writes:
> On Tue, 2005-04-26 at 23:22 -0400, Tom Lane wrote:
>> Rod Taylor <pg@rbt.ca> writes:
>>> I eventually clued in and made a TOC and removed all of the Slony items,
>>> but I'm still curious to know what exactly pg_restore had been doing for
>>> the last hour or so.
>>
>> You tell us ;-). You've got the test case, attach to it with a debugger
>> and find out what it's doing.
> I wasn't entirely sure how to "catch it in action" so I just used CTRL+C
> to interrupt the pg_restore process, and got these as backtraces:
I had forgotten about this problem, but noticed it again in my mail
folder. After staring at the code for awhile, I have a theory: whoever
added dollar-quote parsing to _sendSQLLine() did not understand that it
has to keep all its state in AH->sqlparse, because the input it's passed
can be broken into arbitrary bufferload boundaries. Suppose that the
input contains $1$2 (which should properly be parsed as two parameter
symbols) and a bufferload boundary happens to fall between the first $
and the 1. Because startDT is incorrectly treated as a reinitializable
local, the code will mistakenly decide that $1$ is a dollar-quote
start tag, and start looking for the matching close tag. As long as it
doesn't happen to find a match, all the rest of the output intended to
go to the database (including both SQL commands and COPY data) is going
to get crammed into AH->sqlBuf. This wouldn't be an infinite loop
exactly, but it could certainly drive the program into swap hell before
long, if the dump file contains sufficiently many megabytes of data.
To believe that this explains your report, we'd have to assume that the
Slony part of the dump included such a string and it wasn't within any
other form of quoting. I'm not sure offhand whether pg_dump would ever
actually produce such a string --- in most contexts I'd expect "$n" to
be surrounded by spaces.
Whether or not this actually is what you saw, the code is definitely broken.
Will work on cleaning it up.
regards, tom lane