diff --git a/core/lib/Drupal/Core/Database/Connection.php b/core/lib/Drupal/Core/Database/Connection.php
index c3bfff0d512e68b0006a448e332c4bebd8234d9e..919261ab21d89e1e0cb8be756d9ca4607205f1c0 100644
--- a/core/lib/Drupal/Core/Database/Connection.php
+++ b/core/lib/Drupal/Core/Database/Connection.php
@@ -214,6 +214,13 @@ public function __construct(\PDO $connection, array $connection_options) {
       unset($connection_options['transactions']);
     }
 
+    // Work out the database driver namespace if none is provided. This normally
+    // written to setting.php by installer or set by
+    // \Drupal\Core\Database\Database::parseConnectionInfo().
+    if (empty($connection_options['namespace'])) {
+      $connection_options['namespace'] = (new \ReflectionObject($this))->getNamespaceName();
+    }
+
     // Initialize and prepare the connection prefix.
     $this->setPrefix(isset($connection_options['prefix']) ? $connection_options['prefix'] : '');
 
@@ -863,10 +870,6 @@ protected function expandArguments(&$query, &$args) {
    */
   public function getDriverClass($class) {
     if (empty($this->driverClasses[$class])) {
-      if (empty($this->connectionOptions['namespace'])) {
-        // Fallback for Drupal 7 settings.php and the test runner script.
-        $this->connectionOptions['namespace'] = (new \ReflectionObject($this))->getNamespaceName();
-      }
       $driver_class = $this->connectionOptions['namespace'] . '\\' . $class;
       $this->driverClasses[$class] = class_exists($driver_class) ? $driver_class : $class;
       if ($this->driverClasses[$class] === 'Condition') {
diff --git a/core/lib/Drupal/Core/Database/Database.php b/core/lib/Drupal/Core/Database/Database.php
index 08e2146bd81709468ecde902cf038e3167be8b3d..719dd29c4d23f17ae2030116375284ac78d237b7 100644
--- a/core/lib/Drupal/Core/Database/Database.php
+++ b/core/lib/Drupal/Core/Database/Database.php
@@ -214,6 +214,7 @@ final public static function parseConnectionInfo(array $info) {
     if (empty($info['driver'])) {
       $info = $info[mt_rand(0, count($info) - 1)];
     }
+
     // Parse the prefix information.
     if (!isset($info['prefix'])) {
       // Default to an empty prefix.
@@ -227,6 +228,12 @@ final public static function parseConnectionInfo(array $info) {
         'default' => $info['prefix'],
       ];
     }
+
+    // Fallback for Drupal 7 settings.php if namespace is not provided.
+    if (empty($info['namespace'])) {
+      $info['namespace'] = 'Drupal\\Core\\Database\\Driver\\' . $info['driver'];
+    }
+
     return $info;
   }
 
@@ -368,8 +375,7 @@ final protected static function openConnection($key, $target) {
       throw new DriverNotSpecifiedException('Driver not specified for this database connection: ' . $key);
     }
 
-    $namespace = static::getDatabaseDriverNamespace(self::$databaseInfo[$key][$target]);
-    $driver_class = $namespace . '\\Connection';
+    $driver_class = self::$databaseInfo[$key][$target]['namespace'] . '\\Connection';
 
     $pdo_connection = $driver_class::open(self::$databaseInfo[$key][$target]);
     $new_connection = new $driver_class($pdo_connection, self::$databaseInfo[$key][$target]);
@@ -605,7 +611,7 @@ public static function getConnectionInfoAsUrl($key = 'default') {
     if (empty($db_info) || empty($db_info['default'])) {
       throw new \RuntimeException("Database connection $key not defined or missing the 'default' settings");
     }
-    $namespace = static::getDatabaseDriverNamespace($db_info['default']);
+    $namespace = $db_info['default']['namespace'];
 
     // If the driver namespace is within a Drupal module, add the module name
     // to the connection options to make it easy for the connection class's
@@ -628,8 +634,14 @@ public static function getConnectionInfoAsUrl($key = 'default') {
    *
    * @return string
    *   The PHP namespace of the driver's database.
+   *
+   * @deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. There is no
+   *   replacement as $connection_info['namespace'] is always set.
+   *
+   * @see https://www.drupal.org/node/3127769
    */
   protected static function getDatabaseDriverNamespace(array $connection_info) {
+    @trigger_error(__METHOD__ . " is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. There is no replacement as \$connection_info['namespace'] is always set. See https://www.drupal.org/node/3127769.", E_USER_DEPRECATED);
     if (isset($connection_info['namespace'])) {
       return $connection_info['namespace'];
     }
diff --git a/core/lib/Drupal/Core/Database/Log.php b/core/lib/Drupal/Core/Database/Log.php
index ce7780eb0ade366ea55226c4e591b1e7b9f98176..49d00cfc2837679e01f76fd4ed76809a83011995 100644
--- a/core/lib/Drupal/Core/Database/Log.php
+++ b/core/lib/Drupal/Core/Database/Log.php
@@ -38,13 +38,6 @@ class Log {
    */
   protected $connectionKey = 'default';
 
-  /**
-   * The PHP namespace of the database driver that this object is logging.
-   *
-   * @var string
-   */
-  protected $driverNamespace;
-
   /**
    * Constructor.
    *
@@ -152,6 +145,8 @@ public function log(StatementInterface $statement, $args, $time) {
   public function findCaller() {
     $stack = $this->getDebugBacktrace();
 
+    $driver_namespace = Database::getConnectionInfo($this->connectionKey)['default']['namespace'];
+
     // Starting from the very first entry processed during the request, find
     // the first function call that can be identified as a call to a
     // method/function in the database layer.
@@ -160,7 +155,7 @@ public function findCaller() {
       // it a default empty string value in that case.
       $class = $stack[$n]['class'] ?? '';
 
-      if (strpos($class, __NAMESPACE__, 0) === 0 || strpos($class, $this->getDriverNamespace(), 0) === 0) {
+      if (strpos($class, __NAMESPACE__, 0) === 0 || strpos($class, $driver_namespace, 0) === 0) {
         break;
       }
     }
@@ -181,20 +176,6 @@ public function findCaller() {
     }
   }
 
-  /**
-   * Gets the namespace of the database driver.
-   *
-   * @return string|null
-   *   Namespace of the database driver, or NULL if the connection is
-   *   missing.
-   */
-  protected function getDriverNamespace() {
-    if (!isset($this->driverNamespace)) {
-      $this->driverNamespace = (new \ReflectionObject(Database::getConnection('default', $this->connectionKey)))->getNamespaceName();
-    }
-    return $this->driverNamespace;
-  }
-
   /**
    * Gets the debug backtrace.
    *
diff --git a/core/modules/system/tests/modules/database_statement_monitoring_test/src/LoggedStatementsTrait.php b/core/modules/system/tests/modules/database_statement_monitoring_test/src/LoggedStatementsTrait.php
index d4f760e093cfe33290c7525c0b3d255c4befb4ac..72de5448297fcad3d960be0fcf17bfbee590b82b 100644
--- a/core/modules/system/tests/modules/database_statement_monitoring_test/src/LoggedStatementsTrait.php
+++ b/core/modules/system/tests/modules/database_statement_monitoring_test/src/LoggedStatementsTrait.php
@@ -46,8 +46,9 @@ public function resetLoggedStatements() {
    * {@inheritdoc}
    */
   public function getDriverClass($class) {
-    // Override because the base class uses reflection to determine namespace
-    // based on object, which would break.
+    // Override because the database driver copies in the
+    // database_statement_monitoring_test module don't contain all the necessary
+    // classes.
     $namespace = (new \ReflectionClass(get_parent_class($this)))->getNamespaceName();
     $driver_class = $namespace . '\\' . $class;
     if (class_exists($driver_class)) {
diff --git a/core/tests/Drupal/KernelTests/Core/Database/LoggingTest.php b/core/tests/Drupal/KernelTests/Core/Database/LoggingTest.php
index daa6a15a5cda4b2207b60ffb836826819f687f8b..3b4a920c776243ff6aa3a5c866f9de1147a55a25 100644
--- a/core/tests/Drupal/KernelTests/Core/Database/LoggingTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Database/LoggingTest.php
@@ -155,14 +155,13 @@ public function testGetLoggingWrongKey() {
   public function testContribDriverLog($driver_namespace, $stack, array $expected_entry) {
     $mock_builder = $this->getMockBuilder(Log::class);
     $log = $mock_builder
-      ->setMethods(['getDriverNamespace', 'getDebugBacktrace'])
+      ->setMethods(['getDebugBacktrace'])
+      ->setConstructorArgs(['test'])
       ->getMock();
-    $log->expects($this->any())
-      ->method('getDriverNamespace')
-      ->will($this->returnValue($driver_namespace));
     $log->expects($this->once())
       ->method('getDebugBacktrace')
       ->will($this->returnValue($stack));
+    Database::addConnectionInfo('test', 'default', ['driver' => 'mysql', 'namespace' => $driver_namespace]);
 
     $result = $log->findCaller($stack);
     $this->assertEquals($expected_entry, $result);
diff --git a/core/tests/Drupal/Tests/Core/Database/ConnectionTest.php b/core/tests/Drupal/Tests/Core/Database/ConnectionTest.php
index ceb5cb9761c12e607d874c91b22e529f0b6506f5..80055026677af6f45a3dd232c025a051af31a49a 100644
--- a/core/tests/Drupal/Tests/Core/Database/ConnectionTest.php
+++ b/core/tests/Drupal/Tests/Core/Database/ConnectionTest.php
@@ -432,4 +432,13 @@ public function testIdentifierQuotesAssertString() {
     new StubConnection($mock_pdo, [], [0, '1']);
   }
 
+  /**
+   * @covers ::__construct
+   */
+  public function testNamespaceDefault() {
+    $mock_pdo = $this->createMock(StubPDO::class);
+    $connection = new StubConnection($mock_pdo, []);
+    $this->assertSame('Drupal\Tests\Core\Database\Stub', $connection->getConnectionOptions()['namespace']);
+  }
+
 }
diff --git a/core/tests/Drupal/Tests/Core/Database/LogTest.php b/core/tests/Drupal/Tests/Core/Database/LogTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7184be4dc2ca6d3bcdca9234470f17060aeb0afe
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Database/LogTest.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Drupal\Tests\Core\Database;
+
+use Drupal\Core\Database\Database;
+use Drupal\Core\Database\Log;
+use Drupal\Tests\Core\Database\Stub\StubConnection;
+use Drupal\Tests\Core\Database\Stub\StubPDO;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Tests the Log class.
+ *
+ * @group Database
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState disabled
+ * @coversDefaultClass \Drupal\Core\Database\Log
+ */
+class LogTest extends UnitTestCase {
+
+  /**
+   * Tests that a log called by a custom database driver returns proper caller.
+   *
+   * @covers ::findCaller
+   */
+  public function testContribDriverLog() {
+    Database::addConnectionInfo('default', 'default', [
+      'driver' => 'test',
+      'namespace' => 'Drupal\Tests\Core\Database\Stub',
+    ]);
+
+    $pdo = $this->prophesize(StubPDO::class)->reveal();
+    $result = (new StubConnection($pdo, []))->testLogCaller();
+    $this->assertSame([
+      'file' => __FILE__,
+      'line' => 33,
+      'function' => 'testContribDriverLog',
+      'class' => 'Drupal\Tests\Core\Database\LogTest',
+      'type' => '->',
+      'args' => [],
+    ], $result);
+
+    // Test calling the database log from outside of database code.
+    $result = (new Log())->findCaller();
+    $this->assertSame([
+      'file' => __FILE__,
+      'line' => 44,
+      'function' => 'testContribDriverLog',
+      'class' => 'Drupal\Tests\Core\Database\LogTest',
+      'type' => '->',
+      'args' => [],
+    ], $result);
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Database/OrderByTest.php b/core/tests/Drupal/Tests/Core/Database/OrderByTest.php
index 4f330a426fc659e1f80b8914de8d634c54092b39..8f7427ed3eaca421399f1227cd53b4d894f68762 100644
--- a/core/tests/Drupal/Tests/Core/Database/OrderByTest.php
+++ b/core/tests/Drupal/Tests/Core/Database/OrderByTest.php
@@ -3,6 +3,8 @@
 namespace Drupal\Tests\Core\Database;
 
 use Drupal\Core\Database\Query\Select;
+use Drupal\Tests\Core\Database\Stub\StubConnection;
+use Drupal\Tests\Core\Database\Stub\StubPDO;
 use Drupal\Tests\UnitTestCase;
 
 /**
@@ -23,9 +25,8 @@ class OrderByTest extends UnitTestCase {
    * {@inheritdoc}
    */
   protected function setUp(): void {
-    $connection = $this->getMockBuilder('Drupal\Core\Database\Connection')
-      ->disableOriginalConstructor()
-      ->getMockForAbstractClass();
+    $mockPdo = $this->createMock(StubPDO::class);
+    $connection = new StubConnection($mockPdo, []);
     $this->query = new Select($connection, 'test', NULL);
   }
 
diff --git a/core/tests/Drupal/Tests/Core/Database/Stub/StubConnection.php b/core/tests/Drupal/Tests/Core/Database/Stub/StubConnection.php
index db1a3809b296a5ad46e54b73cb1320e423f67a12..eb8d9487b68819ee0b92b4da647494648bbb849b 100644
--- a/core/tests/Drupal/Tests/Core/Database/Stub/StubConnection.php
+++ b/core/tests/Drupal/Tests/Core/Database/Stub/StubConnection.php
@@ -3,6 +3,7 @@
 namespace Drupal\Tests\Core\Database\Stub;
 
 use Drupal\Core\Database\Connection;
+use Drupal\Core\Database\Log;
 use Drupal\Core\Database\StatementEmpty;
 
 /**
@@ -84,4 +85,14 @@ public function nextId($existing_id = 0) {
     return 0;
   }
 
+  /**
+   * Helper method to test database classes are not included in backtraces.
+   *
+   * @return array
+   *   The caller stack entry.
+   */
+  public function testLogCaller() {
+    return (new Log())->findCaller();
+  }
+
 }