Re: Visibility map and freezing

Поиск
Список
Период
Сортировка
Искать
От
Heikki Linnakangas
Тема
Re: Visibility map and freezing
Дата
Msg-id
496F67EA.5030901@enterprisedb.com
Ответ на
Список
Дерево обсуждения
Visibility map and freezing Heikki Linnakangas <heikki.linnakangas@enterprisedb.com>
Re: Visibility map and freezing Zdenek Kotala <Zdenek.Kotala@Sun.COM>
Re: Visibility map and freezing Heikki Linnakangas <heikki.linnakangas@enterprisedb.com>
Re: Visibility map and freezing Gregory Stark <greg.stark@enterprisedb.com>
Re: Visibility map and freezing Peter Eisentraut <peter_e@gmx.net>
Re: Visibility map and freezing Heikki Linnakangas <heikki.linnakangas@enterprisedb.com>
Re: Visibility map and freezing Heikki Linnakangas <heikki.linnakangas@enterprisedb.com>
Re: Visibility map and freezing Jeff Davis <pgsql@j-davis.com>
Re: Visibility map and freezing Heikki Linnakangas <heikki.linnakangas@enterprisedb.com>
Re: Visibility map and freezing Jeff Davis <pgsql@j-davis.com>
Re: Visibility map and freezing Heikki Linnakangas <heikki.linnakangas@enterprisedb.com>
Re: Visibility map and freezing Jeff Davis <pgsql@j-davis.com>
Re: Visibility map and freezing Heikki Linnakangas <heikki.linnakangas@enterprisedb.com>
Re: Visibility map and freezing Alvaro Herrera <alvherre@commandprompt.com>
Re: Visibility map and freezing Heikki Linnakangas <heikki.linnakangas@enterprisedb.com>
Re: Visibility map and freezing Gregory Stark <stark@enterprisedb.com>
Re: Visibility map and freezing ITAGAKI Takahiro <itagaki.takahiro@oss.ntt.co.jp>
Re: Visibility map and freezing Heikki Linnakangas <heikki.linnakangas@enterprisedb.com>
Re: Visibility map and freezing Simon Riggs <simon@2ndQuadrant.com>
Re: Visibility map and freezing Heikki Linnakangas <heikki.linnakangas@enterprisedb.com>
Re: Visibility map and freezing Simon Riggs <simon@2ndQuadrant.com>
Re: Visibility map and freezing Euler Taveira de Oliveira <euler@timbira.com>
Re: Visibility map and freezing Heikki Linnakangas <heikki.linnakangas@enterprisedb.com>
Re: Visibility map and freezing Heikki Linnakangas <heikki.linnakangas@enterprisedb.com>
Re: Visibility map and freezing "Fujii Masao" <masao.fujii@gmail.com>
Jeff Davis wrote:
> On Fri, 2009-01-09 at 13:49 +0200, Heikki Linnakangas wrote:
> If the distinction you're making is that autovacuum_freeze_max_age
> affects the launching of a vacuum rather than the behavior of a vacuum,
> maybe we could incorporate the word "launch" like:
> 
> autovacuum_launch_freeze_threshold

Hmm, I think I'd like it in the form autovacuum_freeze_launch_threshold 
more.

>> I'm now leaning towards:
>>
>> autovacuum_freeze_max_age
>> vacuum_freeze_table_age
>> vacuum_freeze_min_age
>>
>> where autovacuum_freeze_max_age and vacuum_freeze_min_age are unchanged, 
>> and vacuum_freeze_table_age is the new setting that controls when VACUUM 
>> or autovacuum should perform a full scan of the table to advance 
>> relfrozenxid.
> 
> I'm still bothered by the fact that "max" and "min" really mean the same
> thing here.

Yeah. Those are existing names, though, and I don't recall any 
complaints from users.

> I don't think we can perfectly capture the meaning of these GUCs in the
> name. I think our goal should be to avoid confusion between them.

Agreed.

Well, for better or worse here's a patch leaving the existing setting 
names alone, and the new GUC is called "vacuum_freeze_table_age". I'm 
not opposed to changing the names of the existing GUCs. If we do change 
them, the columns in pg_autovacuum need to be changed too.

There's documentation changes included to descríbe the new GUC, and the 
new behavior of VACUUM with visibility map in general. Is it readable, 
and is it enough?

Alvaro, are you getting rid of pg_autovacuum in favor of the reloptions 
for 8.4? This patch adds a new column to pg_autovacuum, reflecting the 
new vacuum_freeze_table_age GUC just like freeze_min_age column reflects 
vacuum_freeze_min_age. If I commit this tomorrow, will I cause you a lot 
of trouble with the reloptions patch?

-- 
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com
*** doc/src/sgml/catalogs.sgml
--- doc/src/sgml/catalogs.sgml
***************
*** 1361,1366 ****
--- 1361,1373 ----
        
        Custom autovacuum_freeze_max_age</> parameter
       
+ 
+      
+       freeze_table_age
+       integer
+       
+       Custom vacuum_freeze_table_age</> parameter
+      
      
     
    
*** doc/src/sgml/config.sgml
--- doc/src/sgml/config.sgml
***************
*** 3950,3955 **** COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
--- 3950,3975 ----
        
       
  
+      
+       vacuum_freeze_max_age (integer)
+       
+        vacuum_freeze_max_age</> configuration parameter
+       
+       
+        
+         VACUUM</> performs a whole-table scan if the table's
+         pg_class</>.relfrozenxid</> field reaches the
+         age specified by this setting.  The default is 150 million
+         transactions.  Although users can set this value anywhere from zero to
+         one billion, VACUUM</> will silently limit the effective value
+         to the value of  minus
+         1 million transactions, so that regular manual VACUUM</> has a
+         chance to run before autovacuum is launched to prevent XID wraparound.
+         For more information see .
+        
+       
+      
+ 
       
        vacuum_freeze_min_age (integer)
        
***************
*** 3960,3966 **** COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
          Specifies the cutoff age (in transactions) that VACUUM</>
          should use to decide whether to replace transaction IDs with
          FrozenXID</> while scanning a table.
!         The default is 100 million transactions.  Although
          users can set this value anywhere from zero to one billion,
          VACUUM</> will silently limit the effective value to half
          the value of , so
--- 3980,3986 ----
          Specifies the cutoff age (in transactions) that VACUUM</>
          should use to decide whether to replace transaction IDs with
          FrozenXID</> while scanning a table.
!         The default is 50 million transactions.  Although
          users can set this value anywhere from zero to one billion,
          VACUUM</> will silently limit the effective value to half
          the value of , so
***************
*** 3971,3976 **** COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
--- 3991,4017 ----
        
       
  
+      
+       vacuum_freeze_table_age (integer)
+       
+        vacuum_freeze_table_age</> configuration parameter
+       
+       
+        
+         Specifies the cutoff age (in transactions) that VACUUM</>
+         should use to decide whether to replace scan the whole table,
+         to freeze old tuples and advance pg_class</>.relfrozenxid</>.
+         The default is 150 million transactions.  Although
+         users can set this value anywhere from zero to two billion,
+         VACUUM</> will silently limit the effective value to 95%
+         of the value of , so
+         that a regularly run manual VACUUM</> has a chance to do
+         a whole table scan before an anti-wraparound autovacuum is launched.
+         For more information see .
+        
+       
+      
+ 
       
        xmlbinary (enum)
        
*** doc/src/sgml/maintenance.sgml
--- doc/src/sgml/maintenance.sgml
***************
*** 367,376 ****
     
  
     
!     VACUUM</>'s behavior is controlled by the configuration parameter
!     : any XID older than
!     vacuum_freeze_min_age</> transactions is replaced by
!     FrozenXID</>.  Larger values of vacuum_freeze_min_age</>
      preserve transactional information longer, while smaller values increase
      the number of transactions that can elapse before the table must be
      vacuumed again.
--- 367,380 ----
     
  
     
!     VACUUM</>'s behavior is controlled by the two configuration
!     parameters:  and
!     .
!     vacuum_freeze_table_age</> controls when VACUUM</>
!     performs a full sweep of the table, in order to replace old XID values 
!     with FrozenXID</>.  vacuum_freeze_min_age</> 
!     controls how old an XID value has to be before it's replaced with
!     FrozenXID</>.  Larger values of these settings
      preserve transactional information longer, while smaller values increase
      the number of transactions that can elapse before the table must be
      vacuumed again.
***************
*** 379,385 ****
     
      The maximum time that a table can go unvacuumed is two billion
      transactions minus the vacuum_freeze_min_age</> that was used
!     when it was last vacuumed.  If it were to go unvacuumed for longer than
      that, data loss could result.  To ensure that this does not happen,
      autovacuum is invoked on any table that might contain XIDs older than the
      age specified by the configuration parameter 
      The maximum time that a table can go unvacuumed is two billion
      transactions minus the vacuum_freeze_min_age</> that was used
!     when VACUUM</> last scanned the whole table.  If it were to go
!     unvacuumed for longer than
      that, data loss could result.  To ensure that this does not happen,
      autovacuum is invoked on any table that might contain XIDs older than the
      age specified by the configuration parameter 
  
     
!     The sole disadvantage of increasing autovacuum_freeze_max_age</>
      is that the pg_clog</> subdirectory of the database cluster
      will take more space, because it must store the commit status for all
      transactions back to the autovacuum_freeze_max_age</> horizon.
--- 408,415 ----
     
  
     
!     The sole disadvantage of increasing vacuum_freeze_table_age</>
!     and autovacuum_freeze_max_age</>
      is that the pg_clog</> subdirectory of the database cluster
      will take more space, because it must store the commit status for all
      transactions back to the autovacuum_freeze_max_age</> horizon.
***************
*** 411,418 ****
      autovacuum_freeze_max_age</> has its maximum allowed value of
      a little less than two billion, pg_clog</> can be expected to
      grow to about half a gigabyte.  If this is trivial compared to your
!     total database size, setting autovacuum_freeze_max_age</> to
!     its maximum allowed value is recommended.  Otherwise, set it depending
      on what you are willing to allow for pg_clog</> storage.
      (The default, 200 million transactions, translates to about 50MB of
      pg_clog</> storage.)
--- 417,425 ----
      autovacuum_freeze_max_age</> has its maximum allowed value of
      a little less than two billion, pg_clog</> can be expected to
      grow to about half a gigabyte.  If this is trivial compared to your
!     total database size, setting autovacuum_freeze_max_age</> and
!     vacuum_freeze_table_age to their maximum allowed values
!     is recommended.  Otherwise, set them depending
      on what you are willing to allow for pg_clog</> storage.
      (The default, 200 million transactions, translates to about 50MB of
      pg_clog</> storage.)
***************
*** 455,467 **** SELECT datname, age(datfrozenxid) FROM pg_database;
  
  
      The age</> column measures the number of transactions from the
!     cutoff XID to the current transaction's XID.  Immediately after a
!     VACUUM</>, age(relfrozenxid)</> should be a little
!     more than the vacuum_freeze_min_age</> setting that was used
!     (more by the number of transactions started since the VACUUM</>
!     started).  If age(relfrozenxid)</> exceeds
!     autovacuum_freeze_max_age</>, an autovacuum will soon be forced
!     for the table.
     
  
     
--- 462,485 ----
  
  
      The age</> column measures the number of transactions from the
!     cutoff XID to the current transaction's XID.  When VACUUM</>
!     scans the whole table, after it's finished age(relfrozenxid)</>
!     should be a little more than the vacuum_freeze_min_age</> setting
!     that was used (more by the number of transactions started since the
!     VACUUM</> started).
!    
! 
!    
!     VACUUM</> normally only scans pages that have been modified
!     since last vacuum, but relfrozenxid</> can only be advanced
!     when the whole table is scanned. The whole table is scanned when
!     relfrozenxid</> is more than
!     vacuum_freeze_table_age</> transactions old, if
!     VACUUM FREEZE</> command is used, or if all pages happen to
!     require vacuuming to remove dead row versions. If no whole-table-scanning
!     VACUUM</> is issued on the table until
!     autovacuum_freeze_max_age</> is reached, an autovacuum will soon
!     be forced for the table.
     
  
     
*** src/backend/commands/cluster.c
--- src/backend/commands/cluster.c
***************
*** 789,796 **** copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
  	 * freeze_min_age to avoid having CLUSTER freeze tuples earlier than a
  	 * plain VACUUM would.
  	 */
