diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index c1dd8168ca..d4ce99a9f5 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -75,6 +75,7 @@
 #include "catalog/dependency.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_database.h"
+#include "catalog/pg_inherits.h"
 #include "commands/dbcommands.h"
 #include "commands/vacuum.h"
 #include "lib/ilist.h"
@@ -2036,11 +2037,11 @@ do_autovacuum(void)
 	 * Scan pg_class to determine which tables to vacuum.
 	 *
 	 * We do this in two passes: on the first one we collect the list of plain
-	 * relations and materialized views, and on the second one we collect
-	 * TOAST tables. The reason for doing the second pass is that during it we
-	 * want to use the main relation's pg_class.reloptions entry if the TOAST
-	 * table does not have any, and we cannot obtain it unless we know
-	 * beforehand what's the main table OID.
+	 * relations, materialized views and partitioned tables, and on the second
+	 * one we collect TOAST tables. The reason for doing the second pass is that
+	 * during it we want to use the main relation's pg_class.reloptions entry
+	 * if the TOAST table does not have any, and we cannot obtain it unless we
+	 * know beforehand what's the main table OID.
 	 *
 	 * We need to check TOAST tables separately because in cases with short,
 	 * wide tables there might be proportionally much more activity in the
@@ -2063,7 +2064,12 @@ do_autovacuum(void)
 		bool		wraparound;
 
 		if (classForm->relkind != RELKIND_RELATION &&
-			classForm->relkind != RELKIND_MATVIEW)
+			classForm->relkind != RELKIND_MATVIEW &&
+			classForm->relkind != RELKIND_PARTITIONED_TABLE)
+			continue;
+
+		/* Collect partitioned tables, not partitions.  So skip them. */
+		if (classForm->relispartition)
 			continue;
 
 		relid = classForm->oid;
@@ -2092,19 +2098,76 @@ do_autovacuum(void)
 			continue;
 		}
 
-		/* 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);
+		if (classForm->relkind == RELKIND_RELATION ||
+			classForm->relkind == RELKIND_MATVIEW)
+		{
+			/* 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,
+									  effective_multixact_freeze_max_age,
+									  &dovacuum, &doanalyze, &wraparound);
+
+			/* Relations that need work are added to table_oids */
+			if (dovacuum || doanalyze)
+				table_oids = lappend_oid(table_oids, relid);
+		}
+		else
+		{
+			/*
+			 * If the relation is a partitioned table, we check if its children
+			 * need vacuum or analyze.  All children excluding foreign partitions
+			 * need to do that are added to the table_oids list.  At least one 
+			 * child is added the list, the partitioned table become an object
+			 * for autovacuum. 
+			 */
+			List     *tableOIDs;
+			ListCell *lc;
+			List     *child_oids = NIL;
 
-		/* Check if it needs vacuum or analyze */
-		relation_needs_vacanalyze(relid, relopts, classForm, tabentry,
-								  effective_multixact_freeze_max_age,
-								  &dovacuum, &doanalyze, &wraparound);
+			/* Find all members of inheritance set taking AccessShareLock */
+			tableOIDs = find_all_inheritors(relid, AccessShareLock, NULL);
 
-		/* Relations that need work are added to table_oids */
-		if (dovacuum || doanalyze)
-			table_oids = lappend_oid(table_oids, relid);
+			foreach(lc, tableOIDs)
+			{
+				Oid        childOID = lfirst_oid(lc);
+				HeapTuple  childtuple;
+				Form_pg_class childclassForm;
+
+				/* Ignore the parent table */
+				if (childOID == relid)
+					continue;
+
+				childtuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(childOID));
+				childclassForm = (Form_pg_class) GETSTRUCT(childtuple);
+
+				/* Skip foreign partitions */
+				if (childclassForm->relkind == RELKIND_FOREIGN_TABLE)
+					continue;
+
+				/* Fetch reloptions and the pgstat entry for this table */
+				relopts = extract_autovac_opts(childtuple, pg_class_desc);
+				tabentry = get_pgstat_tabentry_relid(childOID,
+													 childclassForm->relisshared,
+													 shared, dbentry);
+
+				relation_needs_vacanalyze(childOID, relopts, childclassForm, tabentry,
+										  effective_multixact_freeze_max_age,
+										  &dovacuum, &doanalyze, &wraparound);
+
+				if (dovacuum || doanalyze)
+					child_oids = lappend_oid(child_oids, childOID);
+			}
+
+			if (child_oids)
+			{
+				table_oids = lappend_oid(table_oids, relid);
+				table_oids = list_concat(table_oids, child_oids);
+			}
+		}
 
 		/*
 		 * Remember TOAST associations for the second pass.  Note: we must do
@@ -2725,6 +2788,7 @@ extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc)
 
 	Assert(((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_RELATION ||
 		   ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_MATVIEW ||
+		   ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_PARTITIONED_TABLE ||
 		   ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_TOASTVALUE);
 
 	relopts = extractRelOptions(tup, pg_class_desc, NULL);
@@ -2798,33 +2862,79 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
 		return NULL;
 	classForm = (Form_pg_class) GETSTRUCT(classTup);
 
-	/*
-	 * 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)
+	if (classForm->relkind != RELKIND_PARTITIONED_TABLE)
 	{
-		av_relation *hentry;
-		bool		found;
+		/*
+		 * 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)
+		{
+			av_relation *hentry;
+			bool		found;
+
+			hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found);
+			if (found && hentry->ar_hasrelopts)
+				avopts = &hentry->ar_reloptions;
+		}
+
+		/* fetch the pgstat table entry */
+		tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
+											 shared, dbentry);
+
+		relation_needs_vacanalyze(relid, avopts, classForm, tabentry,
+								  effective_multixact_freeze_max_age,
+								  &dovacuum, &doanalyze, &wraparound);
 
