On 2015-04-16 10:25:29 -0700, Peter Geoghegan wrote: > On Thu, Apr 16, 2015 at 2:18 AM, Andres Freund <and...@anarazel.de> wrote: > > If we go that way that's the way I think it should be done: Whenever we > > encounter a speculative record we 'unlink' it from the changes that will > > be reused for spooling from disk and do nothing further. Then we just > > continue reading through the records. > > You mean we continue iterating through *changes* from ReorderBufferCommit()?
changes, records, not much of a difference here. > > If the next thing we encounter is > > a super-deletion we throw away that record. If it's another type of > > change (or even bettter a 'speculative insertion succeeded' record) > > insert it. > > By "insert it", I gather you mean report to the the logical decoding > plugin as an insert change. Yes. > We'd have coordination between records originally decoded into > changes, maybe "intercepting" them during xact reassembly, like my > first approach. We'd mostly do the same thing as the first approach, > actually. The major difference would be that there'd be explicit > "speculative affirmation" WAL records. But we wouldn't rely on those > affirmation records within ReorderBufferCommit() - we'd rely on the > *absence* of a super deletion WAL record (to report an insert change > to the decoding plugin). To emphasize, like my first approach, it > would be based on an *absence* of a super deletion WAL record. > However, like my second approach, there would be a "speculative > affirmation" WAL record. I think there should be one, but it's not required for the approach. The 'pending speculative insertion' can just be completed whenever there's a insert/update/delete that's not a super deletion. I.e. in the REORDER_BUFFER_CHANGE_INSERT/... case ReorderBufferCommit() just add something like: if (pending_insertion != NULL) { if (new_record_is_super_deletion) ReorderBufferReturnTupleBuf(pending_insertion); else rb->apply_change(rb, txn, relation, pending_insertion); } ... You'll have to be careful to store the pending_insertion *after* ReorderBufferToastReplace(), but that should not be a problem. > Right now, I'm tired, so bear with me. What I think I'm not quite > getting here is how the new type of "affirmation" record affects > visibility (or anything else, actually). Clearly dirty snapshots need > to see the record to set a speculative insertion token for their > caller to wait on (and HeapTupleSatisfiesVacuum() cannot see the > speculatively inserted tuple as reclaimable, of course). They need > this *before* the speculative insertion is affirmed, of course. > > Maybe you mean: If the speculative insertion xact is in progress, then > the tuple is visible to several types of snapshots (dirty, vacuum, > self, any). If it is not, then tuples are not visible because they are > only speculative (and not *confirmed*). If they were confirmed, and > the xact was committed, then those tuples are logically and physically > indistinguishable from tuples that were inserted in the ordinary > manner. > > Is that it? Basically, the affirmation records have nothing much to do > with logical decoding in particular. But you still need to super > delete, so that several types of snapshots ((dirty, vacuum, self, any) > *stop* seeing the tuple as visible independent of the inserting xact > being in progress. I have no idea what this has to do with the email you responded to? Maybe it's more meant as a response to my separate email that I want the HEAP_SPECULATIVE to be cleared? Greetings, Andres Freund -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers