Re: [HACKERS] Bug? relpages, reltuples resets to zero
| От | jwieck@debis.com (Jan Wieck) | 
|---|---|
| Тема | Re: [HACKERS] Bug? relpages, reltuples resets to zero | 
| Дата | |
| Msg-id | m0zWj9h-000EBPC@orion.SAPserv.Hamburg.dsh.de обсуждение исходный текст | 
| Ответ на | Re: [HACKERS] Bug? relpages, reltuples resets to zero (jwieck@debis.com (Jan Wieck)) | 
| Ответы | Re: [HACKERS] Bug? relpages, reltuples resets to zero | 
| Список | pgsql-hackers | 
>     I think the simple way of modifying the  tuple  in  the  page
>     does not work. I found that catalog/index.c does the same for
>     relpages   and   reltuples    in    UpdateStats().    Calling
>     UpdateStats()  after vc_updstats() as a quick hack solved the
>     problem.
    And now I know the way of modifying them in the buffer is the
    only  one  to   succeed.   Doing   it   like   index.c   with
    heap_replace() irritates vacuum itself.
    Sometimes    it's    good    to    check   returncodes   :-).
    WriteNoReleaseBuffer() (as it's name  says)  takes  a  buffer
    number  as  argument,  not  a  disk  block  number.  Thus, it
    returned FALSE sometimes when called to write buffer # 0.
    The attdisbursion is also permanently saved on disk  now.  It
    had the same problem.
    Anyway, the fix is below.
    Patch is regression tested.
Jan
--
#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#======================================== jwieck@debis.com (Jan Wieck) #
*** vacuum.c.orig    Fri Oct 23 16:47:21 1998
--- vacuum.c    Fri Oct 23 16:41:56 1998
***************
*** 1792,1799 ****
--- 1792,1807 ----
              /* overwrite the existing statistics in the tuple */
              if (VacAttrStatsEqValid(stats))
              {
+                 Buffer        abuffer;
+                 /*
+                  * We manipulate the heap tuple in the
+                  * buffer, so we fetch it to get the
+                  * buffer number
+                  */
+                 atup = heap_fetch(ad, SnapshotNow, &atup->t_ctid, &abuffer);
                  vc_setpagelock(ad, ItemPointerGetBlockNumber(&atup->t_ctid));
+                 attp = (Form_pg_attribute) GETSTRUCT(atup);
                  if (stats->nonnull_cnt + stats->null_cnt == 0 ||
                      (stats->null_cnt <= 1 && stats->best_cnt == 1))
***************
*** 1822,1828 ****
                  if (selratio > 1.0)
                      selratio = 1.0;
                  attp->attdisbursion = selratio;
!                 WriteNoReleaseBuffer(ItemPointerGetBlockNumber(&atup->t_ctid));
                  /* DO PG_STATISTIC INSERTS */
--- 1830,1843 ----
                  if (selratio > 1.0)
                      selratio = 1.0;
                  attp->attdisbursion = selratio;
!
!                 /*
!                  * Invalidate the cache for the tuple
!                  * and write the buffer
!                  */
!                 RelationInvalidateHeapTuple(ad, atup);
!                 WriteNoReleaseBuffer(abuffer);
!                 ReleaseBuffer(abuffer);
                  /* DO PG_STATISTIC INSERTS */
***************
*** 1875,1884 ****
          heap_close(sd);
      }
      RelationInvalidateHeapTuple(rd, rtup);
!     /* XXX -- after write, should invalidate relcache in other backends */
!     WriteBuffer(ItemPointerGetBlockNumber(&rtup->t_ctid));
      heap_close(rd);
  }
--- 1890,1904 ----
          heap_close(sd);
      }
+     /*
+      * Invalidate the cached pg_class tuple and
+      * write the buffer
+      */
      RelationInvalidateHeapTuple(rd, rtup);
!     WriteNoReleaseBuffer(buffer);
!
!     ReleaseBuffer(buffer);
      heap_close(rd);
  }
		
	В списке pgsql-hackers по дате отправления: