diff --git a/core/includes/database.inc b/core/includes/database.inc
index e81c628565..04bd0bf639 100644
--- a/core/includes/database.inc
+++ b/core/includes/database.inc
@@ -233,6 +233,9 @@ function db_update($table, array $options = []) {
  * @see \Drupal\Core\Database\Connection::defaultOptions()
  */
 function db_delete($table, array $options = []) {
+  @trigger_error('db_delete is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Instead, get a database connection injected into your service from the container and call delete() on it. For example, $injected_database->delete($table, $options). See https://www.drupal.org/node/2993033', E_USER_DEPRECATED);
+  // @todo Move away from here setting default target connection,
+  // https://www.drupal.org/node/2947775
   if (empty($options['target']) || $options['target'] == 'replica') {
     $options['target'] = 'default';
   }
diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
index 626be4bba6..f1a516c9a4 100644
--- a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
@@ -610,7 +610,8 @@ public function nextIdDelete() {
     // counter.
     try {
       $max_id = $this->query('SELECT MAX(value) FROM {sequences}')->fetchField();
-      // We know we are using MySQL here, no need for the slower db_delete().
+      // We know we are using MySQL here, no need for the slower
+      // \Drupal::database()->delete().
       $this->query('DELETE FROM {sequences} WHERE value < :value', [':value' => $max_id]);
     }
     // During testing, this function is called from shutdown with the
diff --git a/core/lib/Drupal/Core/Entity/entity.api.php b/core/lib/Drupal/Core/Entity/entity.api.php
index ac137330f8..96a65619d7 100644
--- a/core/lib/Drupal/Core/Entity/entity.api.php
+++ b/core/lib/Drupal/Core/Entity/entity.api.php
@@ -1340,7 +1340,7 @@ function hook_ENTITY_TYPE_predelete(Drupal\Core\Entity\EntityInterface $entity)
  */
 function hook_entity_delete(Drupal\Core\Entity\EntityInterface $entity) {
   // Delete the entity's entry from a fictional table of all entities.
-  db_delete('example_entity')
+  \Drupal::database()->delete('example_entity')
     ->condition('type', $entity->getEntityTypeId())
     ->condition('id', $entity->id())
     ->execute();
@@ -1359,7 +1359,7 @@ function hook_entity_delete(Drupal\Core\Entity\EntityInterface $entity) {
  */
 function hook_ENTITY_TYPE_delete(Drupal\Core\Entity\EntityInterface $entity) {
   // Delete the entity's entry from a fictional table of all entities.
-  db_delete('example_entity')
+  \Drupal::database()->delete('example_entity')
     ->condition('type', $entity->getEntityTypeId())
     ->condition('id', $entity->id())
     ->execute();
diff --git a/core/modules/aggregator/tests/src/Functional/ImportOpmlTest.php b/core/modules/aggregator/tests/src/Functional/ImportOpmlTest.php
index 2500b9ebb5..7c6ba1c878 100644
--- a/core/modules/aggregator/tests/src/Functional/ImportOpmlTest.php
+++ b/core/modules/aggregator/tests/src/Functional/ImportOpmlTest.php
@@ -70,6 +70,7 @@ public function validateImportFormFields() {
    * Submits form with invalid, empty, and valid OPML files.
    */
   protected function submitImportForm() {
+    $connection = \Drupal::database();
     $before = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();
 
     $form['files[upload]'] = $this->getInvalidOpml();
@@ -83,7 +84,7 @@ protected function submitImportForm() {
     $after = db_query('SELECT COUNT(*) FROM {aggregator_feed}')->fetchField();
     $this->assertEqual($before, $after, 'No feeds were added during the two last form submissions.');
 
-    db_delete('aggregator_feed')->execute();
+    $connection->delete('aggregator_feed')->execute();
 
     $feeds[0] = $this->getFeedEditArray();
     $feeds[1] = $this->getFeedEditArray();
diff --git a/core/modules/dblog/dblog.module b/core/modules/dblog/dblog.module
index bc04ce8fe4..a32c67de01 100644
--- a/core/modules/dblog/dblog.module
+++ b/core/modules/dblog/dblog.module
@@ -67,6 +67,7 @@ function dblog_cron() {
   // Counting the most recent n rows avoids issues with wid number sequences,
   // e.g. auto_increment value > 1 or rows deleted directly from the table.
   if ($row_limit > 0) {
+    $connection = \Drupal::database();
     $min_row = db_select('watchdog', 'w')
       ->fields('w', ['wid'])
       ->orderBy('wid', 'DESC')
@@ -75,7 +76,7 @@ function dblog_cron() {
 
     // Delete all table entries older than the nth row, if nth row was found.
     if ($min_row) {
-      db_delete('watchdog')
+      $connection->delete('watchdog')
         ->condition('wid', $min_row, '<')
         ->execute();
     }
diff --git a/core/modules/dblog/tests/src/Functional/DbLogTest.php b/core/modules/dblog/tests/src/Functional/DbLogTest.php
index 2b2f388cb2..53ebd8f374 100644
--- a/core/modules/dblog/tests/src/Functional/DbLogTest.php
+++ b/core/modules/dblog/tests/src/Functional/DbLogTest.php
@@ -554,7 +554,7 @@ public function testFilter() {
     $this->drupalLogin($this->adminUser);
 
     // Clear the log to ensure that only generated entries will be found.
-    db_delete('watchdog')->execute();
+    \Drupal::database()->delete('watchdog')->execute();
 
     // Generate 9 random watchdog entries.
     $type_names = [];
diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php
index 64e2893e71..6e5de30f00 100644
--- a/core/modules/field/field.api.php
+++ b/core/modules/field/field.api.php
@@ -393,7 +393,7 @@ function hook_field_info_max_weight($entity_type, $bundle, $context, $context_mo
  *   The field storage being purged.
  */
 function hook_field_purge_field_storage(\Drupal\field\Entity\FieldStorageConfig $field_storage) {
-  db_delete('my_module_field_storage_info')
+  \Drupal::database()->delete('my_module_field_storage_info')
     ->condition('uuid', $field_storage->uuid())
     ->execute();
 }
@@ -410,7 +410,7 @@ function hook_field_purge_field_storage(\Drupal\field\Entity\FieldStorageConfig
  *   The field being purged.
  */
 function hook_field_purge_field(\Drupal\field\Entity\FieldConfig $field) {
-  db_delete('my_module_field_info')
+  \Drupal::database()->delete('my_module_field_info')
     ->condition('id', $field->id())
     ->execute();
 }
diff --git a/core/modules/history/history.module b/core/modules/history/history.module
index fddbe44c8a..e1ca3f4f33 100644
--- a/core/modules/history/history.module
+++ b/core/modules/history/history.module
@@ -124,7 +124,7 @@ function history_write($nid, $account = NULL) {
  * Implements hook_cron().
  */
 function history_cron() {
-  db_delete('history')
+  \Drupal::database()->delete('history')
     ->condition('timestamp', HISTORY_READ_LIMIT, '<')
     ->execute();
 }
@@ -151,7 +151,7 @@ function history_node_view_alter(array &$build, EntityInterface $node, EntityVie
  * Implements hook_ENTITY_TYPE_delete() for node entities.
  */
 function history_node_delete(EntityInterface $node) {
-  db_delete('history')
+  \Drupal::database()->delete('history')
     ->condition('nid', $node->id())
     ->execute();
 }
@@ -162,7 +162,7 @@ function history_node_delete(EntityInterface $node) {
 function history_user_cancel($edit, $account, $method) {
   switch ($method) {
     case 'user_cancel_reassign':
-      db_delete('history')
+      \Drupal::database()->delete('history')
         ->condition('uid', $account->id())
         ->execute();
       break;
@@ -173,7 +173,7 @@ function history_user_cancel($edit, $account, $method) {
  * Implements hook_ENTITY_TYPE_delete() for user entities.
  */
 function history_user_delete($account) {
-  db_delete('history')
+  \Drupal::database()->delete('history')
     ->condition('uid', $account->id())
     ->execute();
 }
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index 8bc05fc75f..0adb1fc602 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -863,7 +863,7 @@ function locale_translation_update_file_history($file) {
  *   Language code(s) to be deleted from the file history.
  */
 function locale_translation_file_history_delete($projects = [], $langcodes = []) {
-  $query = db_delete('locale_file');
+  $query = \Drupal::database()->delete('locale_file');
   if (!empty($projects)) {
     $query->condition('project', $projects, 'IN');
   }
diff --git a/core/modules/path/path.api.php b/core/modules/path/path.api.php
index 6a69f355d9..911847f47b 100644
--- a/core/modules/path/path.api.php
+++ b/core/modules/path/path.api.php
@@ -56,7 +56,7 @@ function hook_path_update($path) {
  * @see \Drupal\Core\Path\AliasStorageInterface::delete()
  */
 function hook_path_delete($path) {
-  db_delete('mytable')
+  \Drupal::database()->delete('mytable')
     ->condition('pid', $path['pid'])
     ->execute();
 }
diff --git a/core/modules/search/search.module b/core/modules/search/search.module
index c7707fd51c..42ccff1908 100644
--- a/core/modules/search/search.module
+++ b/core/modules/search/search.module
@@ -140,8 +140,9 @@ function search_preprocess_block(&$variables) {
  *   omitted, all items matching $sid and $type are cleared.
  */
 function search_index_clear($type = NULL, $sid = NULL, $langcode = NULL) {
-  $query_index = db_delete('search_index');
-  $query_dataset = db_delete('search_dataset');
+  $connection = \Drupal::database();
+  $query_index = $connection->delete('search_index');
+  $query_dataset = $connection->delete('search_dataset');
   if ($type) {
     $query_index->condition('type', $type);
     $query_dataset->condition('type', $type);
@@ -211,6 +212,7 @@ function search_cron() {
  * up to date (even if cron times out or otherwise fails).
  */
 function search_update_totals() {
+  $connection = \Drupal::database();
   // Update word IDF (Inverse Document Frequency) counts for new/changed words.
   foreach (search_dirty() as $word => $dummy) {
     // Get total count
@@ -231,7 +233,7 @@ function search_update_totals() {
     $or->condition('word', $word->realword);
   }
   if (count($or) > 0) {
-    db_delete('search_total')
+    $connection->delete('search_total')
       ->condition($or)
       ->execute();
   }
diff --git a/core/modules/shortcut/src/ShortcutSetStorage.php b/core/modules/shortcut/src/ShortcutSetStorage.php
index ecb3472c0c..899032e1e1 100644
--- a/core/modules/shortcut/src/ShortcutSetStorage.php
+++ b/core/modules/shortcut/src/ShortcutSetStorage.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Database\Connection;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -24,6 +25,13 @@ class ShortcutSetStorage extends ConfigEntityStorage implements ShortcutSetStora
    */
   protected $moduleHandler;
 
+  /**
+   * The database connection.
+   *
+   * @var \Drupal\Core\Database\Connection
+   */
+  protected $connection;
+
   /**
    * Constructs a ShortcutSetStorageController object.
    *
@@ -39,11 +47,14 @@ class ShortcutSetStorage extends ConfigEntityStorage implements ShortcutSetStora
    *   The language manager.
    * @param \Drupal\Core\Cache\MemoryCache\MemoryCacheInterface $memory_cache
    *   The memory cache.
+   * @param \Drupal\Core\Database\Connection $connection
+   *   The database connection.
    */
-  public function __construct(EntityTypeInterface $entity_info, ConfigFactoryInterface $config_factory, UuidInterface $uuid_service, ModuleHandlerInterface $module_handler, LanguageManagerInterface $language_manager, MemoryCacheInterface $memory_cache) {
+  public function __construct(EntityTypeInterface $entity_info, ConfigFactoryInterface $config_factory, UuidInterface $uuid_service, ModuleHandlerInterface $module_handler, LanguageManagerInterface $language_manager, MemoryCacheInterface $memory_cache, Connection $connection) {
     parent::__construct($entity_info, $config_factory, $uuid_service, $language_manager, $memory_cache);
 
     $this->moduleHandler = $module_handler;
+    $this->connection = $connection;
   }
 
   /**
@@ -56,7 +67,8 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
       $container->get('uuid'),
       $container->get('module_handler'),
       $container->get('language_manager'),
-      $container->get('entity.memory_cache')
+      $container->get('entity.memory_cache'),
+      $container->get('database')
     );
   }
 
@@ -66,7 +78,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
   public function deleteAssignedShortcutSets(ShortcutSetInterface $entity) {
     // First, delete any user assignments for this set, so that each of these
     // users will go back to using whatever default set applies.
-    db_delete('shortcut_set_users')
+    $this->connection->delete('shortcut_set_users')
       ->condition('set_name', $entity->id())
       ->execute();
   }
@@ -86,7 +98,7 @@ public function assignUser(ShortcutSetInterface $shortcut_set, $account) {
    * {@inheritdoc}
    */
   public function unassignUser($account) {
-    $deleted = db_delete('shortcut_set_users')
+    $deleted = $this->connection->delete('shortcut_set_users')
       ->condition('uid', $account->id())
       ->execute();
     return (bool) $deleted;
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index 179487d3f0..92eb81a897 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -587,7 +587,7 @@ function taxonomy_node_predelete(EntityInterface $node) {
  */
 function taxonomy_delete_node_index(EntityInterface $node) {
   if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) {
-    db_delete('taxonomy_index')->condition('nid', $node->id())->execute();
+    \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute();
   }
 }
 
@@ -597,7 +597,7 @@ function taxonomy_delete_node_index(EntityInterface $node) {
 function taxonomy_taxonomy_term_delete(Term $term) {
   if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) {
     // Clean up the {taxonomy_index} table when terms are deleted.
-    db_delete('taxonomy_index')->condition('tid', $term->id())->execute();
+    \Drupal::database()->delete('taxonomy_index')->condition('tid', $term->id())->execute();
   }
 }
 
diff --git a/core/modules/tracker/tests/src/Functional/TrackerTest.php b/core/modules/tracker/tests/src/Functional/TrackerTest.php
index 75b7b5cde7..37c3602318 100644
--- a/core/modules/tracker/tests/src/Functional/TrackerTest.php
+++ b/core/modules/tracker/tests/src/Functional/TrackerTest.php
@@ -373,9 +373,10 @@ public function testTrackerCronIndexing() {
     \Drupal::state()->set('tracker.index_nid', 4);
 
     // Clear the current tracker tables and rebuild them.
-    db_delete('tracker_node')
+    $connection = \Drupal::database();
+    $connection->delete('tracker_node')
       ->execute();
-    db_delete('tracker_user')
+    $connection->delete('tracker_user')
       ->execute();
     tracker_cron();
 
diff --git a/core/modules/tracker/tracker.module b/core/modules/tracker/tracker.module
index dadefecabc..540d85924f 100644
--- a/core/modules/tracker/tracker.module
+++ b/core/modules/tracker/tracker.module
@@ -61,10 +61,10 @@ function tracker_cron() {
       $changed = _tracker_calculate_changed($node);
 
       // Remove existing data for this node.
-      db_delete('tracker_node')
+      \Drupal::database()->delete('tracker_node')
         ->condition('nid', $nid)
         ->execute();
-      db_delete('tracker_user')
+      \Drupal::database()->delete('tracker_user')
         ->condition('nid', $nid)
         ->execute();
 
@@ -199,10 +199,11 @@ function tracker_node_update(NodeInterface $node, $arg = 0) {
  * Deletes tracking information for a node.
  */
 function tracker_node_predelete(EntityInterface $node, $arg = 0) {
-  db_delete('tracker_node')
+  $connection = \Drupal::database();
+  $connection->delete('tracker_node')
     ->condition('nid', $node->id())
     ->execute();
-  db_delete('tracker_user')
+  $connection->delete('tracker_user')
     ->condition('nid', $node->id())
     ->execute();
 }
@@ -322,6 +323,7 @@ function _tracker_calculate_changed($node) {
  */
 function _tracker_remove($nid, $uid = NULL, $changed = NULL) {
   $node = Node::load($nid);
+  $connection = \Drupal::database();
 
   // The user only keeps their subscription if the node exists.
   if ($node) {
@@ -343,7 +345,7 @@ function _tracker_remove($nid, $uid = NULL, $changed = NULL) {
 
     // If we haven't found a reason to keep the user's subscription, delete it.
     if (!$keep_subscription) {
-      db_delete('tracker_user')
+      $connection->delete('tracker_user')
         ->condition('nid', $nid)
         ->condition('uid', $uid)
         ->execute();
@@ -381,10 +383,10 @@ function _tracker_remove($nid, $uid = NULL, $changed = NULL) {
   }
   else {
     // If the node doesn't exist, remove everything.
-    db_delete('tracker_node')
+    $connection->delete('tracker_node')
       ->condition('nid', $nid)
       ->execute();
-    db_delete('tracker_user')
+    $connection->delete('tracker_user')
       ->condition('nid', $nid)
       ->execute();
   }
diff --git a/core/tests/Drupal/KernelTests/Core/Config/Storage/DatabaseStorageTest.php b/core/tests/Drupal/KernelTests/Core/Config/Storage/DatabaseStorageTest.php
index 0aecc72b8f..8dee85c56b 100644
--- a/core/tests/Drupal/KernelTests/Core/Config/Storage/DatabaseStorageTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Config/Storage/DatabaseStorageTest.php
@@ -38,7 +38,7 @@ protected function update($name, $data) {
   }
 
   protected function delete($name) {
-    db_delete('config')->condition('name', $name)->execute();
+    \Drupal::database()->delete('config')->condition('name', $name)->execute();
   }
 
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Database/DatabaseLegacyTest.php b/core/tests/Drupal/KernelTests/Core/Database/DatabaseLegacyTest.php
index 411338d64d..5b10c04455 100644
--- a/core/tests/Drupal/KernelTests/Core/Database/DatabaseLegacyTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Database/DatabaseLegacyTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\KernelTests\Core\Database;
 
+use Drupal\Core\Database\Query\Delete;
 use Drupal\Core\Database\Transaction;
 
 /**
@@ -65,4 +66,13 @@ public function testDbTransaction() {
     $this->assertInstanceOf(Transaction::class, db_transaction());
   }
 
+  /**
+   * Tests deprecation of the db_delete() function.
+   *
+   * @expectedDeprecation db_delete is deprecated in Drupal 8.0.x and will be removed before Drupal 9.0.0. Instead, get a database connection injected into your service from the container and call delete() on it. For example, $injected_database->delete($table, $options). See https://www.drupal.org/node/2993033
+   */
+  public function testDbDelete() {
+    $this->assertInstanceOf(Delete::class, db_delete('test'));
+  }
+
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Database/DeleteTruncateTest.php b/core/tests/Drupal/KernelTests/Core/Database/DeleteTruncateTest.php
index ad1d050364..86ced24839 100644
--- a/core/tests/Drupal/KernelTests/Core/Database/DeleteTruncateTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Database/DeleteTruncateTest.php
@@ -21,13 +21,14 @@ class DeleteTruncateTest extends DatabaseTestBase {
    * Confirms that we can use a subselect in a delete successfully.
    */
   public function testSubselectDelete() {
+    $connection = \Drupal::database();
     $num_records_before = db_query('SELECT COUNT(*) FROM {test_task}')->fetchField();
     $pid_to_delete = db_query("SELECT * FROM {test_task} WHERE task = 'sleep'")->fetchField();
 
     $subquery = db_select('test', 't')
       ->fields('t', ['id'])
       ->condition('t.id', [$pid_to_delete], 'IN');
-    $delete = db_delete('test_task')
+    $delete = $connection->delete('test_task')
       ->condition('task', 'sleep')
       ->condition('pid', $subquery, 'IN');
 
@@ -42,9 +43,10 @@ public function testSubselectDelete() {
    * Confirms that we can delete a single record successfully.
    */
   public function testSimpleDelete() {
+    $connection = \Drupal::database();
     $num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
 
-    $num_deleted = db_delete('test')
+    $num_deleted = $connection->delete('test')
       ->condition('id', 1)
       ->execute();
     $this->assertIdentical($num_deleted, 1, 'Deleted 1 record.');
@@ -148,9 +150,10 @@ public function testTruncateTransactionRollback() {
    * Confirms that we can delete a single special column name record successfully.
    */
   public function testSpecialColumnDelete() {
+    $connection = \Drupal::database();
     $num_records_before = db_query('SELECT COUNT(*) FROM {test_special_columns}')->fetchField();
 
-    $num_deleted = db_delete('test_special_columns')
+    $num_deleted = $connection->delete('test_special_columns')
       ->condition('id', 1)
       ->execute();
     $this->assertIdentical($num_deleted, 1, 'Deleted 1 special column record.');