! 	vacuum_set_xid_limits(-1, OldHeap->rd_rel->relisshared,
! 						  &OldestXmin, &FreezeXid);
  
  	/*
  	 * FreezeXid will become the table's new relfrozenxid, and that mustn't
--- 789,796 ----
  	 * freeze_min_age to avoid having CLUSTER freeze tuples earlier than a
  	 * plain VACUUM would.
  	 */
! 	vacuum_set_xid_limits(-1, -1, OldHeap->rd_rel->relisshared,
! 						  &OldestXmin, &FreezeXid, NULL);
  
  	/*
  	 * FreezeXid will become the table's new relfrozenxid, and that mustn't
*** src/backend/commands/vacuum.c
--- src/backend/commands/vacuum.c
***************
*** 62,67 ****
--- 62,68 ----
   * GUC parameters
   */
  int			vacuum_freeze_min_age;
+ int			vacuum_freeze_table_age;
  
  /*
   * VacPage structures keep track of each page on which we find useful
***************
*** 590,598 **** get_rel_oids(Oid relid, const RangeVar *vacrel, const char *stmttype)
   * vacuum_set_xid_limits() -- compute oldest-Xmin and freeze cutoff points
   */
  void
! vacuum_set_xid_limits(int freeze_min_age, bool sharedRel,
  					  TransactionId *oldestXmin,
! 					  TransactionId *freezeLimit)
  {
  	int			freezemin;
  	TransactionId limit;
--- 591,602 ----
   * vacuum_set_xid_limits() -- compute oldest-Xmin and freeze cutoff points
   */
  void
! vacuum_set_xid_limits(int freeze_min_age,
! 					  int freeze_table_age,
! 					  bool sharedRel,
  					  TransactionId *oldestXmin,
! 					  TransactionId *freezeLimit,
! 					  TransactionId *freezeTableLimit)
  {
  	int			freezemin;
  	TransactionId limit;
***************
*** 648,653 **** vacuum_set_xid_limits(int freeze_min_age, bool sharedRel,
--- 652,685 ----
  	}
  
  	*freezeLimit = limit;
+ 
+ 	if (freezeTableLimit != NULL)
+ 	{
+ 		int freezetable;
+ 
+ 		/*
+ 		 * Determine the table freeze age to use: as specified by the caller,
+ 		 * or vacuum_freeze_table_age, but in any case not more than
+ 		 * autovacuum_freeze_max_age * 0.95, so that if you have e.g nightly
+ 		 * VACUUM schedule, the nightly VACUUM gets a chance to freeze tuples
+ 		 * before anti-wraparound autovacuum is launched.
+ 		 */
+ 		freezetable = freeze_min_age;
+ 		if (freezetable < 0)
+ 			freezetable = vacuum_freeze_table_age;
+ 		freezetable = Min(freezetable, autovacuum_freeze_max_age * 0.95);
+ 		Assert(freezetable >= 0);
+ 
+ 		/*
+ 		 * Compute the cutoff XID, being careful not to generate a
+ 		 * "permanent" XID.
+ 		 */
+ 		limit = ReadNewTransactionId() - freezetable;
+ 		if (!TransactionIdIsNormal(limit))
+ 			limit = FirstNormalTransactionId;
+ 
+ 		*freezeTableLimit = limit;
+ 	}
  }
  
  
***************
*** 1219,1226 **** full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
  				i;
  	VRelStats  *vacrelstats;
  
! 	vacuum_set_xid_limits(vacstmt->freeze_min_age, onerel->rd_rel->relisshared,
! 						  &OldestXmin, &FreezeLimit);
  
  	/*
  	 * Flush any previous async-commit transactions.  This does not guarantee
--- 1251,1259 ----
  				i;
  	VRelStats  *vacrelstats;
  
! 	vacuum_set_xid_limits(vacstmt->freeze_min_age, vacstmt->freeze_table_age,
! 						  onerel->rd_rel->relisshared,
! 						  &OldestXmin, &FreezeLimit, NULL);
  
  	/*
  	 * Flush any previous async-commit transactions.  This does not guarantee
*** src/backend/commands/vacuumlazy.c
--- src/backend/commands/vacuumlazy.c
***************
*** 144,149 **** lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
--- 144,151 ----
  	BlockNumber possibly_freeable;
  	PGRUsage	ru0;
  	TimestampTz starttime = 0;
+ 	bool		scan_all;
+ 	TransactionId freezeTableLimit;
  
  	pg_rusage_init(&ru0);
  
***************
*** 158,165 **** lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
  
  	vac_strategy = bstrategy;
  
! 	vacuum_set_xid_limits(vacstmt->freeze_min_age, onerel->rd_rel->relisshared,
! 						  &OldestXmin, &FreezeLimit);
  
  	vacrelstats = (LVRelStats *) palloc0(sizeof(LVRelStats));
  
--- 160,170 ----
  
  	vac_strategy = bstrategy;
  
! 	vacuum_set_xid_limits(vacstmt->freeze_min_age, vacstmt->freeze_table_age,
! 						  onerel->rd_rel->relisshared,
! 						  &OldestXmin, &FreezeLimit, &freezeTableLimit);
! 	scan_all = TransactionIdPrecedesOrEquals(onerel->rd_rel->relfrozenxid,
! 											 freezeTableLimit);
  
  	vacrelstats = (LVRelStats *) palloc0(sizeof(LVRelStats));
  
***************
*** 171,177 **** lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
  	vacrelstats->hasindex = (nindexes > 0);
   
  	/* Do the vacuuming */
! 	lazy_scan_heap(onerel, vacrelstats, Irel, nindexes, vacstmt->scan_all);
  
  	/* Done with indexes */
  	vac_close_indexes(nindexes, Irel, NoLock);
--- 176,182 ----
  	vacrelstats->hasindex = (nindexes > 0);
   
  	/* Do the vacuuming */
! 	lazy_scan_heap(onerel, vacrelstats, Irel, nindexes, scan_all);
  
  	/* Done with indexes */
  	vac_close_indexes(nindexes, Irel, NoLock);
*** src/backend/nodes/copyfuncs.c
--- src/backend/nodes/copyfuncs.c
***************
*** 2865,2871 **** _copyVacuumStmt(VacuumStmt *from)
  	COPY_SCALAR_FIELD(analyze);
  	COPY_SCALAR_FIELD(verbose);
  	COPY_SCALAR_FIELD(freeze_min_age);
! 	COPY_SCALAR_FIELD(scan_all);
  	COPY_NODE_FIELD(relation);
  	COPY_NODE_FIELD(va_cols);
  
--- 2865,2871 ----
  	COPY_SCALAR_FIELD(analyze);
  	COPY_SCALAR_FIELD(verbose);
  	COPY_SCALAR_FIELD(freeze_min_age);
! 	COPY_SCALAR_FIELD(freeze_table_age);
  	COPY_NODE_FIELD(relation);
  	COPY_NODE_FIELD(va_cols);
  
*** src/backend/nodes/equalfuncs.c
--- src/backend/nodes/equalfuncs.c
***************
*** 1454,1460 **** _equalVacuumStmt(VacuumStmt *a, VacuumStmt *b)
  	COMPARE_SCALAR_FIELD(analyze);
  	COMPARE_SCALAR_FIELD(verbose);
  	COMPARE_SCALAR_FIELD(freeze_min_age);
! 	COMPARE_SCALAR_FIELD(scan_all);
  	COMPARE_NODE_FIELD(relation);
  	COMPARE_NODE_FIELD(va_cols);
  
--- 1454,1460 ----
  	COMPARE_SCALAR_FIELD(analyze);
  	COMPARE_SCALAR_FIELD(verbose);
  	COMPARE_SCALAR_FIELD(freeze_min_age);
! 	COMPARE_SCALAR_FIELD(freeze_table_age);
  	COMPARE_NODE_FIELD(relation);
  	COMPARE_NODE_FIELD(va_cols);
  
*** src/backend/parser/gram.y
--- src/backend/parser/gram.y
***************
*** 6263,6269 **** VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
  					n->analyze = false;
  					n->full = $2;
  					n->freeze_min_age = $3 ? 0 : -1;
! 					n->scan_all = $2 || $3;
  					n->verbose = $4;
  					n->relation = NULL;
  					n->va_cols = NIL;
--- 6263,6269 ----
  					n->analyze = false;
  					n->full = $2;
  					n->freeze_min_age = $3 ? 0 : -1;
! 					n->freeze_table_age = $3 ? 0 : -1;
  					n->verbose = $4;
  					n->relation = NULL;
  					n->va_cols = NIL;
***************
*** 6276,6282 **** VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
  					n->analyze = false;
  					n->full = $2;
  					n->freeze_min_age = $3 ? 0 : -1;
! 					n->scan_all = $2 || $3;
  					n->verbose = $4;
  					n->relation = $5;
  					n->va_cols = NIL;
--- 6276,6282 ----
  					n->analyze = false;
  					n->full = $2;
  					n->freeze_min_age = $3 ? 0 : -1;
! 					n->freeze_table_age = $3 ? 0 : -1;
  					n->verbose = $4;
  					n->relation = $5;
  					n->va_cols = NIL;
***************
*** 6288,6294 **** VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
  					n->vacuum = true;
  					n->full = $2;
  					n->freeze_min_age = $3 ? 0 : -1;
! 					n->scan_all = $2 || $3;
  					n->verbose |= $4;
  					$$ = (Node *)n;
  				}
