Re: Fix for regression caused by heap tuple header changes - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: Fix for regression caused by heap tuple header changes
Date
Msg-id 200207182036.g6IKauK14987@candle.pha.pa.us
Whole thread Raw
In response to Fix for regression caused by heap tuple header changes  (Manfred Koizar <mkoi-pg@aon.at>)
List pgsql-patches
Your patch has been added to the PostgreSQL unapplied patches list at:

    http://candle.pha.pa.us/cgi-bin/pgpatches

I will try to apply it within the next 48 hours.

---------------------------------------------------------------------------


Manfred Koizar wrote:
> This patch fixes a regression caused by my recent changes to heap
> tuple header.  The fix is based on the thought that HEAP_MOVED_IN is
> not needed any more as soon as HEAP_XMIN_COMMITTED has been set.  So
> in tqual.c and vacuum.c the HEAP_MOVED bits are cleared when
> HEAP_XMIN_COMMITTED is set.
>
> Vacuum robustness is enhanced by rearranging ifs, so that we have a
> chance to elog(ERROR, ...) before an assertion fails.
>
> A new regression test is included.
>
> Servus
>  Manfred

> diff -ruN ../base/src/backend/commands/vacuum.c src/backend/commands/vacuum.c
> --- ../base/src/backend/commands/vacuum.c    2002-07-15 20:39:19.000000000 +0200
> +++ src/backend/commands/vacuum.c    2002-07-16 13:41:59.000000000 +0200
> @@ -1534,8 +1534,6 @@
>
>              if (!(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED))
>              {
> -                if (HeapTupleHeaderGetXvac(tuple.t_data) != myXID)
> -                    elog(ERROR, "Invalid XVAC in tuple header");
>                  if (tuple.t_data->t_infomask & HEAP_MOVED_IN)
>                      elog(ERROR, "HEAP_MOVED_IN was not expected");
>
> @@ -1546,6 +1544,8 @@
>                   */
>                  if (tuple.t_data->t_infomask & HEAP_MOVED_OFF)
>                  {
> +                    if (HeapTupleHeaderGetXvac(tuple.t_data) != myXID)
> +                        elog(ERROR, "Invalid XVAC in tuple header");
>                      if (keep_tuples == 0)
>                          continue;
>                      if (chain_tuple_moved)        /* some chains was moved
> @@ -2009,7 +2009,7 @@
>
>              /*
>               * Mark new tuple as moved_in by vacuum and store vacuum XID
> -             * in t_cmin !!!
> +             * in t_cid !!!
>               */
>              newtup.t_data->t_infomask &=
>                  ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_OFF);
> @@ -2035,7 +2035,7 @@
>
>              /*
>               * Mark old tuple as moved_off by vacuum and store vacuum XID
> -             * in t_cmin !!!
> +             * in t_cid !!!
>               */
>              tuple.t_data->t_infomask &=
>                  ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN);
> @@ -2088,12 +2088,12 @@
>                  tuple.t_data = (HeapTupleHeader) PageGetItem(page, itemid);
>                  if (tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED)
>                      continue;
> -                if (HeapTupleHeaderGetXvac(tuple.t_data) != myXID)
> -                    elog(ERROR, "Invalid XVAC in tuple header (4)");
>                  if (tuple.t_data->t_infomask & HEAP_MOVED_IN)
>                      elog(ERROR, "HEAP_MOVED_IN was not expected (2)");
>                  if (tuple.t_data->t_infomask & HEAP_MOVED_OFF)
>                  {
> +                    if (HeapTupleHeaderGetXvac(tuple.t_data) != myXID)
> +                        elog(ERROR, "Invalid XVAC in tuple header (4)");
>                      /* some chains was moved while */
>                      if (chain_tuple_moved)
>                      {            /* cleaning this page */
> @@ -2117,6 +2117,8 @@
>                          keep_tuples--;
>                      }
>                  }
> +                else
> +                    elog(ERROR, "HEAP_MOVED_OFF was expected (2)");
>              }
>          }
>
> @@ -2226,17 +2228,18 @@
>              tuple.t_data = (HeapTupleHeader) PageGetItem(page, itemid);
>              if (!(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED))
>              {
> +                if (!(tuple.t_data->t_infomask & HEAP_MOVED))
> +                    elog(ERROR, "HEAP_MOVED_OFF/HEAP_MOVED_IN was expected");
>                  if (HeapTupleHeaderGetXvac(tuple.t_data) != myXID)
>                      elog(ERROR, "Invalid XVAC in tuple header (2)");
>                  if (tuple.t_data->t_infomask & HEAP_MOVED_IN)
>                  {
>                      tuple.t_data->t_infomask |= HEAP_XMIN_COMMITTED;
> +                    tuple.t_data->t_infomask &= ~HEAP_MOVED;
>                      num_tuples++;
>                  }
> -                else if (tuple.t_data->t_infomask & HEAP_MOVED_OFF)
> -                    tuple.t_data->t_infomask |= HEAP_XMIN_INVALID;
>                  else
> -                    elog(ERROR, "HEAP_MOVED_OFF/HEAP_MOVED_IN was expected");
> +                    tuple.t_data->t_infomask |= HEAP_XMIN_INVALID;
>              }
>          }
>          LockBuffer(buf, BUFFER_LOCK_UNLOCK);
> @@ -2305,15 +2308,15 @@
>
>                  if (!(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED))
>                  {
> -                    if (HeapTupleHeaderGetXvac(tuple.t_data) != myXID)
> -                        elog(ERROR, "Invalid XVAC in tuple header (3)");
>                      if (tuple.t_data->t_infomask & HEAP_MOVED_OFF)
>                      {
> +                        if (HeapTupleHeaderGetXvac(tuple.t_data) != myXID)
> +                            elog(ERROR, "Invalid XVAC in tuple header (3)");
>                          itemid->lp_flags &= ~LP_USED;
>                          num_tuples++;
>                      }
>                      else
> -                        elog(ERROR, "HEAP_MOVED_OFF was expected (2)");
> +                        elog(ERROR, "HEAP_MOVED_OFF was expected (3)");
>                  }
>
>              }
> diff -ruN ../base/src/backend/utils/time/tqual.c src/backend/utils/time/tqual.c
> --- ../base/src/backend/utils/time/tqual.c    2002-06-21 02:12:23.000000000 +0200
> +++ src/backend/utils/time/tqual.c    2002-07-16 13:19:59.000000000 +0200
> @@ -92,7 +92,10 @@
>                  if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
>                      return false;
>                  if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
> +                {
>                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
> +                    tuple->t_infomask &= ~HEAP_MOVED;
> +                }
>                  else
>                  {
>                      tuple->t_infomask |= HEAP_XMIN_INVALID;
> @@ -219,6 +222,7 @@
>                      return false;
>                  }
>                  tuple->t_infomask |= HEAP_XMIN_COMMITTED;
> +                tuple->t_infomask &= ~HEAP_MOVED;
>              }
>          }
>          else if (tuple->t_infomask & HEAP_MOVED_IN)
> @@ -228,7 +232,10 @@
>                  if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
>                      return false;
>                  if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
> +                {
>                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
> +                    tuple->t_infomask &= ~HEAP_MOVED;
> +                }
>                  else
>                  {
>                      tuple->t_infomask |= HEAP_XMIN_INVALID;
> @@ -336,6 +343,7 @@
>                      return false;
>                  }
>                  tuple->t_infomask |= HEAP_XMIN_COMMITTED;
> +                tuple->t_infomask &= ~HEAP_MOVED;
>              }
>          }
>          else if (tuple->t_infomask & HEAP_MOVED_IN)
> @@ -345,7 +353,10 @@
>                  if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
>                      return false;
>                  if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
> +                {
>                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
> +                    tuple->t_infomask &= ~HEAP_MOVED;
> +                }
>                  else
>                  {
>                      tuple->t_infomask |= HEAP_XMIN_INVALID;
> @@ -389,6 +400,7 @@
>                      return HeapTupleInvisible;
>                  }
>                  tuple->t_infomask |= HEAP_XMIN_COMMITTED;
> +                tuple->t_infomask &= ~HEAP_MOVED;
>              }
>          }
>          else if (tuple->t_infomask & HEAP_MOVED_IN)
> @@ -398,7 +410,10 @@
>                  if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
>                      return HeapTupleInvisible;
>                  if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
> +                {
>                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
> +                    tuple->t_infomask &= ~HEAP_MOVED;
> +                }
>                  else
>                  {
>                      tuple->t_infomask |= HEAP_XMIN_INVALID;
> @@ -520,6 +535,7 @@
>                      return false;
>                  }
>                  tuple->t_infomask |= HEAP_XMIN_COMMITTED;
> +                tuple->t_infomask &= ~HEAP_MOVED;
>              }
>          }
>          else if (tuple->t_infomask & HEAP_MOVED_IN)
> @@ -529,7 +545,10 @@
>                  if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
>                      return false;
>                  if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
> +                {
>                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
> +                    tuple->t_infomask &= ~HEAP_MOVED;
> +                }
>                  else
>                  {
>                      tuple->t_infomask |= HEAP_XMIN_INVALID;
> @@ -651,6 +670,7 @@
>                      return false;
>                  }
>                  tuple->t_infomask |= HEAP_XMIN_COMMITTED;
> +                tuple->t_infomask &= ~HEAP_MOVED;
>              }
>          }
>          else if (tuple->t_infomask & HEAP_MOVED_IN)
> @@ -660,7 +680,10 @@
>                  if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
>                      return false;
>                  if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
> +                {
>                      tuple->t_infomask |= HEAP_XMIN_COMMITTED;
> +                    tuple->t_infomask &= ~HEAP_MOVED;
> +                }
>                  else
>                  {
>                      tuple->t_infomask |= HEAP_XMIN_INVALID;
> @@ -809,6 +832,7 @@
>                  return HEAPTUPLE_DEAD;
>              }
>              tuple->t_infomask |= HEAP_XMIN_COMMITTED;
> +            tuple->t_infomask &= ~HEAP_MOVED;
>          }
>          else if (tuple->t_infomask & HEAP_MOVED_IN)
>          {
> @@ -817,7 +841,10 @@
>              if (TransactionIdIsInProgress(HeapTupleHeaderGetXvac(tuple)))
>                  return HEAPTUPLE_INSERT_IN_PROGRESS;
>              if (TransactionIdDidCommit(HeapTupleHeaderGetXvac(tuple)))
> +            {
>                  tuple->t_infomask |= HEAP_XMIN_COMMITTED;
> +                tuple->t_infomask &= ~HEAP_MOVED;
> +            }
>              else
>              {
>                  tuple->t_infomask |= HEAP_XMIN_INVALID;
> diff -ruN ../base/src/test/regress/expected/vacuum.out src/test/regress/expected/vacuum.out
> --- ../base/src/test/regress/expected/vacuum.out    2002-07-16 14:12:56.000000000 +0200
> +++ src/test/regress/expected/vacuum.out    2002-07-16 14:26:05.000000000 +0200
> @@ -0,0 +1,59 @@
> +--
> +-- VACUUM
> +--
> +CREATE TABLE vactst (i INT);
> +INSERT INTO vactst VALUES (1);
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst VALUES (0);
> +SELECT count(*) FROM vactst;
> + count
> +-------
> +  2049
> +(1 row)
> +
> +DELETE FROM vactst WHERE i != 0;
> +SELECT * FROM vactst;
> + i
> +---
> + 0
> +(1 row)
> +
> +VACUUM FULL vactst;
> +UPDATE vactst SET i = i + 1;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst VALUES (0);
> +SELECT count(*) FROM vactst;
> + count
> +-------
> +  2049
> +(1 row)
> +
> +DELETE FROM vactst WHERE i != 0;
> +VACUUM FULL vactst;
> +DELETE FROM vactst;
> +SELECT * FROM vactst;
> + i
> +---
> +(0 rows)
> +
> +DROP TABLE vactst;
> diff -ruN ../base/src/test/regress/parallel_schedule src/test/regress/parallel_schedule
> --- ../base/src/test/regress/parallel_schedule    2002-07-10 23:29:32.000000000 +0200
> +++ src/test/regress/parallel_schedule    2002-07-16 14:01:23.000000000 +0200
> @@ -38,7 +38,7 @@
>  # ----------
>  # The third group of parallel test
>  # ----------
> -test: constraints triggers create_misc create_aggregate create_operator create_index inherit
> +test: constraints triggers create_misc create_aggregate create_operator create_index inherit vacuum
>
>  # Depends on the above
>  test: create_view
> diff -ruN ../base/src/test/regress/serial_schedule src/test/regress/serial_schedule
> --- ../base/src/test/regress/serial_schedule    2002-07-10 23:31:16.000000000 +0200
> +++ src/test/regress/serial_schedule    2002-07-16 14:01:45.000000000 +0200
> @@ -50,6 +50,7 @@
>  test: create_operator
>  test: create_index
>  test: inherit
> +test: vacuum
>  test: create_view
>  test: sanity_check
>  test: errors
> diff -ruN ../base/src/test/regress/sql/vacuum.sql src/test/regress/sql/vacuum.sql
> --- ../base/src/test/regress/sql/vacuum.sql    2002-07-16 14:36:30.000000000 +0200
> +++ src/test/regress/sql/vacuum.sql    2002-07-16 14:22:43.000000000 +0200
> @@ -0,0 +1,42 @@
> +--
> +-- VACUUM
> +--
> +
> +CREATE TABLE vactst (i INT);
> +INSERT INTO vactst VALUES (1);
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst VALUES (0);
> +SELECT count(*) FROM vactst;
> +DELETE FROM vactst WHERE i != 0;
> +SELECT * FROM vactst;
> +VACUUM FULL vactst;
> +UPDATE vactst SET i = i + 1;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst SELECT * FROM vactst;
> +INSERT INTO vactst VALUES (0);
> +SELECT count(*) FROM vactst;
> +DELETE FROM vactst WHERE i != 0;
> +VACUUM FULL vactst;
> +DELETE FROM vactst;
> +SELECT * FROM vactst;
> +
> +DROP TABLE vactst;

>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: minor GEQO fixes
Next
From: Tom Lane
Date:
Subject: Re: Between Node