From 8a2437927d51a7f8faf79c1be7cce818fbccde4e Mon Sep 17 00:00:00 2001 From: Louis Chemineau Date: Tue, 18 Feb 2025 15:49:36 +0100 Subject: [PATCH] fix: Initialize lastConnectionCheck after first connection We are checking whether the DB connection is alive once every 30 seconds. But when we are lacking the last check time, we are skipping the check and reconnect logic. This is causing the reconnect logic to never fire in those cases. It seems to me that "those cases", are actually always the case, as upon initialization, we are not using the proper connection name to store the time. In the `connect()` logic, when `$this->_conn` is null, `$this->getConnectionName()` is returning `replica`, so `$this->lastConnectionCheck` will be equal to `['replica' => time()];` https://github.com/nextcloud/server/blob/60711ea4cfde6f53d0b18bcd7e166a34a43056a5/lib/private/DB/Connection.php#L215-L221 https://github.com/nextcloud/server/blob/60711ea4cfde6f53d0b18bcd7e166a34a43056a5/lib/private/DB/Connection.php#L891-L893 https://github.com/nextcloud/3rdparty/blob/2b6d7bf65ff242ea050e736925f752a38d8da220/doctrine/dbal/src/Connections/PrimaryReadReplicaConnection.php#L136-L139 Then, if the connection name ends up as being 'primary', the reconnect logic is skipped: https://github.com/nextcloud/server/blob/60711ea4cfde6f53d0b18bcd7e166a34a43056a5/lib/private/DB/Connection.php#L874-L880 Follow-up of https://github.com/nextcloud/server/pull/41819 Signed-off-by: Louis Chemineau --- lib/private/DB/Connection.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/private/DB/Connection.php b/lib/private/DB/Connection.php index 1b61cc83319ac..e2e36f83c8844 100644 --- a/lib/private/DB/Connection.php +++ b/lib/private/DB/Connection.php @@ -218,8 +218,6 @@ public function connect($connectionName = null) { return parent::connect(); } - $this->lastConnectionCheck[$this->getConnectionName()] = time(); - // Only trigger the event logger for the initial connect call $eventLogger = Server::get(IEventLogger::class); $eventLogger->start('connect:db', 'db connection opened'); @@ -227,6 +225,8 @@ public function connect($connectionName = null) { $status = parent::connect(); $eventLogger->end('connect:db'); + $this->lastConnectionCheck[$this->getConnectionName()] = time(); + return $status; } catch (Exception $e) { // throw a new exception to prevent leaking info from the stacktrace