Re: [HACKERS] MARKED_FOR_UPDATE && XMAX_COMMITTED == XMAX_INVALID ? - Mailing list pgsql-patches

From Manfred Koizar
Subject Re: [HACKERS] MARKED_FOR_UPDATE && XMAX_COMMITTED == XMAX_INVALID ?
Date
Msg-id kl0hevs8mjt2mv12t45safbteqapuval1o@4ax.com
Whole thread Raw
Responses Re: [HACKERS] MARKED_FOR_UPDATE && XMAX_COMMITTED == XMAX_INVALID ?
Re: [HACKERS] MARKED_FOR_UPDATE && XMAX_COMMITTED == XMAX_INVALID ?
List pgsql-patches
On Wed, 11 Jun 2003 09:05:33 -0400, Tom Lane <tgl@sss.pgh.pa.us>
wrote:
>> If a transaction marks a tuple for update and later commits without
>> actually having updated the tuple, [...] can we simply
>> set the HEAP_XMAX_INVALID hint bit of the tuple?
>
>AFAICS this is a reasonable thing to do.

Thanks for the confirmation.  Here's a patch which also contains some
more noncritical changes to tqual.c:
 .  make code more readable by introducing local variables for xvac
 .  no longer two separate branches for aborted and crashed.
    The actions were the same in all cases.

Servus
 Manfred
diff -rcN ../base/src/backend/utils/time/tqual.c src/backend/utils/time/tqual.c
*** ../base/src/backend/utils/time/tqual.c    Thu May  8 21:45:55 2003
--- src/backend/utils/time/tqual.c    Thu Jun 12 12:10:31 2003
***************
*** 76,86 ****

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return false;
!             if (!TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
--- 76,87 ----

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
!             if (TransactionIdIsCurrentTransactionId(xvac))
                  return false;
!             if (!TransactionIdIsInProgress(xvac))
              {
!                 if (TransactionIdDidCommit(xvac))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
***************
*** 90,100 ****
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                      return false;
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
--- 91,102 ----
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
!             if (!TransactionIdIsCurrentTransactionId(xvac))
              {
!                 if (TransactionIdIsInProgress(xvac))
                      return false;
!                 if (TransactionIdDidCommit(xvac))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
***************
*** 152,162 ****
      }

      /* xmax transaction committed */
-     tuple->t_infomask |= HEAP_XMAX_COMMITTED;

      if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
          return true;

      return false;
  }

--- 154,167 ----
      }

      /* xmax transaction committed */

      if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
+     {
+         tuple->t_infomask |= HEAP_XMAX_INVALID;
          return true;
+     }

+     tuple->t_infomask |= HEAP_XMAX_COMMITTED;
      return false;
  }

***************
*** 212,222 ****

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return false;
!             if (!TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
--- 217,228 ----

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
!             if (TransactionIdIsCurrentTransactionId(xvac))
                  return false;
!             if (!TransactionIdIsInProgress(xvac))
              {
!                 if (TransactionIdDidCommit(xvac))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
***************
*** 226,236 ****
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                      return false;
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
--- 232,243 ----
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
!             if (!TransactionIdIsCurrentTransactionId(xvac))
              {
!                 if (TransactionIdIsInProgress(xvac))
                      return false;
!                 if (TransactionIdDidCommit(xvac))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
***************
*** 297,307 ****
      }

      /* xmax transaction committed */
-     tuple->t_infomask |= HEAP_XMAX_COMMITTED;

      if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
          return true;

      return false;
  }

--- 304,317 ----
      }

      /* xmax transaction committed */

      if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
+     {
+         tuple->t_infomask |= HEAP_XMAX_INVALID;
          return true;
+     }

+     tuple->t_infomask |= HEAP_XMAX_COMMITTED;
      return false;
  }

