*** a/src/backend/access/common/reloptions.c
--- b/src/backend/access/common/reloptions.c
***************
*** 1170,1180 **** default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
  		{"autovacuum_freeze_table_age", RELOPT_TYPE_INT,
  		offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, freeze_table_age)},
  		{"autovacuum_multixact_freeze_min_age", RELOPT_TYPE_INT,
! 		offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, multixact_freeze_min_age)},
  		{"autovacuum_multixact_freeze_max_age", RELOPT_TYPE_INT,
! 		offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, multixact_freeze_max_age)},
  		{"autovacuum_multixact_freeze_table_age", RELOPT_TYPE_INT,
! 		offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, multixact_freeze_table_age)},
  		{"autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL,
  		offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, vacuum_scale_factor)},
  		{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,
--- 1170,1180 ----
  		{"autovacuum_freeze_table_age", RELOPT_TYPE_INT,
  		offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, freeze_table_age)},
  		{"autovacuum_multixact_freeze_min_age", RELOPT_TYPE_INT,
! 		offsetof(StdRdOptions, autovacuum2) +offsetof(AutoVacOpts2, multixact_freeze_min_age)},
  		{"autovacuum_multixact_freeze_max_age", RELOPT_TYPE_INT,
! 		offsetof(StdRdOptions, autovacuum2) +offsetof(AutoVacOpts2, multixact_freeze_max_age)},
  		{"autovacuum_multixact_freeze_table_age", RELOPT_TYPE_INT,
! 		offsetof(StdRdOptions, autovacuum2) +offsetof(AutoVacOpts2, multixact_freeze_table_age)},
  		{"autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL,
  		offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, vacuum_scale_factor)},
  		{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,
*** a/src/backend/postmaster/autovacuum.c
--- b/src/backend/postmaster/autovacuum.c
***************
*** 302,307 **** static void FreeWorkerInfo(int code, Datum arg);
--- 302,308 ----
  static autovac_table *table_recheck_autovac(Oid relid, HTAB *table_toast_map,
  					  TupleDesc pg_class_desc);
  static void relation_needs_vacanalyze(Oid relid, AutoVacOpts *relopts,
+ 						  AutoVacOpts2 *relopts2,
  						  Form_pg_class classForm,
  						  PgStat_StatTabEntry *tabentry,
  						  bool *dovacuum, bool *doanalyze, bool *wraparound);
***************
*** 309,315 **** static void relation_needs_vacanalyze(Oid relid, AutoVacOpts *relopts,
  static void autovacuum_do_vac_analyze(autovac_table *tab,
  						  BufferAccessStrategy bstrategy);
  static AutoVacOpts *extract_autovac_opts(HeapTuple tup,
! 					 TupleDesc pg_class_desc);
  static PgStat_StatTabEntry *get_pgstat_tabentry_relid(Oid relid, bool isshared,
  						  PgStat_StatDBEntry *shared,
  						  PgStat_StatDBEntry *dbentry);
--- 310,317 ----
  static void autovacuum_do_vac_analyze(autovac_table *tab,
  						  BufferAccessStrategy bstrategy);
  static AutoVacOpts *extract_autovac_opts(HeapTuple tup,
! 					 TupleDesc pg_class_desc,
! 					 AutoVacOpts2 **opts2);
  static PgStat_StatTabEntry *get_pgstat_tabentry_relid(Oid relid, bool isshared,
  						  PgStat_StatDBEntry *shared,
  						  PgStat_StatDBEntry *dbentry);
***************
*** 2020,2025 **** do_autovacuum(void)
--- 2022,2028 ----
  		Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple);
  		PgStat_StatTabEntry *tabentry;
  		AutoVacOpts *relopts;
+ 		AutoVacOpts2 *relopts2;
  		Oid			relid;
  		bool		dovacuum;
  		bool		doanalyze;
***************
*** 2032,2043 **** do_autovacuum(void)
  		relid = HeapTupleGetOid(tuple);
  
  		/* Fetch reloptions and the pgstat entry for this table */
! 		relopts = extract_autovac_opts(tuple, pg_class_desc);
  		tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
  											 shared, dbentry);
  
  		/* Check if it needs vacuum or analyze */
