aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJulius Härtl <jus@bitgrid.net>2023-11-29 09:17:26 +0100
committerJulius Härtl <jus@bitgrid.net>2024-01-12 14:38:01 +0100
commit296096e06996aee1a06d901b99adde5f04688f58 (patch)
tree0f929bee7bf7f4e4d729ae5b7d79f8e4006ee8fc /lib
parent48628b90690d8204e7875d561b8115c526cc9176 (diff)
downloadnextcloud-server-296096e06996aee1a06d901b99adde5f04688f58.tar.gz
nextcloud-server-296096e06996aee1a06d901b99adde5f04688f58.zip
fix: Add reconnect check in case of timeouts on the db side
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'lib')
-rw-r--r--lib/private/DB/Connection.php27
1 files changed, 27 insertions, 0 deletions
diff --git a/lib/private/DB/Connection.php b/lib/private/DB/Connection.php
index a5f41cc66c9..b65f4520290 100644
--- a/lib/private/DB/Connection.php
+++ b/lib/private/DB/Connection.php
@@ -41,6 +41,7 @@ use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Exception;
+use Doctrine\DBAL\Exception\ConnectionLost;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Platforms\SqlitePlatform;
@@ -78,6 +79,7 @@ class Connection extends PrimaryReadReplicaConnection {
/** @var DbDataCollector|null */
protected $dbDataCollector = null;
+ private array $lastConnectionCheck = [];
protected ?float $transactionActiveSince = null;
@@ -127,10 +129,13 @@ class Connection extends PrimaryReadReplicaConnection {
public function connect($connectionName = null) {
try {
if ($this->_conn) {
+ $this->reconnectIfNeeded();
/** @psalm-suppress InternalMethod */
return parent::connect();
}
+ $this->lastConnectionCheck[$this->getConnectionName()] = time();
+
// Only trigger the event logger for the initial connect call
$eventLogger = \OC::$server->get(IEventLogger::class);
$eventLogger->start('connect:db', 'db connection opened');
@@ -679,4 +684,26 @@ class Connection extends PrimaryReadReplicaConnection {
}
return $result;
}
+
+ private function reconnectIfNeeded(): void {
+ if (
+ !isset($this->lastConnectionCheck[$this->getConnectionName()]) ||
+ $this->lastConnectionCheck[$this->getConnectionName()] + 30 >= time() ||
+ $this->isTransactionActive()
+ ) {
+ return;
+ }
+
+ try {
+ $this->_conn->query($this->getDriver()->getDatabasePlatform()->getDummySelectSQL());
+ $this->lastConnectionCheck[$this->getConnectionName()] = time();
+ } catch (ConnectionLost|\Exception $e) {
+ $this->logger->warning('Exception during connectivity check, closing and reconnecting', ['exception' => $e]);
+ $this->close();
+ }
+ }
+
+ private function getConnectionName(): string {
+ return $this->isConnectedToPrimary() ? 'primary' : 'replica';
+ }
}