Index: wp-admin/includes/upgrade.php
===================================================================
--- wp-admin/includes/upgrade.php	(revision 20523)
+++ wp-admin/includes/upgrade.php	(working copy)
@@ -370,6 +370,7 @@
 	upgrade_all();
 	if ( is_multisite() && is_main_site() )
 		upgrade_network();
+	_clear_transients( 'all' );
 	wp_cache_flush();
 
 	if ( is_multisite() ) {
Index: wp-includes/functions.php
===================================================================
--- wp-includes/functions.php	(revision 20523)
+++ wp-includes/functions.php	(working copy)
@@ -3314,9 +3314,9 @@
 function wp_scheduled_delete() {
 	global $wpdb;
 
-	$delete_timestamp = time() - (60*60*24*EMPTY_TRASH_DAYS);
+	$delete_timestamp = time() - ( 60 * 60 * 24 * EMPTY_TRASH_DAYS );
 
-	$posts_to_delete = $wpdb->get_results($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < '%d'", $delete_timestamp), ARRAY_A);
+	$posts_to_delete = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < '%d'", $delete_timestamp ), ARRAY_A );
 
 	foreach ( (array) $posts_to_delete as $post ) {
 		$post_id = (int) $post['post_id'];
@@ -3333,7 +3333,7 @@
 		}
 	}
 
-	$comments_to_delete = $wpdb->get_results($wpdb->prepare("SELECT comment_id FROM $wpdb->commentmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < '%d'", $delete_timestamp), ARRAY_A);
+	$comments_to_delete = $wpdb->get_results( $wpdb->prepare( "SELECT comment_id FROM $wpdb->commentmeta WHERE meta_key = '_wp_trash_meta_time' AND meta_value < '%d'", $delete_timestamp ), ARRAY_A );
 
 	foreach ( (array) $comments_to_delete as $comment ) {
 		$comment_id = (int) $comment['comment_id'];
@@ -3349,6 +3349,8 @@
 			wp_delete_comment($comment_id);
 		}
 	}
+
+	_clear_transients();
 }
 
 /**
@@ -3693,3 +3695,44 @@
 	}
 }
 
+/**
+ * Clear transients on a scheduled cleanup or on DB upgrade.
+ *
+ * @since 3.4.0
+ * @access private
+ *
+ * @param string $mode Either 'expired' or 'all'.
+ */
+function _clear_transients( $mode = 'expired' ) {
+	global $wpdb, $_wp_using_ext_object_cache;
+
+	if ( $_wp_using_ext_object_cache )
+		return;
+
+	if ( 'expired' == $mode )
+		$where = "( option_name LIKE '\_transient_timeout%' OR option_name LIKE '\_site_transient_timeout%' ) AND option_value < UNIX_TIMESTAMP()";
+	else
+		$where = "( option_name LIKE '\_transient%' OR option_name LIKE '\_site_transient%' ) AND option_name NOT LIKE '\_%transient_timeout%'";
+
+	$transients = $wpdb->get_col( "SELECT option_name FROM $wpdb->options WHERE $where" );
+
+	foreach ( (array) $transients as $transient ) {
+		if ( false !== strpos( $transient, '_site_transient_' ) )
+			delete_site_transient( str_replace( array( '_site_transient_timeout_', '_site_transient_' ), '', $transient ) );
+		else
+			delete_transient( str_replace( array( '_transient_timeout_', '_transient_' ), '', $transient ) );
+	}
+
+	if ( is_multisite() ) {
+		if ( 'expired' == $mode )
+			$where = "meta_key LIKE '\_site_transient_timeout%' AND meta_value < UNIX_TIMESTAMP()";
+		else
+			$where = "meta_key LIKE '\_site_transient%' AND meta_key NOT LIKE '\_%transient_timeout%'";
+
+		$site_transients = $wpdb->get_col( "SELECT meta_key FROM $wpdb->sitemeta WHERE $where" );
+
+		foreach ( (array) $site_transients as $transient )
+			delete_site_transient( str_replace( array( '_site_transient_timeout_', '_site_transient_' ), '', $transient ) );
+	}
+}
+
