Re: Undo logs

From: Dilip Kumar <dilipbalaut(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: Dilip Kumar <dilip(dot)kumar(at)enterprisedb(dot)com>, Thomas Munro <thomas(dot)munro(at)enterprisedb(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Undo logs
Date: 2018-12-23 10:18:52
Message-ID: CAFiTN-tfquvm6tnWFaJNYYz-vSY=+SQTMv+Fv1jPozTrW4mtKw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Wed, Dec 12, 2018 at 3:03 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> On Wed, Dec 12, 2018 at 11:18 AM Dilip Kumar
> <dilip(dot)kumar(at)enterprisedb(dot)com> wrote:
> >
> > On Sat, Dec 8, 2018 at 7:52 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> >>
> >>
> >> I think I see the problem in the discard mechanism when the log is
> >> spread across multiple logs. Basically, if the second log contains
> >> undo of some transaction prior to the transaction which has just
> >> decided to spread it's undo in the chosen undo log, then we might
> >> discard the undo log of some transaction(s) inadvertently. Am, I
> >> missing something?
> >
> > Actually, I don't see exactly this problem here because we only process one undo log at a time, so we will not got to the next undo log and discard some transaction for which we supposed to retain the undo.
> >
>
> How will rollbacks work for such a case? I have more to say about
> this, see below.
Yeah, I agree rollback will have the problem.

>
> >>
> >> If not, then I guess we need to ensure that we
> >> don't immediately discard the undo in the second log when a single
> >> transactions undo is spreaded across two logs
> >>
> >> Before choosing a new undo log to span the undo for a transaction, do
> >> we ensure that it is not already linked with some other undo log for a
> >> similar reason?
> >>
>
> You seem to forget answering this.
In current patch I have removed the concept of prevlogno in undo log meta.
>
> >> One more thing in this regard:
> >> +UndoRecordAllocate(UnpackedUndoRecord *undorecords, int nrecords,
> >> + TransactionId txid, UndoPersistence upersistence)
> ..
> >>
> >> Isn't there a hidden assumption in the above code that you will always
> >> get a fresh undo log if the undo doesn't fit in the currently attached
> >> log? What is the guarantee of same?
> >
> >
> > Yeah it's a problem, we might get the undo which may not be empty. One way to avoid this could be that instead of relying on the check "UndoRecPtrGetOffset(urecptr) == UndoLogBlockHeaderSize". We can add some flag to the undo log meta data that whether it's the first record after attach or not and based on that we can decide. But, I want to think some better solution where we can identify without adding anything extra to undo meta.
> >
>
> I think what we need to determine here is whether we have switched the
> log for some non-first record of the transaction. If so, can't we
> detect by something like:
>
> log = GetLatestUndoLogAmAttachedTo();
> UndoLogAllocate();
> if (!need_xact_hdr)
> {
> currnet_log = GetLatestUndoLogAmAttachedTo();
> if (currnet_log is not same as log)
> {
> Assert(currnet_log->meta.prevlogno == log->logno);
> log_switched = true;
> }
> }
>
>
> Won't the similar problem happens when we read undo records during
> rollback? In code below:
>
> +UndoRecPtr
> +UndoGetPrevUndoRecptr(UndoRecPtr urp, uint16 prevlen)
> +{
> + UndoLogNumber logno = UndoRecPtrGetLogNo(urp);
> + UndoLogOffset offset = UndoRecPtrGetOffset(urp);
> +
> + /*
> + * We have reached to the first undo record of this undo log, so fetch the
> + * previous undo record of the transaction from the previous log.
> + */
> + if (offset == UndoLogBlockHeaderSize)
> + {
> + UndoLogControl *prevlog,
>
> We seem to be assuming here that the new log starts from the
> beginning. IIUC, we can read the record of some other transaction if
> the transaction's log spans across two logs and the second log
> contains some other transaction's log in the beginning.

For addressing these issues related to multilog I have changed the
design as we discussed offlist.
1) Now, at Do time we identify the log switch as you mentioned above
(identify which log we are attached to before and after allocate).
And, if the log is switched we write a WAL for the same and during
recovery whenever this WAL is replayed we stored the undo record
pointer of the transaction header (which is in the previous undo log)
in UndoLogStateData and read it while allocating space the undo record
and immediately reset it.

2) For handling the discard issue, along with updating the current
transaction's start header in the previous undo log we also update the
previous transaction's start header in the current log if we get
assigned with the non-empty undo log.

3) For, identifying the previous undo record of the transaction during
rollback (when undo log is switched), we store the transaction's last
record's (in previous undo log) undo record pointer in the transaction
header of the first undo record in the new undo log.

>
> >>
> >> 8.
> >> +typedef struct UndoRecordTransaction
> >> +{
> >> + uint32 urec_progress; /* undo applying progress. */
> >> + uint32 urec_xidepoch; /* epoch of the current transaction */
> >>
> >> Can you expand comments about how the progress is defined and used?
> >
> > Moved your comment from UnpackedUndoRecord to this structure and in UnpackedUndoRecord I have mentioned that we can refer detailed comment in this structure.
> >
> >>
> >> Also, write a few sentences about why epoch is captured and or used?
> >
> > urec_xidepoch is captured mainly for the zheap visibility purpose so isn't it good that we mention it there?
> >
>
> Okay, you can leave it here as it is. One small point about this structure:
>
> + uint64 urec_next; /* urec pointer of the next transaction */
> +} UndoRecordTransaction;
> +
> +#define SizeOfUrecNext (sizeof(UndoRecPtr))
> +#define SizeOfUndoRecordTransaction \
> + (offsetof(UndoRecordTransaction, urec_next) + SizeOfUrecNext)
>
> Isn't it better to define urec_next as UndoRecPtr, even though it is
> technically the same as per the current code?

While replying I noticed that I haven't address this comment, I will
handle this in next patch. I have to change this at couple of place.

Handling multilog, needed some changes in undo-log-manager patch so
attaching the updated version of the undo-log patches as well.

Commit on which patches created (bf491a9073e12ce1fc3e6facd0ae1308534df570)

--
Regards,
Dilip Kumar
EnterpriseDB: http://www.enterprisedb.com

Attachment Content-Type Size
0001-Add-undo-log-manager_v4.patch application/octet-stream 116.5 KB
0002-Provide-access-to-undo-log-data-via-the-buffer-manag_v4.patch application/octet-stream 40.3 KB
0003-undo-interface-v12.patch application/octet-stream 68.4 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Magnus Hagander 2018-12-23 11:50:29 Re: CF app feature request
Previous Message Michael Paquier 2018-12-23 08:04:53 Re: pgsql: Update ssl test certificates and keys