--- 6288,6294 ----
  					n->vacuum = true;
  					n->full = $2;
  					n->freeze_min_age = $3 ? 0 : -1;
! 					n->freeze_table_age = $3 ? 0 : -1;
  					n->verbose |= $4;
  					$$ = (Node *)n;
  				}
***************
*** 6302,6307 **** AnalyzeStmt:
--- 6302,6308 ----
  					n->analyze = true;
  					n->full = false;
  					n->freeze_min_age = -1;
+ 					n->freeze_table_age = -1;
  					n->verbose = $2;
  					n->relation = NULL;
  					n->va_cols = NIL;
***************
*** 6314,6319 **** AnalyzeStmt:
--- 6315,6321 ----
  					n->analyze = true;
  					n->full = false;
  					n->freeze_min_age = -1;
+ 					n->freeze_table_age = -1;
  					n->verbose = $2;
  					n->relation = $3;
  					n->va_cols = $4;
*** src/backend/postmaster/autovacuum.c
--- src/backend/postmaster/autovacuum.c
***************
*** 136,143 **** static volatile sig_atomic_t got_SIGTERM = false;
  /* Comparison point for determining whether freeze_max_age is exceeded */
  static TransactionId recentXid;
  
! /* Default freeze_min_age to use for autovacuum (varies by database) */
  static int	default_freeze_min_age;
  
  /* Memory context for long-lived data */
  static MemoryContext AutovacMemCxt;