-		hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found);
-		if (found && hentry->ar_hasrelopts)
-			avopts = &hentry->ar_reloptions;
+		/* ignore ANALYZE for toast tables */
+		if (classForm->relkind == RELKIND_TOASTVALUE)
+			doanalyze = false;
 	}
+	else
+	{
+		/* 
+		 * If the relation is partitioned and doesn't have any foreign tables
+		 * we check its children again.
+		 */
+		List     *tableOIDs;
+		ListCell *lc;
+
+		/* Find all members of inheritance set taking AccessShareLock */
+		tableOIDs = find_all_inheritors(relid, AccessShareLock, NULL);
+
+		foreach(lc, tableOIDs)
+		{
+			Oid       childOID = lfirst_oid(lc);
+			HeapTuple childtuple;
+			Form_pg_class childclassForm;
+
+			/* Ignore the parent table */
+			if (childOID == relid)
+				continue;
+
+			childtuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(childOID));
+			childclassForm = (Form_pg_class) GETSTRUCT(childtuple);
+
+			/* Skip foreign partitions */
+			if (childclassForm->relkind == RELKIND_FOREIGN_TABLE)
+				continue;
 
-	/* fetch the pgstat table entry */
-	tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
-										 shared, dbentry);
+			/* Fetch reloptions and the pgstat entry */
+			avopts = extract_autovac_opts(childtuple, pg_class_desc);
+			tabentry = get_pgstat_tabentry_relid(childOID, childclassForm->relisshared,
+												 shared, dbentry);
 
-	relation_needs_vacanalyze(relid, avopts, classForm, tabentry,
-							  effective_multixact_freeze_max_age,
-							  &dovacuum, &doanalyze, &wraparound);
+			relation_needs_vacanalyze(childOID, avopts, childclassForm, tabentry,
+									  effective_multixact_freeze_max_age,
+									  &dovacuum, &doanalyze, &wraparound);
 
-	/* ignore ANALYZE for toast tables */
-	if (classForm->relkind == RELKIND_TOASTVALUE)
-		doanalyze = false;
+			/* Its parents need vacuum or analyze */
+			if (dovacuum || doanalyze)
+				break;
+		}
+	}
 
 	/* OK, it needs something done */
 	if (doanalyze || dovacuum)
