diff --git a/core/ajax/update.php b/core/ajax/update.php
index 84d7a21209e4be4225776ab2e53d8e3fddcf90db..698614c975f2a865068d5e49124ab9a62ad1a2f7 100644
--- a/core/ajax/update.php
+++ b/core/ajax/update.php
@@ -15,6 +15,9 @@ if (OC::checkUpgrade(false)) {
 	$updater->listen('\OC\Updater', 'dbUpgrade', function () use ($eventSource, $l) {
 		$eventSource->send('success', (string)$l->t('Updated database'));
 	});
+	$updater->listen('\OC\Updater', 'dbSimulateUpgrade', function () use ($eventSource, $l) {
+		$eventSource->send('success', (string)$l->t('Checked database schema update'));
+	});
 	$updater->listen('\OC\Updater', 'disabledApps', function ($appList) use ($eventSource, $l) {
 		$list = array();
 		foreach ($appList as $appId) {
diff --git a/core/command/upgrade.php b/core/command/upgrade.php
index 8ce8ef9b6e5e4b9753bba37d6d2c1bb0c3f8e489..c3946d2aab5276c5ef634b0b3ae3161f8533c6ba 100644
--- a/core/command/upgrade.php
+++ b/core/command/upgrade.php
@@ -56,6 +56,9 @@ class Upgrade extends Command {
 			$updater->listen('\OC\Updater', 'dbUpgrade', function () use($output) {
 				$output->writeln('<info>Updated database</info>');
 			});
+			$updater->listen('\OC\Updater', 'dbSimulateUpgrade', function () use($output) {
+				$output->writeln('<info>Checked database schema update</info>');
+			});
 			$updater->listen('\OC\Updater', 'disabledApps', function ($appList) use($output) {
 				$output->writeln('<info>Disabled incompatible apps: ' . implode(', ', $appList) . '</info>');
 			});
diff --git a/core/js/update.js b/core/js/update.js
index cc0f541bd7985c9e9afd8bedb4f28e0106883a2a..e5ce322df9587baf9597b55393bf78e565de9d63 100644
--- a/core/js/update.js
+++ b/core/js/update.js
@@ -28,7 +28,7 @@
 			this.addMessage(t(
 				'core',
 				'Updating {productName} to version {version}, this may take a while.', {
-					productName: OC.theme.name,
+					productName: OC.theme.name || 'ownCloud',
 					version: OC.config.versionstring
 				}),
 				'bold'
diff --git a/lib/base.php b/lib/base.php
index 376bb6c1d0ac6c07ebd7b17c76df5ee80e56ecb2..608fe16dcefbd3d432465e41bff42828af5048e0 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -730,7 +730,7 @@ class OC {
 
 		if (!self::$CLI and (!isset($_GET["logout"]) or ($_GET["logout"] !== 'true'))) {
 			try {
-				if (!OC_Config::getValue('maintenance', false)) {
+				if (!OC_Config::getValue('maintenance', false) && !self::needUpgrade()) {
 					OC_App::loadApps();
 				}
 				self::checkSingleUserMode();
diff --git a/lib/private/app.php b/lib/private/app.php
index 52f77535a5262fce2b34ba411f0546225910805e..2650ad98bc6a8c80130a40211c5ad010977c6b28 100644
--- a/lib/private/app.php
+++ b/lib/private/app.php
@@ -875,6 +875,18 @@ class OC_App {
 		}
 	}
 
+	public static function shouldUpgrade($app) {
+		$versions = self::getAppVersions();
+		$currentVersion = OC_App::getAppVersion($app);
+		if ($currentVersion) {
+			$installedVersion = $versions[$app];
+			if (version_compare($currentVersion, $installedVersion, '>')) {
+				return true;
+			}
+		}
+		return false;
+	}
+
 	/**
 	 * check if the app needs updating and update when needed
 	 *
@@ -885,26 +897,27 @@ class OC_App {
 			return;
 		}
 		self::$checkedApps[] = $app;
+		if (!self::shouldUpgrade($app)) {
+			return;
+		}
 		$versions = self::getAppVersions();
+		$installedVersion = $versions[$app];
 		$currentVersion = OC_App::getAppVersion($app);
-		if ($currentVersion) {
-			$installedVersion = $versions[$app];
-			if (version_compare($currentVersion, $installedVersion, '>')) {
-				$info = self::getAppInfo($app);
-				OC_Log::write($app,
-					'starting app upgrade from ' . $installedVersion . ' to ' . $currentVersion,
-					OC_Log::DEBUG);
-				try {
-					OC_App::updateApp($app);
-					OC_Hook::emit('update', 'success', 'Updated ' . $info['name'] . ' app');
-				} catch (Exception $e) {
-					OC_Hook::emit('update', 'failure', 'Failed to update ' . $info['name'] . ' app: ' . $e->getMessage());
-					$l = OC_L10N::get('lib');
-					throw new RuntimeException($l->t('Failed to upgrade "%s".', array($app)), 0, $e);
-				}
-				OC_Appconfig::setValue($app, 'installed_version', OC_App::getAppVersion($app));
-			}
+		OC_Log::write(
+			$app,
+			'starting app upgrade from ' . $installedVersion . ' to ' . $currentVersion,
+			OC_Log::DEBUG
+		);
+		$info = self::getAppInfo($app);
+		try {
+			OC_App::updateApp($app);
+			OC_Hook::emit('update', 'success', 'Updated ' . $info['name'] . ' app');
+		} catch (Exception $e) {
+			OC_Hook::emit('update', 'failure', 'Failed to update ' . $info['name'] . ' app: ' . $e->getMessage());
+			$l = OC_L10N::get('lib');
+			throw new RuntimeException($l->t('Failed to upgrade "%s".', array($app)), 0, $e);
 		}
+		OC_Appconfig::setValue($app, 'installed_version', OC_App::getAppVersion($app));
 	}
 
 	/**
diff --git a/lib/private/db.php b/lib/private/db.php
index 422f783c745633ac3941f5ff1fd79ba889b54ea2..82affe293edab44bf6d1fe4bba1c3c2f9d18da9c 100644
--- a/lib/private/db.php
+++ b/lib/private/db.php
@@ -321,6 +321,23 @@ class OC_DB {
 		return $result;
 	}
 
+	/**
+	 * simulate the database schema update
+	 * @param string $file file to read structure from
+	 * @throws Exception
+	 * @return string|boolean
+	 */
+	public static function simulateUpdateDbFromStructure($file) {
+		$schemaManager = self::getMDB2SchemaManager();
+		try {
+			$result = $schemaManager->simulateUpdateDbFromStructure($file);
+		} catch (Exception $e) {
+			OC_Log::write('core', 'Simulated database structure update failed ('.$e.')', OC_Log::FATAL);
+			throw $e;
+		}
+		return $result;
+	}
+
 	/**
 	 * drop a table - the database prefix will be prepended
 	 * @param string $tableName the table to drop
diff --git a/lib/private/db/mdb2schemamanager.php b/lib/private/db/mdb2schemamanager.php
index 533ed9110e7b780247a4eb02bf4829bf52ea3ef2..734ba18d1ac8688a64ab3ba95b1422263ef9d638 100644
--- a/lib/private/db/mdb2schemamanager.php
+++ b/lib/private/db/mdb2schemamanager.php
@@ -73,6 +73,17 @@ class MDB2SchemaManager {
 		}
 	}
 
+	/**
+	 * Reads database schema from file
+	 *
+	 * @param string $file file to read from
+	 */
+	private function readSchemaFromFile($file) {
+		$platform = $this->conn->getDatabasePlatform();
+		$schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $platform);
+		return $schemaReader->loadSchemaFromFile($file);
+	}
+
 	/**
 	 * update the database scheme
 	 * @param string $file file to read structure from
@@ -80,21 +91,28 @@ class MDB2SchemaManager {
 	 * @return string|boolean
 	 */
 	public function updateDbFromStructure($file, $generateSql = false) {
-
-		$platform = $this->conn->getDatabasePlatform();
-		$schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $platform);
-		$toSchema = $schemaReader->loadSchemaFromFile($file);
+		$toSchema = $this->readSchemaFromFile($file);
 		$migrator = $this->getMigrator();
 
 		if ($generateSql) {
 			return $migrator->generateChangeScript($toSchema);
 		} else {
-			$migrator->checkMigrate($toSchema);
 			$migrator->migrate($toSchema);
 			return true;
 		}
 	}
 
+	/**
+	 * update the database scheme
+	 * @param string $file file to read structure from
+	 * @return string|boolean
+	 */
+	public function simulateUpdateDbFromStructure($file) {
+		$toSchema = $this->readSchemaFromFile($file);
+		$migrator = $this->getMigrator()->checkMigrate($toSchema);
+		return true;
+	}
+
 	/**
 	 * @param \Doctrine\DBAL\Schema\Schema $schema
 	 * @return string
diff --git a/lib/private/updater.php b/lib/private/updater.php
index 58d3cab73aa0a0e8ce65a4d9e5944d34a5fd76fc..106970c412194e7855385a68faf7d44df23ea591 100644
--- a/lib/private/updater.php
+++ b/lib/private/updater.php
@@ -125,29 +125,63 @@ class Updater extends BasicEmitter {
 		 * STOP CONFIG CHANGES FOR OLDER VERSIONS
 		 */
 
+		$canUpgrade = false;
 
+		// simulate DB upgrade
 		try {
-			\OC_DB::updateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml');
-			$this->emit('\OC\Updater', 'dbUpgrade');
-
+			// simulate core DB upgrade
+			\OC_DB::simulateUpdateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml');
+
+			// simulate apps DB upgrade
+			$version = \OC_Util::getVersion();
+			$apps = \OC_App::getEnabledApps();
+			foreach ($apps as $appId) {
+				$info = \OC_App::getAppInfo($appId);
+				if (\OC_App::isAppCompatible($version, $info) && \OC_App::shouldUpgrade($appId)) {
+					if (file_exists(\OC_App::getAppPath($appId) . '/appinfo/database.xml')) {
+						\OC_DB::simulateUpdateDbFromStructure(\OC_App::getAppPath($appId) . '/appinfo/database.xml');
+					}
+				}
+			}
+
+			$this->emit('\OC\Updater', 'dbSimulateUpgrade');
+
+			$canUpgrade = true;
 		} catch (\Exception $exception) {
 			$this->emit('\OC\Updater', 'failure', array($exception->getMessage()));
 		}
-		\OC_Config::setValue('version', implode('.', \OC_Util::getVersion()));
-		$disabledApps = \OC_App::checkAppsRequirements();
-		if (!empty($disabledApps)) {
-			$this->emit('\OC\Updater', 'disabledApps', array($disabledApps));
-		}
-		// load all apps to also upgrade enabled apps
-		\OC_App::loadApps();
 
-		$repair = new Repair();
-		$repair->run();
+		if ($canUpgrade) {
+			// proceed with real upgrade
+			try {
+				// do the real upgrade
+				\OC_DB::updateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml');
+				$this->emit('\OC\Updater', 'dbUpgrade');
+
+			} catch (\Exception $exception) {
+				$this->emit('\OC\Updater', 'failure', array($exception->getMessage()));
+				return false;
+			}
+			// TODO: why not do this at the end ?
+			\OC_Config::setValue('version', implode('.', \OC_Util::getVersion()));
+			$disabledApps = \OC_App::checkAppsRequirements();
+			if (!empty($disabledApps)) {
+				$this->emit('\OC\Updater', 'disabledApps', array($disabledApps));
+			}
+			// load all apps to also upgrade enabled apps
+			\OC_App::loadApps();
+
+			$repair = new Repair();
+			$repair->run();
+
+			//Invalidate update feed
+			\OC_Appconfig::setValue('core', 'lastupdatedat', 0);
+		}
 
-		//Invalidate update feed
-		\OC_Appconfig::setValue('core', 'lastupdatedat', 0);
 		\OC_Config::setValue('maintenance', false);
 		$this->emit('\OC\Updater', 'maintenanceEnd');
+
+		return $canUpgrade;
 	}
 
 }