! 		relation_needs_vacanalyze(relid, relopts, classForm, tabentry,
  								  &dovacuum, &doanalyze, &wraparound);
  
  		/*
--- 2035,2046 ----
  		relid = HeapTupleGetOid(tuple);
  
  		/* Fetch reloptions and the pgstat entry for this table */
! 		relopts = extract_autovac_opts(tuple, pg_class_desc, &relopts2);
  		tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
  											 shared, dbentry);
  
  		/* Check if it needs vacuum or analyze */
! 		relation_needs_vacanalyze(relid, relopts, relopts2, classForm, tabentry,
  								  &dovacuum, &doanalyze, &wraparound);
  
  		/*
***************
*** 2134,2139 **** do_autovacuum(void)
--- 2137,2143 ----
  		PgStat_StatTabEntry *tabentry;
  		Oid			relid;
  		AutoVacOpts *relopts = NULL;
+ 		AutoVacOpts2 *relopts2 = NULL;
  		bool		dovacuum;
  		bool		doanalyze;
  		bool		wraparound;
***************
*** 2150,2156 **** do_autovacuum(void)
  		 * fetch reloptions -- if this toast table does not have them, try the
  		 * main rel
  		 */
! 		relopts = extract_autovac_opts(tuple, pg_class_desc);
  		if (relopts == NULL)
  		{
  			av_relation *hentry;
--- 2154,2160 ----
  		 * fetch reloptions -- if this toast table does not have them, try the
  		 * main rel
  		 */
! 		relopts = extract_autovac_opts(tuple, pg_class_desc, &relopts2);
  		if (relopts == NULL)
  		{
  			av_relation *hentry;
***************
*** 2165,2171 **** do_autovacuum(void)
  		tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
  											 shared, dbentry);
  
! 		relation_needs_vacanalyze(relid, relopts, classForm, tabentry,
  								  &dovacuum, &doanalyze, &wraparound);
  
  		/* ignore analyze for toast tables */
--- 2169,2175 ----
  		tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
  											 shared, dbentry);
  
! 		relation_needs_vacanalyze(relid, relopts, relopts2, classForm, tabentry,
  								  &dovacuum, &doanalyze, &wraparound);
  
  		/* ignore analyze for toast tables */
***************
*** 2406,2417 **** deleted:
   *
   * Given a relation's pg_class tuple, return the AutoVacOpts portion of
   * reloptions, if set; otherwise, return NULL.
   */
  static AutoVacOpts *
! extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc)
  {
  	bytea	   *relopts;
  	AutoVacOpts *av;
  
  	Assert(((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_RELATION ||
  		   ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_MATVIEW ||
--- 2410,2426 ----
   *
   * Given a relation's pg_class tuple, return the AutoVacOpts portion of
   * reloptions, if set; otherwise, return NULL.
+  *
+  * 9.3 kludge: return the separate "AutoVacOpts2" part too.
   */
  static AutoVacOpts *
! extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc, AutoVacOpts2 **opts2)
  {
  	bytea	   *relopts;
  	AutoVacOpts *av;
+ 	AutoVacOpts2 *av2;
+ 
+ 	*opts2 = NULL;
  
  	Assert(((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_RELATION ||
  		   ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_MATVIEW ||
***************
*** 2423,2428 **** extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc)
--- 2432,2442 ----
  
  	av = palloc(sizeof(AutoVacOpts));
  	memcpy(av, &(((StdRdOptions *) relopts)->autovacuum), sizeof(AutoVacOpts));
+ 
+ 	av2 = palloc(sizeof(AutoVacOpts2));
+ 	memcpy(av2, &(((StdRdOptions *) relopts)->autovacuum2), sizeof(AutoVacOpts2));
+ 	*opts2 = av2;
+ 
  	pfree(relopts);
  
  	return av;
***************
*** 2474,2479 **** table_recheck_autovac(Oid relid, HTAB *table_toast_map,
--- 2488,2494 ----
  	PgStat_StatDBEntry *dbentry;
  	bool		wraparound;
  	AutoVacOpts *avopts;
+ 	AutoVacOpts2 *avopts2;
  
  	/* use fresh stats */
  	autovac_refresh_stats();
***************
*** 2491,2497 **** table_recheck_autovac(Oid relid, HTAB *table_toast_map,
  	 * Get the applicable reloptions.  If it is a TOAST table, try to get the
  	 * main table reloptions if the toast table itself doesn't have.
  	 */
! 	avopts = extract_autovac_opts(classTup, pg_class_desc);
  	if (classForm->relkind == RELKIND_TOASTVALUE &&
  		avopts == NULL && table_toast_map != NULL)
  	{
--- 2506,2512 ----
  	 * Get the applicable reloptions.  If it is a TOAST table, try to get the
  	 * main table reloptions if the toast table itself doesn't have.
  	 */
! 	avopts = extract_autovac_opts(classTup, pg_class_desc, &avopts2);
  	if (classForm->relkind == RELKIND_TOASTVALUE &&
  		avopts == NULL && table_toast_map != NULL)
  	{
***************
*** 2507,2513 **** table_recheck_autovac(Oid relid, HTAB *table_toast_map,
  	tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
  										 shared, dbentry);
  
! 	relation_needs_vacanalyze(relid, avopts, classForm, tabentry,
  							  &dovacuum, &doanalyze, &wraparound);
  
  	/* ignore ANALYZE for toast tables */
--- 2522,2528 ----
  	tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
  										 shared, dbentry);
  
! 	relation_needs_vacanalyze(relid, avopts, avopts2, classForm, tabentry,
  							  &dovacuum, &doanalyze, &wraparound);
  
  	/* ignore ANALYZE for toast tables */
***************
*** 2554,2567 **** table_recheck_autovac(Oid relid, HTAB *table_toast_map,
  			? avopts->freeze_table_age
  			: default_freeze_table_age;
  
! 		multixact_freeze_min_age = (avopts &&
! 									avopts->multixact_freeze_min_age >= 0)
! 			? avopts->multixact_freeze_min_age
  			: default_multixact_freeze_min_age;
  
! 		multixact_freeze_table_age = (avopts &&
! 									  avopts->multixact_freeze_table_age >= 0)
! 			? avopts->multixact_freeze_table_age
  			: default_multixact_freeze_table_age;
  
  		tab = palloc(sizeof(autovac_table));
--- 2569,2582 ----
  			? avopts->freeze_table_age
  			: default_freeze_table_age;
  
! 		multixact_freeze_min_age = (avopts2 &&
! 									avopts2->multixact_freeze_min_age >= 0)
! 			? avopts2->multixact_freeze_min_age
  			: default_multixact_freeze_min_age;
  
! 		multixact_freeze_table_age = (avopts2 &&
! 									  avopts2->multixact_freeze_table_age >= 0)
! 			? avopts2->multixact_freeze_table_age
  			: default_multixact_freeze_table_age;
  
  		tab = palloc(sizeof(autovac_table));
***************
*** 2625,2630 **** table_recheck_autovac(Oid relid, HTAB *table_toast_map,
--- 2640,2646 ----
  static void
  relation_needs_vacanalyze(Oid relid,
  						  AutoVacOpts *relopts,
+ 						  AutoVacOpts2 *relopts2,
  						  Form_pg_class classForm,
  						  PgStat_StatTabEntry *tabentry,
   /* output params below */
***************
*** 2686,2693 **** relation_needs_vacanalyze(Oid relid,
  		? Min(relopts->freeze_max_age, autovacuum_freeze_max_age)
  		: autovacuum_freeze_max_age;
  
! 	multixact_freeze_max_age = (relopts && relopts->multixact_freeze_max_age >= 0)
! 		  ? Min(relopts->multixact_freeze_max_age, autovacuum_multixact_freeze_max_age)
  		  : autovacuum_multixact_freeze_max_age;
  
  	av_enabled = (relopts ? relopts->enabled : true);
--- 2702,2709 ----
  		? Min(relopts->freeze_max_age, autovacuum_freeze_max_age)
  		: autovacuum_freeze_max_age;
  
! 	multixact_freeze_max_age = (relopts2 && relopts2->multixact_freeze_max_age >= 0)
! 		  ? Min(relopts2->multixact_freeze_max_age, autovacuum_multixact_freeze_max_age)
  		  : autovacuum_multixact_freeze_max_age;
  
  	av_enabled = (relopts ? relopts->enabled : true);
*** a/src/include/nodes/parsenodes.h
--- b/src/include/nodes/parsenodes.h
***************
*** 2430,2441 **** typedef struct VacuumStmt
  	int			options;		/* OR of VacuumOption flags */
  	int			freeze_min_age; /* min freeze age, or -1 to use default */
  	int			freeze_table_age;		/* age at which to scan whole table */
  	int			multixact_freeze_min_age;		/* min multixact freeze age,
  												 * or -1 to use default */
  	int			multixact_freeze_table_age;		/* multixact 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;
  
  /* ----------------------
--- 2430,2442 ----
  	int			options;		/* OR of VacuumOption flags */
  	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 */
+ 	/* place these at the end, to avoid ABI break within 9.3 branch */
  	int			multixact_freeze_min_age;		/* min multixact freeze age,
  												 * or -1 to use default */
  	int			multixact_freeze_table_age;		/* multixact age at which to
  												 * scan whole table */
  } VacuumStmt;
  
  /* ----------------------
*** a/src/include/utils/rel.h
--- b/src/include/utils/rel.h
***************
*** 187,193 **** typedef struct RelationData
   * be applied to relations that use this format or a superset for
   * private options data.
   */
!  /* autovacuum-related reloptions. */
  typedef struct AutoVacOpts
  {
  	bool		enabled;
--- 187,197 ----
   * be applied to relations that use this format or a superset for
   * private options data.
   */
!  /*
!   * autovacuum-related reloptions.
!   *
!   * Split in two to avoid ABI break.
!   */
  typedef struct AutoVacOpts
  {
  	bool		enabled;
***************
*** 198,216 **** typedef struct AutoVacOpts
  	int			freeze_min_age;
  	int			freeze_max_age;
  	int			freeze_table_age;
- 	int			multixact_freeze_min_age;
- 	int			multixact_freeze_max_age;
- 	int			multixact_freeze_table_age;
  	float8		vacuum_scale_factor;
  	float8		analyze_scale_factor;
  } AutoVacOpts;
  
  typedef struct StdRdOptions
  {
  	int32		vl_len_;		/* varlena header (do not touch directly!) */
  	int			fillfactor;		/* page fill factor in percent (0..100) */
  	AutoVacOpts autovacuum;		/* autovacuum-related options */
  	bool		security_barrier;		/* for views */
  } StdRdOptions;
  
  #define HEAP_MIN_FILLFACTOR			10
--- 202,231 ----
  	int			freeze_min_age;
  	int			freeze_max_age;
  	int			freeze_table_age;
  	float8		vacuum_scale_factor;
  	float8		analyze_scale_factor;
  } AutoVacOpts;
  
+ /*
+  * The multixact freeze parameters were added after 9.3.2 had been released;
+  * to preserve ABI compatibility with modules that might have been compiled
+  * prior to 9.3.3, these are placed in a separate struct so that they can be
+  * located at the end of the containing struct.
+  */
+ typedef struct AutoVacOpts2
+ {
+ 	int		multixact_freeze_min_age;
+ 	int		multixact_freeze_max_age;
+ 	int		multixact_freeze_table_age;
+ } AutoVacOpts2;
+ 
  typedef struct StdRdOptions
  {
  	int32		vl_len_;		/* varlena header (do not touch directly!) */
  	int			fillfactor;		/* page fill factor in percent (0..100) */
  	AutoVacOpts autovacuum;		/* autovacuum-related options */
  	bool		security_barrier;		/* for views */
+ 	AutoVacOpts2 autovacuum2;	/* rest of autovacuum options */
  } StdRdOptions;
  
  #define HEAP_MIN_FILLFACTOR			10
