RE: [HACKERS] Re:HEAP_MOVED_IN during vacuum - test case

Hiroshi Inoue <inoue@tpf.co.jp>

From: "Hiroshi Inoue" <Inoue@tpf.co.jp>
To: "Stephen Birch" <sbirch@ironmountainsystems.com>
Cc: "Tom Lane" <tgl@sss.pgh.pa.us>, "PostgreSQL-development" <pgsql-hackers@postgreSQL.org>, "The Hermit Hacker" <scrappy@hub.org>
Date: 2000-01-10T03:03:23Z
Lists: pgsql-hackers
> -----Original Message-----
> From: owner-pgsql-hackers@postgreSQL.org
> [mailto:owner-pgsql-hackers@postgreSQL.org]On Behalf Of Stephen Birch
>
> I have now created a test case that demonstrate the HEAP_MOVED_IN during
> vacuum problem.  Since the tar ball is 182k - I put it on an ftp site
> instead of mailing it.
>
> You can grab it from the following location:
>
>  http://www.ironmountainsystems.com/heap_moved_in/
>

The following patch seems to fix your case.
However I'm not sure it's a right solution.

Regards.

Hiroshi Inoue
Inoue@tpf.co.jp

Index: commands/vacuum.c
===================================================================
RCS file: /home/cvs/pgcurrent/backend/commands/vacuum.c,v
retrieving revision 1.18
diff -c -r1.18 vacuum.c
*** commands/vacuum.c	2000/01/05 03:05:35	1.18
--- commands/vacuum.c	2000/01/10 02:39:35
***************
*** 1049,1054 ****
--- 1049,1055 ----
  			   *idcur;
  	int			last_fraged_block,
  				last_vacuum_block,
+ 				last_movedin_block,
  				i = 0;
  	Size		tuple_len;
  	int			num_moved,
***************
*** 1084,1089 ****
--- 1085,1091 ----
  	vacuumed_pages = vacuum_pages->vpl_num_pages -
vacuum_pages->vpl_empty_end_pages;
  	last_vacuum_page = vacuum_pages->vpl_pagedesc[vacuumed_pages - 1];
  	last_vacuum_block = last_vacuum_page->vpd_blkno;
+ 	last_movedin_block = 0;
  	Assert(last_vacuum_block >= last_fraged_block);
  	cur_buffer = InvalidBuffer;
  	num_moved = 0;
***************
*** 1097,1102 ****
--- 1099,1107 ----
  		/* if it's reapped page and it was used by me - quit */
  		if (blkno == last_fraged_block && last_fraged_page->vpd_offsets_used >
0)
  			break;
+ 		/* couldn't shrink any more if this block has MOVED_INd tuples - quit */
+ 		if (blkno == last_movedin_block)
+ 			break;

  		buf = ReadBuffer(onerel, blkno);
  		page = BufferGetPage(buf);
***************
*** 1477,1482 ****
--- 1482,1489 ----
  					newtup.t_datamcxt = NULL;
  					newtup.t_data = (HeapTupleHeader) PageGetItem(ToPage, newitemid);
  					ItemPointerSet(&(newtup.t_self), vtmove[ti].vpd->vpd_blkno, newoff);
+ 					if (vtmove[i].vpd->vpd_blkno > last_movedin_block)
+ 						last_movedin_block = vtmove[i].vpd->vpd_blkno;

  					/*
  					 * Set t_ctid pointing to itself for last tuple in
***************
*** 1610,1615 ****
--- 1617,1624 ----
  			newtup.t_data = (HeapTupleHeader) PageGetItem(ToPage, newitemid);
  			ItemPointerSet(&(newtup.t_data->t_ctid), cur_page->vpd_blkno, newoff);
  			newtup.t_self = newtup.t_data->t_ctid;
+ 			if (cur_page->vpd_blkno > last_movedin_block)
+ 				last_movedin_block = cur_page->vpd_blkno;

  			/*
  			 * Mark old tuple as moved_off by vacuum and store vacuum XID