***************
*** 329,339 ****

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return false;
!             if (!TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
--- 339,350 ----

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
!             if (TransactionIdIsCurrentTransactionId(xvac))
                  return false;
!             if (!TransactionIdIsInProgress(xvac))
              {
!                 if (TransactionIdDidCommit(xvac))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
***************
*** 343,353 ****
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                      return false;
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
--- 354,365 ----
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
!             if (!TransactionIdIsCurrentTransactionId(xvac))
              {
!                 if (TransactionIdIsInProgress(xvac))
                      return false;
!                 if (TransactionIdDidCommit(xvac))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
***************
*** 382,392 ****

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return HeapTupleInvisible;
!             if (!TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return HeapTupleInvisible;
--- 394,405 ----

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
!             if (TransactionIdIsCurrentTransactionId(xvac))
                  return HeapTupleInvisible;
!             if (!TransactionIdIsInProgress(xvac))
              {
!                 if (TransactionIdDidCommit(xvac))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return HeapTupleInvisible;
***************
*** 396,406 ****
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                      return HeapTupleInvisible;
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
--- 409,420 ----
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
!             if (!TransactionIdIsCurrentTransactionId(xvac))
              {
!                 if (TransactionIdIsInProgress(xvac))
                      return HeapTupleInvisible;
!                 if (TransactionIdDidCommit(xvac))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
***************
*** 475,485 ****
      }

      /* xmax transaction committed */
-     tuple->t_infomask |= HEAP_XMAX_COMMITTED;

      if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
          return HeapTupleMayBeUpdated;

      return HeapTupleUpdated;    /* updated by other */
  }

--- 489,502 ----
      }

      /* xmax transaction committed */

      if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
+     {
+         tuple->t_infomask |= HEAP_XMAX_INVALID;
          return HeapTupleMayBeUpdated;
+     }

+     tuple->t_infomask |= HEAP_XMAX_COMMITTED;
      return HeapTupleUpdated;    /* updated by other */
  }

***************
*** 513,523 ****

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return false;
!             if (!TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
--- 530,541 ----

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
!             if (TransactionIdIsCurrentTransactionId(xvac))
                  return false;
!             if (!TransactionIdIsInProgress(xvac))
              {
!                 if (TransactionIdDidCommit(xvac))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
***************
*** 527,537 ****
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                      return false;
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
--- 545,556 ----
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
!             if (!TransactionIdIsCurrentTransactionId(xvac))
              {
!                 if (TransactionIdIsInProgress(xvac))
                      return false;
!                 if (TransactionIdDidCommit(xvac))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
***************
*** 600,610 ****
      }

      /* xmax transaction committed */
-     tuple->t_infomask |= HEAP_XMAX_COMMITTED;

      if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
          return true;

      SnapshotDirty->tid = tuple->t_ctid;
      return false;                /* updated by other */
  }
--- 619,632 ----
      }

      /* xmax transaction committed */

      if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
+     {
+         tuple->t_infomask |= HEAP_XMAX_INVALID;
          return true;
+     }

+     tuple->t_infomask |= HEAP_XMAX_COMMITTED;
      SnapshotDirty->tid = tuple->t_ctid;
      return false;                /* updated by other */
  }
***************
*** 644,654 ****

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return false;
!             if (!TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
--- 666,677 ----

          if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
!             if (TransactionIdIsCurrentTransactionId(xvac))
                  return false;
!             if (!TransactionIdIsInProgress(xvac))
              {
!                 if (TransactionIdDidCommit(xvac))
                  {
                      tuple->t_infomask |= HEAP_XMIN_INVALID;
                      return false;
***************
*** 658,668 ****
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
              {
!                 if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                      return false;
!                 if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
--- 681,692 ----
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
!             if (!TransactionIdIsCurrentTransactionId(xvac))
              {
!                 if (TransactionIdIsInProgress(xvac))
                      return false;
!                 if (TransactionIdDidCommit(xvac))
                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
                  else
                  {
***************
*** 802,812 ****
              return HEAPTUPLE_DEAD;
          else if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return HEAPTUPLE_DELETE_IN_PROGRESS;
!             if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                  return HEAPTUPLE_DELETE_IN_PROGRESS;
!             if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
              {
                  tuple->t_infomask |= HEAP_XMIN_INVALID;
                  return HEAPTUPLE_DEAD;
--- 826,837 ----
              return HEAPTUPLE_DEAD;
          else if (tuple->t_infomask & HEAP_MOVED_OFF)
          {
!             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
!             if (TransactionIdIsCurrentTransactionId(xvac))
                  return HEAPTUPLE_DELETE_IN_PROGRESS;
!             if (TransactionIdIsInProgress(xvac))
                  return HEAPTUPLE_DELETE_IN_PROGRESS;
!             if (TransactionIdDidCommit(xvac))
              {
                  tuple->t_infomask |= HEAP_XMIN_INVALID;
                  return HEAPTUPLE_DEAD;
***************
*** 815,825 ****
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXvac(tuple)))
                  return HEAPTUPLE_INSERT_IN_PROGRESS;
!             if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
                  return HEAPTUPLE_INSERT_IN_PROGRESS;
!             if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
                  tuple->t_infomask |= HEAP_XMIN_COMMITTED;
              else
              {
--- 840,851 ----
          }
          else if (tuple->t_infomask & HEAP_MOVED_IN)
          {
!             TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
!             if (TransactionIdIsCurrentTransactionId(xvac))
                  return HEAPTUPLE_INSERT_IN_PROGRESS;
!             if (TransactionIdIsInProgress(xvac))
                  return HEAPTUPLE_INSERT_IN_PROGRESS;
!             if (TransactionIdDidCommit(xvac))
                  tuple->t_infomask |= HEAP_XMIN_COMMITTED;
              else
              {
***************
*** 831,846 ****
              return HEAPTUPLE_INSERT_IN_PROGRESS;
          else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
              tuple->t_infomask |= HEAP_XMIN_COMMITTED;
-         else if (TransactionIdDidAbort(HeapTupleHeaderGetXmin(tuple)))
-         {
-             tuple->t_infomask |= HEAP_XMIN_INVALID;
-             return HEAPTUPLE_DEAD;
-         }
          else
          {
              /*
!              * Not in Progress, Not Committed, Not Aborted - so it's from
!              * crashed process. - vadim 11/26/96
               */
              tuple->t_infomask |= HEAP_XMIN_INVALID;
              return HEAPTUPLE_DEAD;
--- 857,866 ----
              return HEAPTUPLE_INSERT_IN_PROGRESS;
          else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
              tuple->t_infomask |= HEAP_XMIN_COMMITTED;
          else
          {
              /*
!              * Not in Progress, Not Committed, so either Aborted or crashed
               */
              tuple->t_infomask |= HEAP_XMIN_INVALID;
              return HEAPTUPLE_DEAD;
***************
*** 868,878 ****
          {
              if (TransactionIdIsInProgress(HeapTupleHeaderGetXmax(tuple)))
                  return HEAPTUPLE_LIVE;
!             if (TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
!                 tuple->t_infomask |= HEAP_XMAX_COMMITTED;
!             else
! /* it's either aborted or crashed */
!                 tuple->t_infomask |= HEAP_XMAX_INVALID;
          }
          return HEAPTUPLE_LIVE;
      }
--- 888,899 ----
          {
              if (TransactionIdIsInProgress(HeapTupleHeaderGetXmax(tuple)))
                  return HEAPTUPLE_LIVE;
!             /*
!              * We don't really care whether xmax did commit, abort or crash.
!              * We know that xmax did mark the tuple for update, but it did not
!              * and will never actually update it.
!              */
!             tuple->t_infomask |= HEAP_XMAX_INVALID;
          }
          return HEAPTUPLE_LIVE;
      }
***************
*** 883,898 ****
              return HEAPTUPLE_DELETE_IN_PROGRESS;
          else if (TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
              tuple->t_infomask |= HEAP_XMAX_COMMITTED;
-         else if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
-         {
-             tuple->t_infomask |= HEAP_XMAX_INVALID;
-             return HEAPTUPLE_LIVE;
-         }
          else
          {
              /*
!              * Not in Progress, Not Committed, Not Aborted - so it's from
!              * crashed process. - vadim 06/02/97
               */
              tuple->t_infomask |= HEAP_XMAX_INVALID;
              return HEAPTUPLE_LIVE;
--- 904,913 ----
              return HEAPTUPLE_DELETE_IN_PROGRESS;
          else if (TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
              tuple->t_infomask |= HEAP_XMAX_COMMITTED;
          else
          {
              /*
!              * Not in Progress, Not Committed, so either Aborted or crashed
               */
              tuple->t_infomask |= HEAP_XMAX_INVALID;
              return HEAPTUPLE_LIVE;

pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: pgstattuple for schemas
Next
From: Rod Taylor
Date:
Subject: Re: [HACKERS] CVS -Tip compile issue -- FreeBSD 4.8