Problem/Motivation
Drupal\Core\Database\Database::closeConnection()
does not actually close connection.
Currently the Database::closeConnection()
works like follows.
unset(self::$connections[$key]);
// Force garbage collection to run. This ensures that client connection
// objects and results in the connection being closed are destroyed.
gc_collect_cycles();
I think the intention was to trigger connection destructor which should close the actual DB connection by removing PDO object. However this does not work as PHP won't call a destructor if there are any references to the object. In this case references likely come from services that depend on @database
because they keep reference to Drupal\Core\Database\Connection
in their class properties.
Steps to reproduce
Drupal\Core\Database\Database::closeConnection();
sleep(60);
While the Drupal is "sleeping" check open connections to your database with tools like pg_stat_activity.
Proposed resolution
Remove Database::closeConnection()
as it basically useless.
Add \Drupal\Core\Database\Connection::closeClientConnection()
and \Drupal\Core\Database\Connection::openClientConnection()
methods.
Those can look like follows.
public function openClientConnection(): void {
$this->connection = self::open($this->connectionOptions);
}
public function closeClientConnection(): void {
$this->connection = NULL;
}