Re: Question about RI checks

Поиск
Список
Период
Сортировка
От Florian Pflug
Тема Re: Question about RI checks
Дата
Msg-id B19A73FB-F3E9-4264-9E17-3E464A174733@phlo.org
обсуждение исходный текст
Ответ на Re: Question about RI checks  (Kevin Grittner <kgrittn@ymail.com>)
Ответы Re: Question about RI checks  (Robert Haas <robertmhaas@gmail.com>)
Список pgsql-hackers
On Oct23, 2014, at 17:45 , Kevin Grittner <kgrittn@ymail.com> wrote:
> Every way I look at it, inside a REPEATABLE READ or SERIALIZABLE
> transaction a check for child rows when validating a parent DELETE
> should consider both rows which exist according to the transaction
> snapshot and according to a "current" snapshot.  Interestingly, the
> run of the query passes both snapshots through to the executor, but
> for this query the estate->es_crosscheck_snapshot field (which
> contains the transaction snapshot) doesn't seem to be consulted.
> It makes me wonder whether we were at some point doing this right
> and it later got broken.

I've been pondering a completely different way to fix this. Many years
ago I tried to get rid of the crosscheck snapshot completely by changing
the way locking conflicts are treated for REPEATABLE READ transactions
above.

The basic idea is that taking a share lock on a row implies that you're
going to apply further changes whose correctness depends on existence
of the row you lock. That, in particular, applies to the locks taken
by RI triggers -- we lock the parent row before we add children, because
the children's existence necessitates the existence of the parent. If
you take an exclusive lock, OTOH, that implies a modification of the row
itself (we never explicitly take that lock during an UPDATE or DELETE,
but we do so implicitly, because UPDATEs and DELETEs conflict with SHARE
locks). So after obtaining such a lock, its the lock holder's responsibility
to check that the desired update doesn't break anything, i.e. in the case
of RI that it doesn't create any orphaned children.

The only reason we need the crosscheck snapshot to do that is because
children may have been added (and the change committed) *after* the
transaction which removed the parent has taken its snapshot, but *before*
that transaction locks the parent row.

My proposal is to instead extend the locking protocol to prevent that.
Essentially, we have to raise a serialization error whenever
 1) We attempt to exclusively lock a row (this includes updating or deleting    it), and
 2) somebody else did hold a share lock on that row recently, and
 3) That somebody is invisible to us according to our snapshot.

My initial attempt to do that failed, because we used to have very little
means of storing the locking history - the only source of information was
the xmax field, so any update of a tuple removed information about previous
lock holders - even if that update was later aborted. I pondered using
multi-xids for this, but at the time I deemed that too risky - back at the
time, they had a few wraparound issues and the like which were OK for share
locks, but not for what I intended.

But now that we have KEY SHARE locks, the situation changes. We now rely on
multi-xids to a much greater extent, and AFAIK multi-xid wraparound is now
correctly dealt with. We also already ensure that the information contained
in multi-xids are preserved across tuple upgrades (otherwise, updating a row
on which someone holds a KEY SHARE lock would be broken).

So all that is missing, I think, is
 1) To make sure we only remove a multi-xid if none of the xids are invisible    to any snapshot (i.e. lie before
GlobalXminor something like that). 
 2) When we acquire a lock (either explicitly or implicitly by doing an    UPDATE or DELETE) check if all previous
committedlock holders are    visible according to our snapshot, and raise a serialization error    if not. 

The big advantage of doing that over fixing the crosscheck logic would be
that it'd make it possible to write concurrency-safe FK triggers in any
procedural language.

best regards,
Florian Pflug




В списке pgsql-hackers по дате отправления:

Предыдущее
От: Fabrízio de Royes Mello
Дата:
Сообщение: Re: Proposal : REINDEX SCHEMA
Следующее
От: Dag-Erling Smørgrav
Дата:
Сообщение: Re: [PATCH] add ssl_protocols configuration option