From 4e1b1c0811763b82bb69cb1c62574df7a16a315d Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 16 May 2020 08:15:51 +0000 Subject: [PATCH 1/4] Issue 8635: Avoid concurrent database updates Possibly helps with #8635 --- src/Database/DBStructure.php | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/Database/DBStructure.php b/src/Database/DBStructure.php index 0ff97d0c6c..9f225cbb93 100644 --- a/src/Database/DBStructure.php +++ b/src/Database/DBStructure.php @@ -291,6 +291,12 @@ class DBStructure */ public static function update($basePath, $verbose, $action, $install = false, array $tables = null, array $definition = null) { + if (!$install) { + if (self::isUpdating()) { + return DI::l10n()->t('Another database update is currently running.'); + } + } + if ($action && !$install) { DI::config()->set('system', 'maintenance', 1); DI::config()->set('system', 'maintenance_reason', DI::l10n()->t('%s: Database update', DateTimeFormat::utcNow() . ' ' . date('e'))); @@ -1060,4 +1066,31 @@ class DBStructure DBA::close($tokens); } } + + /** + * Checks if a database update is currently running + * + * @return boolean + */ + private static function isUpdating() + { + $processes = DBA::select(['information_schema' => 'processlist'], + ['command', 'info'], ['db' => DBA::databaseName()]); + + $isUpdate = false; + + while ($process = DBA::fetch($processes)) { + if (empty($process['info'])) { + continue; + } + $parts = explode(' ', $process['info']); + $command = strtolower(array_shift($parts)); + if ($command == 'alter') { + $isUpdate = true; + } + } + DBA::close($processes); + + return $isUpdate; + } } From 4faef126ff99a7a514834758723734393abb6d93 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 16 May 2020 09:01:54 +0000 Subject: [PATCH 2/4] Improved structure --- src/Database/DBStructure.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/Database/DBStructure.php b/src/Database/DBStructure.php index 9f225cbb93..352e8b0f87 100644 --- a/src/Database/DBStructure.php +++ b/src/Database/DBStructure.php @@ -1074,21 +1074,18 @@ class DBStructure */ private static function isUpdating() { - $processes = DBA::select(['information_schema' => 'processlist'], - ['command', 'info'], ['db' => DBA::databaseName()]); - $isUpdate = false; + $processes = DBA::select(['information_schema' => 'processlist'], ['info'], + ['db' => DBA::databaseName(), 'command' => ['Query', 'Execute']]); + while ($process = DBA::fetch($processes)) { - if (empty($process['info'])) { - continue; - } $parts = explode(' ', $process['info']); - $command = strtolower(array_shift($parts)); - if ($command == 'alter') { + if (strtolower(array_shift($parts)) == 'alter') { $isUpdate = true; } } + DBA::close($processes); return $isUpdate; From 8e12edc375197e16f87156da941a627c421cd674 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 16 May 2020 10:04:09 +0000 Subject: [PATCH 3/4] Improved code --- src/Database/DBStructure.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Database/DBStructure.php b/src/Database/DBStructure.php index 352e8b0f87..dcb59fc9f2 100644 --- a/src/Database/DBStructure.php +++ b/src/Database/DBStructure.php @@ -291,13 +291,11 @@ class DBStructure */ public static function update($basePath, $verbose, $action, $install = false, array $tables = null, array $definition = null) { - if (!$install) { + if ($action && !$install) { if (self::isUpdating()) { return DI::l10n()->t('Another database update is currently running.'); } - } - if ($action && !$install) { DI::config()->set('system', 'maintenance', 1); DI::config()->set('system', 'maintenance_reason', DI::l10n()->t('%s: Database update', DateTimeFormat::utcNow() . ' ' . date('e'))); } From 28e7564d79de34d0c00e5da46549e288de2bc280 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 16 May 2020 10:21:16 +0000 Subject: [PATCH 4/4] Added some more sql commands to the list --- src/Database/DBStructure.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Database/DBStructure.php b/src/Database/DBStructure.php index dcb59fc9f2..9a43c06240 100644 --- a/src/Database/DBStructure.php +++ b/src/Database/DBStructure.php @@ -1079,7 +1079,7 @@ class DBStructure while ($process = DBA::fetch($processes)) { $parts = explode(' ', $process['info']); - if (strtolower(array_shift($parts)) == 'alter') { + if (in_array(strtolower(array_shift($parts)), ['alter', 'create', 'drop', 'rename'])) { $isUpdate = true; } }