Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit df9a3d4

Browse files
committed
Unify two isLogSwitch tests in XLogInsertRecord.
An upcoming patch wants to introduce an additional special case in this function. To keep that as cheap as possible, minimize the amount of branching that we do based on whether this is an XLOG_SWITCH record. Additionally, and also in the interest of keeping the overhead of special-case code paths as low as possible, apply likely() to the non-XLOG_SWITCH case, since only a very tiny fraction of WAL records will be XLOG_SWITCH records. Patch by me, reviewed by Dilip Kumar, Amit Kapila, Andres Freund, and Michael Paquier. Discussion: http://postgr.es/m/CA+TgmoYy-Vc6G9QKcAKNksCa29cv__czr+N9X_QCxEfQVpp_8w@mail.gmail.com
1 parent d9e46df commit df9a3d4

File tree

1 file changed

+58
-43
lines changed
  • src/backend/access/transam

1 file changed

+58
-43
lines changed

src/backend/access/transam/xlog.c

Lines changed: 58 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -792,59 +792,74 @@ XLogInsertRecord(XLogRecData *rdata,
792792
*----------
793793
*/
794794
START_CRIT_SECTION();
795-
if (isLogSwitch)
796-
WALInsertLockAcquireExclusive();
797-
else
798-
WALInsertLockAcquire();
799795

800-
/*
801-
* Check to see if my copy of RedoRecPtr is out of date. If so, may have
802-
* to go back and have the caller recompute everything. This can only
803-
* happen just after a checkpoint, so it's better to be slow in this case
804-
* and fast otherwise.
805-
*
806-
* Also check to see if fullPageWrites was just turned on or there's a
807-
* running backup (which forces full-page writes); if we weren't already
808-
* doing full-page writes then go back and recompute.
809-
*
810-
* If we aren't doing full-page writes then RedoRecPtr doesn't actually
811-
* affect the contents of the XLOG record, so we'll update our local copy
812-
* but not force a recomputation. (If doPageWrites was just turned off,
813-
* we could recompute the record without full pages, but we choose not to
814-
* bother.)
815-
*/
816-
if (RedoRecPtr != Insert->RedoRecPtr)
796+
if (likely(!isLogSwitch))
817797
{
818-
Assert(RedoRecPtr < Insert->RedoRecPtr);
819-
RedoRecPtr = Insert->RedoRecPtr;
820-
}
821-
doPageWrites = (Insert->fullPageWrites || Insert->runningBackups > 0);
798+
WALInsertLockAcquire();
822799

823-
if (doPageWrites &&
824-
(!prevDoPageWrites ||
825-
(fpw_lsn != InvalidXLogRecPtr && fpw_lsn <= RedoRecPtr)))
826-
{
827800
/*
828-
* Oops, some buffer now needs to be backed up that the caller didn't
829-
* back up. Start over.
801+
* Check to see if my copy of RedoRecPtr is out of date. If so, may
802+
* have to go back and have the caller recompute everything. This can
803+
* only happen just after a checkpoint, so it's better to be slow in
804+
* this case and fast otherwise.
805+
*
806+
* Also check to see if fullPageWrites was just turned on or there's a
807+
* running backup (which forces full-page writes); if we weren't
808+
* already doing full-page writes then go back and recompute.
809+
*
810+
* If we aren't doing full-page writes then RedoRecPtr doesn't
811+
* actually affect the contents of the XLOG record, so we'll update
812+
* our local copy but not force a recomputation. (If doPageWrites was
813+
* just turned off, we could recompute the record without full pages,
814+
* but we choose not to bother.)
830815
*/
831-
WALInsertLockRelease();
832-
END_CRIT_SECTION();
833-
return InvalidXLogRecPtr;
834-
}
816+
if (RedoRecPtr != Insert->RedoRecPtr)
817+
{
818+
Assert(RedoRecPtr < Insert->RedoRecPtr);
819+
RedoRecPtr = Insert->RedoRecPtr;
820+
}
821+
doPageWrites = (Insert->fullPageWrites || Insert->runningBackups > 0);
835822

836-
/*
837-
* Reserve space for the record in the WAL. This also sets the xl_prev
838-
* pointer.
839-
*/
840-
if (isLogSwitch)
841-
inserted = ReserveXLogSwitch(&StartPos, &EndPos, &rechdr->xl_prev);
842-
else
843-
{
823+
if (doPageWrites &&
824+
(!prevDoPageWrites ||
825+
(fpw_lsn != InvalidXLogRecPtr && fpw_lsn <= RedoRecPtr)))
826+
{
827+
/*
828+
* Oops, some buffer now needs to be backed up that the caller
829+
* didn't back up. Start over.
830+
*/
831+
WALInsertLockRelease();
832+
END_CRIT_SECTION();
833+
return InvalidXLogRecPtr;
834+
}
835+
836+
/*
837+
* Reserve space for the record in the WAL. This also sets the xl_prev
838+
* pointer.
839+
*/
844840
ReserveXLogInsertLocation(rechdr->xl_tot_len, &StartPos, &EndPos,
845841
&rechdr->xl_prev);
842+
843+
/* Normal records are always inserted. */
846844
inserted = true;
847845
}
846+
else
847+
{
848+
/*
849+
* In order to insert an XLOG_SWITCH record, we need to hold all of
850+
* the WAL insertion locks, not just one, so that no one else can
851+
* begin inserting a record until we've figured out how much space
852+
* remains in the current WAL segment and claimed all of it.
853+
*
854+
* Nonetheless, this case is simpler than the normal cases handled
855+
* above, which must check for changes in doPageWrites and RedoRecPtr.
856+
* Those checks are only needed for records that can contain
857+
* full-pages images, and an XLOG_SWITCH record never does.
858+
*/
859+
Assert(fpw_lsn == InvalidXLogRecPtr);
860+
WALInsertLockAcquireExclusive();
861+
inserted = ReserveXLogSwitch(&StartPos, &EndPos, &rechdr->xl_prev);
862+
}
848863

849864
if (inserted)
850865
{

0 commit comments

Comments
 (0)