Thread
-
Re: SSI predicate locking on heap -- tuple or row?
Kevin Grittner <kevin.grittner@wicourts.gov> — 2011-05-26T03:19:31Z
> Dan Ports wrote: > On Tue, May 24, 2011 at 04:18:37AM -0500, Kevin Grittner wrote: >> These proofs show that there is no legitimate cycle which could >> cause an anomaly which the move from row-based to tuple-based >> logic will miss. They don't prove that the change will generate >> all the same serialization failures; and in fact, some false >> positives are eliminated by the change. > > Yes, that's correct. That's related to the part in the proof where > I claimed T3 couldn't have a conflict out *to some transaction T0 > that precedes T1*. > > I originally tried to show that T3 couldn't have any conflicts out > that T2 didn't have, which would mean we got the same set of > serialization failures, but that's not true. In fact, it's not too > hard to come up with an example where there would be a > serialization failure with the row version links, but not without. > However, because the rw-conflict can't be pointing to a transaction > that precedes T1 in the serial order, it won't create a cycle. In > other words, there are serialization failures that won't happen > anymore, but they were false positives. Dan and I went around a couple times chasing down all code, comment, and patch changes needed, resulting in the attached patch. We found and fixed the bug which originally manifested in a way which I confused with a need for row locks, as well as another which was nearby in the code. We backed out the changes which were causing merge problems for Robert, as those were part of the attempt at the row locking (versus tuple locking). We removed a function which is no longer needed. We adjusted the comments and an affected isolation test. As might be expected from removing an unnecessary feature, the lines of code went down -- a net decrease of 93 lines. This patch applies against HEAD, `make check-world` passes as does `make -C src/test/isolation installcheck` and `make installcheck-world` against a database with default_transaction_isolation = 'serializable'. Dan is running stress testing against the patched version tonight with DBT-2. These changes generate merge conflicts with the work I've done on handling CLUSTER, DROP INDEX, etc. It seems to me that the best course would be to commit this, then I can rebase the other work and post it. Since these issues are orthogonal, it didn't seem like a good idea to combine them in one patch, and this one seems more urgent. -Kevin
-
Re: SSI predicate locking on heap -- tuple or row?
Heikki Linnakangas <heikki.linnakangas@enterprisedb.com> — 2011-05-26T08:06:49Z
On 26.05.2011 06:19, Kevin Grittner wrote: > Dan and I went around a couple times chasing down all code, comment, > and patch changes needed, resulting in the attached patch. We found > and fixed the bug which originally manifested in a way which I > confused with a need for row locks, as well as another which was > nearby in the code. We backed out the changes which were causing > merge problems for Robert, as those were part of the attempt at the > row locking (versus tuple locking). We removed a function which is > no longer needed. We adjusted the comments and an affected isolation > test. Could you explain in the README, why it is safe to only take the lock on the visible row version, please? It's not quite obvious, as we've seen from this discussion, and if I understood correctly the academic papers don't touch that subject either. > As might be expected from removing an unnecessary feature, the lines > of code went down -- a net decrease of 93 lines. That's the kind of patch I like :-). > These changes generate merge conflicts with the work I've done on > handling CLUSTER, DROP INDEX, etc. It seems to me that the best > course would be to commit this, then I can rebase the other work and > post it. Since these issues are orthogonal, it didn't seem like a > good idea to combine them in one patch, and this one seems more > urgent. Agreed. -- Heikki Linnakangas EnterpriseDB http://www.enterprisedb.com
-
Re: SSI predicate locking on heap -- tuple or row?
Kevin Grittner <kevin.grittner@wicourts.gov> — 2011-05-26T19:03:48Z
Heikki Linnakangas <heikki.linnakangas@enterprisedb.com> wrote: > Could you explain in the README, why it is safe to only take the > lock on the visible row version, please? Sure. I actually intended to do this last night but ran out of steam and posted what I had, planning on following up with that. The place it seemed to fit best was in the "Innovations" section, since the SSI papers and their prototype implementations seemed oriented toward "rows" -- certainly the SIREAD locks were at the row level, versus a row version level. Since this doesn't touch any of the files in yesterday's patch, and it seems entirely within the realm of possibility that people will want to argue about how best to document this more than the actual fix, I'm posting it as a separate patch -- README-SSI only. I mostly just copied from Dan's posted proof verbatim. -Kevin
-
Re: SSI predicate locking on heap -- tuple or row?
Heikki Linnakangas <heikki.linnakangas@enterprisedb.com> — 2011-05-30T09:36:04Z
On 26.05.2011 06:19, Kevin Grittner wrote: > /* > * Check whether the writer has become a pivot with an out-conflict > * committed transaction, while neither reader nor writer is committed. If > * the reader is a READ ONLY transaction, there is only a serialization > * failure if an out-conflict transaction causing the pivot committed > * before the reader acquired its snapshot. (That is, the reader must not > * have been concurrent with the out-conflict transaction.) > */ > if (!failure) > { > if (SxactHasSummaryConflictOut(writer)) > { > failure = true; > conflict = NULL; > } > else > conflict = (RWConflict) > SHMQueueNext(&writer->outConflicts, > &writer->outConflicts, > offsetof(RWConflictData, outLink)); > while (conflict) > { > if (SxactIsCommitted(conflict->sxactIn) > && (!SxactIsCommitted(reader) > || conflict->sxactIn->commitSeqNo <= reader->commitSeqNo) > && (!SxactIsCommitted(writer) > || conflict->sxactIn->commitSeqNo <= writer->commitSeqNo) > && (!SxactIsReadOnly(reader) > || conflict->sxactIn->commitSeqNo <= reader->SeqNo.lastCommitBeforeSnapshot)) > { > failure = true; > break; > } > conflict = (RWConflict) > SHMQueueNext(&writer->outConflicts, > &conflict->outLink, > offsetof(RWConflictData, outLink)); > } > } The comment is not in sync with the code. The code is not checking that "neither reader or writer has committed", but something more complicated. Looking at OnConflict_CheckForSerializationFailure(), it's really hard to see how it works, and why the conditions it checks are sufficient. I find it helps tremendously to draw the dangerous structures being checked, in addition to just explaining them in text. Ascii art is a bit clunky, but I think we have to do it here. I did some of that in the comments, and I think I understand it now. See attached patch. Does that look right to you? (note that I swapped the second and third check in the function, I think it's more straightforward that way). I also added a couple of questions about the conditions, marked with XXX comments. Can you answer those, please? PS. Should we say "Cancelled on identification as pivot, during ...", or "Cancelled on identification as a pivot, during ..." ? We seem to use both in the error messages. -- Heikki Linnakangas EnterpriseDB http://www.enterprisedb.com