@@ -792,59 +792,74 @@ XLogInsertRecord(XLogRecData *rdata,
792
792
*----------
793
793
*/
794
794
START_CRIT_SECTION ();
795
- if (isLogSwitch )
796
- WALInsertLockAcquireExclusive ();
797
- else
798
- WALInsertLockAcquire ();
799
795
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 ))
817
797
{
818
- Assert (RedoRecPtr < Insert -> RedoRecPtr );
819
- RedoRecPtr = Insert -> RedoRecPtr ;
820
- }
821
- doPageWrites = (Insert -> fullPageWrites || Insert -> runningBackups > 0 );
798
+ WALInsertLockAcquire ();
822
799
823
- if (doPageWrites &&
824
- (!prevDoPageWrites ||
825
- (fpw_lsn != InvalidXLogRecPtr && fpw_lsn <= RedoRecPtr )))
826
- {
827
800
/*
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.)
830
815
*/
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 );
835
822
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
+ */
844
840
ReserveXLogInsertLocation (rechdr -> xl_tot_len , & StartPos , & EndPos ,
845
841
& rechdr -> xl_prev );
842
+
843
+ /* Normal records are always inserted. */
846
844
inserted = true;
847
845
}
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
+ }
848
863
849
864
if (inserted )
850
865
{
0 commit comments