--- 136,144 ----
  /* Comparison point for determining whether freeze_max_age is exceeded */
  static TransactionId recentXid;
  
! /* Default freeze ages to use for autovacuum (varies by database) */
  static int	default_freeze_min_age;
+ static int	default_freeze_table_age;
  
  /* Memory context for long-lived data */
  static MemoryContext AutovacMemCxt;
***************
*** 174,179 **** typedef struct autovac_table
--- 175,181 ----
  	bool		at_dovacuum;
  	bool		at_doanalyze;
  	int			at_freeze_min_age;
+ 	int			at_freeze_table_age;
  	int			at_vacuum_cost_delay;
  	int			at_vacuum_cost_limit;
  	bool		at_wraparound;
***************
*** 1857,1863 **** do_autovacuum(void)
  	pgstat_vacuum_stat();
  
  	/*
! 	 * Find the pg_database entry and select the default freeze_min_age. We
  	 * use zero in template and nonconnectable databases, else the system-wide
  	 * default.
  	 */
--- 1859,1865 ----
  	pgstat_vacuum_stat();
  
  	/*
! 	 * Find the pg_database entry and select the default freeze ages. We
  	 * use zero in template and nonconnectable databases, else the system-wide
  	 * default.
  	 */
***************
*** 1869,1877 **** do_autovacuum(void)
--- 1871,1885 ----
  	dbForm = (Form_pg_database) GETSTRUCT(tuple);
  
  	if (dbForm->datistemplate || !dbForm->datallowconn)
