On Mon, 2008-06-09 at 14:07 -0400, Alvaro Herrera wrote: > Simon Riggs wrote: > > > If we break down the action into two parts. > > > > ALTER TABLE ... ADD CONSTRAINT foo FOREIGN KEY ... NOVALIDATE; > > which holds exclusive lock, but only momentarily > > After this runs any new data is validated at moment of data change, but > > the older data has yet to be validated. > > > > ALTER TABLE ... VALIDATE CONSTRAINT foo > > which runs lengthy check, though only grabs lock as last part of action > > The problem I see with this approach in general (two-phase FK creation) > is that you have to keep the same transaction for the first and second > command, but you really want concurrent backends to see the tuple for > the not-yet-validated constraint row.
Well, they *must* be in separate transactions if we are to avoid holding an AccessExclusiveLock while we perform the check. Plus the whole idea is to perform the second part at some other non-critical time, though we all agree that never performing the check at all is foolhardy. Maybe we say that you can defer the check, but after a while autovacuum runs it for you if you haven't done so. It would certainly be useful to run the VALIDATE part as a background task with vacuum wait enabled. > Another benefit that could arise from this is that the hypothetical > VALIDATE CONSTRAINT step could validate more than one constraint at a > time, possibly processing all the constraints with a single table scan. Good thought, though not as useful for FK checks. -- Simon Riggs www.2ndQuadrant.com PostgreSQL Training, Services and Support -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers