|
|
|
|
@ -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'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|