+ 	{
  		default_freeze_min_age = 0;
+ 		default_freeze_table_age = 0;
+ 	}
  	else
+ 	{
  		default_freeze_min_age = vacuum_freeze_min_age;
+ 		default_freeze_table_age = vacuum_freeze_table_age;
+ 	}
  
  	ReleaseSysCache(tuple);
  
***************
*** 2418,2423 **** table_recheck_autovac(Oid relid, HTAB *table_toast_map)
--- 2426,2432 ----
  	if (doanalyze || dovacuum)
  	{
  		int			freeze_min_age;
+ 		int			freeze_table_age;
  		int			vac_cost_limit;
  		int			vac_cost_delay;
  
***************
*** 2443,2448 **** table_recheck_autovac(Oid relid, HTAB *table_toast_map)
--- 2452,2460 ----
  
  			freeze_min_age = (avForm->freeze_min_age >= 0) ?
  				avForm->freeze_min_age : default_freeze_min_age;
+ 
+ 			freeze_table_age = (avForm->freeze_table_age >= 0) ?
+ 				avForm->freeze_table_age : default_freeze_table_age;
  		}
  		else
  		{
***************
*** 2453,2458 **** table_recheck_autovac(Oid relid, HTAB *table_toast_map)
--- 2465,2472 ----
  				autovacuum_vac_cost_delay : VacuumCostDelay;
  
  			freeze_min_age = default_freeze_min_age;
+ 
+ 			freeze_table_age = default_freeze_table_age;
  		}
  
  		tab = palloc(sizeof(autovac_table));
***************
*** 2460,2465 **** table_recheck_autovac(Oid relid, HTAB *table_toast_map)
--- 2474,2480 ----
  		tab->at_dovacuum = dovacuum;
  		tab->at_doanalyze = doanalyze;
  		tab->at_freeze_min_age = freeze_min_age;
+ 		tab->at_freeze_table_age = freeze_table_age;
  		tab->at_vacuum_cost_limit = vac_cost_limit;
  		tab->at_vacuum_cost_delay = vac_cost_delay;
  		tab->at_wraparound = wraparound;
***************
*** 2649,2655 **** autovacuum_do_vac_analyze(autovac_table *tab,
  	vacstmt.full = false;
  	vacstmt.analyze = tab->at_doanalyze;
  	vacstmt.freeze_min_age = tab->at_freeze_min_age;
! 	vacstmt.scan_all = tab->at_wraparound;
  	vacstmt.verbose = false;
  	vacstmt.relation = NULL;	/* not used since we pass a relid */
  	vacstmt.va_cols = NIL;
--- 2664,2670 ----
  	vacstmt.full = false;
  	vacstmt.analyze = tab->at_doanalyze;
  	vacstmt.freeze_min_age = tab->at_freeze_min_age;
! 	vacstmt.freeze_table_age = tab->at_freeze_table_age;
  	vacstmt.verbose = false;
  	vacstmt.relation = NULL;	/* not used since we pass a relid */
  	vacstmt.va_cols = NIL;
*** src/backend/utils/misc/guc.c
--- src/backend/utils/misc/guc.c
***************
*** 1544,1550 **** static struct config_int ConfigureNamesInt[] =
  			NULL
  		},
  		&vacuum_freeze_min_age,
! 		100000000, 0, 1000000000, NULL, NULL
  	},
  
  	{
--- 1544,1559 ----
  			NULL
  		},
  		&vacuum_freeze_min_age,
