diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml
index 1c4fc40489..46f3848038 100644
--- a/doc/src/sgml/maintenance.sgml
+++ b/doc/src/sgml/maintenance.sgml
@@ -705,6 +705,35 @@ HINT:  Stop the postmaster and vacuum that database in single-user mode.
      nominally disabled.
     </para>
    </sect3>
+
+   <sect3 id="temporary-tables-and-wraparound">
+    <title>Temporary Tables and Wraparound</title>
+
+    <para>
+     In long sessions, having multiple temporary tables that are not properly
+     cleaned up can cause wraparound.  To avoid this issue, you can manually
+     remove temporary tables that are no longer required.
+    </para>
+    <para>
+     If the wraparound has already occurred and the server has stopped accepting
+     commands, you can do the following:
+     <orderedlist>
+      <listitem>
+       <para>
+        Stop the server and launch it in the
+        <link linkend="app-postgres-single-user">single-user mode</link>.
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+        Run the <command>VACUUM</command> command to remove orphaned temporary
+        tables.
+       </para>
+      </listitem>
+     </orderedlist>
+     Once this operation completes, you can restart the server as usual.
+    </para>
+   </sect3>
   </sect2>
 
   <sect2 id="autovacuum">
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index e91df2171e..e4eac7eccd 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -30,11 +30,13 @@
 #include "access/multixact.h"
 #include "access/transam.h"
 #include "access/xact.h"
+#include "catalog/dependency.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_database.h"
 #include "catalog/pg_inherits.h"
 #include "catalog/pg_namespace.h"
 #include "commands/cluster.h"
+#include "commands/dbcommands.h"
 #include "commands/vacuum.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
@@ -47,6 +49,7 @@
 #include "utils/acl.h"
 #include "utils/fmgroids.h"
 #include "utils/guc.h"
+#include "utils/lsyscache.h"
 #include "utils/memutils.h"
 #include "utils/snapmgr.h"
 #include "utils/syscache.h"
@@ -1638,7 +1641,33 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
 	 */
 	if (RELATION_IS_OTHER_TEMP(onerel))
 	{
-		relation_close(onerel, lmode);
+		/*
+		 * But in single-user mode this is an orphan temp table. We should drop
+		 * it to resolve possible wraparound.
+		 */
+		if (!IsUnderPostmaster && MyAuxProcType == NotAnAuxProcess)
+		{
+			ObjectAddress object;
+
+			ereport(LOG,
+					(errmsg("dropping orphan temp table \"%s.%s.%s\"",
+							get_database_name(MyDatabaseId),
+							get_namespace_name(onerel->rd_rel->relnamespace),
+							NameStr(onerel->rd_rel->relname))));
+
+			relation_close(onerel, lmode);
+
+			object.classId = RelationRelationId;
+			object.objectId = relid;
+			object.objectSubId = 0;
+			performDeletion(&object, DROP_CASCADE,
+							PERFORM_DELETION_INTERNAL |
+							PERFORM_DELETION_QUIETLY |
+							PERFORM_DELETION_SKIP_EXTENSIONS);
+		}
+		else
+			relation_close(onerel, lmode);
+
 		PopActiveSnapshot();
 		CommitTransactionCommand();
 		return false;