! 		50000000, 0, 1000000000, NULL, NULL
! 	},
! 
! 	{
! 		{"vacuum_freeze_table_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
! 			gettext_noop("Age at which VACUUM should scan whole table to freeze tuples."),
! 			NULL
! 		},
! 		&vacuum_freeze_table_age,
! 		150000000, 0, 2000000000, NULL, NULL
  	},
  
  	{
*** src/backend/utils/misc/postgresql.conf.sample
--- src/backend/utils/misc/postgresql.conf.sample
***************
*** 414,419 ****
--- 414,420 ----
  #session_replication_role = 'origin'
  #statement_timeout = 0			# 0 is disabled
  #vacuum_freeze_min_age = 100000000
+ #vacuum_freeze_table_age = 150000000
  #xmlbinary = 'base64'
  #xmloption = 'content'
  
*** src/include/catalog/catversion.h
--- src/include/catalog/catversion.h
***************
*** 53,58 ****
   */
  
  /*							yyyymmddN */
! #define CATALOG_VERSION_NO	200901051
  
  #endif
--- 53,58 ----
   */
  
  /*							yyyymmddN */
! #define CATALOG_VERSION_NO	200901141 /* XXX: update this before committing */
  
  #endif
*** src/include/catalog/pg_autovacuum.h
--- src/include/catalog/pg_autovacuum.h
***************
*** 34,39 **** CATALOG(pg_autovacuum,1248) BKI_WITHOUT_OIDS
--- 34,40 ----
  	int4		vac_cost_limit; /* vacuum cost limit */
  	int4		freeze_min_age; /* vacuum min freeze age */
  	int4		freeze_max_age; /* max age before forcing vacuum */
+ 	int4		freeze_table_age; /* age at which vacuum scans whole table */
  } FormData_pg_autovacuum;
  
  /* ----------------
***************
*** 58,63 **** typedef FormData_pg_autovacuum *Form_pg_autovacuum;
--- 59,65 ----
  #define Anum_pg_autovacuum_vac_cost_limit			8
  #define Anum_pg_autovacuum_freeze_min_age			9
  #define Anum_pg_autovacuum_freeze_max_age			10
+ #define Anum_pg_autovacuum_freeze_table_age			11
  
  /* There are no preloaded tuples in pg_autovacuum.h */
  
*** src/include/commands/vacuum.h
--- src/include/commands/vacuum.h
***************
*** 122,127 **** typedef struct VacAttrStats
--- 122,128 ----
  extern PGDLLIMPORT int default_statistics_target;		/* PGDLLIMPORT for
  														 * PostGIS */
  extern int	vacuum_freeze_min_age;
+ extern int	vacuum_freeze_table_age;
  
  
  /* in commands/vacuum.c */
***************
*** 135,143 **** extern void vac_update_relstats(Relation relation,
  					double num_tuples,
  					bool hasindex,
  					TransactionId frozenxid);
! extern void vacuum_set_xid_limits(int freeze_min_age, bool sharedRel,
  					  TransactionId *oldestXmin,
! 					  TransactionId *freezeLimit);
  extern void vac_update_datfrozenxid(void);
  extern bool vac_is_partial_index(Relation indrel);
  extern void vacuum_delay_point(void);
--- 136,146 ----
  					double num_tuples,
  					bool hasindex,
  					TransactionId frozenxid);
! extern void vacuum_set_xid_limits(int freeze_min_age, int freeze_table_age,
! 					  bool sharedRel,
  					  TransactionId *oldestXmin,
! 					  TransactionId *freezeLimit,
! 					  TransactionId *freezeTableLimit);
  extern void vac_update_datfrozenxid(void);
  extern bool vac_is_partial_index(Relation indrel);
  extern void vacuum_delay_point(void);
*** src/include/nodes/parsenodes.h
--- src/include/nodes/parsenodes.h
***************
*** 2155,2162 **** typedef struct VacuumStmt
  	bool		full;			/* do FULL (non-concurrent) vacuum */
  	bool		analyze;		/* do ANALYZE step */
  	bool		verbose;		/* print progress info */
- 	bool		scan_all;		/* force scan of all pages */
  	int			freeze_min_age; /* min freeze age, or -1 to use default */
  	RangeVar   *relation;		/* single table to process, or NULL */
  	List	   *va_cols;		/* list of column names, or NIL for all */
  } VacuumStmt;
--- 2155,2162 ----
  	bool		full;			/* do FULL (non-concurrent) vacuum */
  	bool		analyze;		/* do ANALYZE step */
  	bool		verbose;		/* print progress info */
  	int			freeze_min_age; /* min freeze age, or -1 to use default */
+ 	int			freeze_table_age; /* age at which to scan whole table */
  	RangeVar   *relation;		/* single table to process, or NULL */
  	List	   *va_cols;		/* list of column names, or NIL for all */
  } VacuumStmt;
В списке pgsql-hackers по дате отправления
От: Greg Sabino Mullane
Дата:
От: Magnus Hagander
Дата:
FAQ