phacility/phabricator · warning · AphrontDeadlockQueryException

1213

1213

Error message

#%d: %s

What it means

MySQL errno 1213 'Deadlock found when trying to get lock', translated into AphrontDeadlockQueryException. Two transactions each hold locks the other needs; InnoDB detects the cycle and sacrifices one with this error. Deadlocks are normal in concurrent OLTP systems — the documented remedy is to roll back and retry the whole transaction, ideally in a new transaction. Phabricator marks this exception class as retryable and its workers re-run such queries.

Source

Thrown at src/infrastructure/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php:338

    }
    $this->throwQueryCodeException($errno, $error);
  }

  private function throwCommonException($errno, $error) {
    $message = pht('#%d: %s', $errno, $error);

    switch ($errno) {
      case 2013: // Connection Dropped
        throw new AphrontConnectionLostQueryException($message);
      case 2006: // Gone Away
        $more = pht(
          'This error may occur if your configured MySQL "wait_timeout" or '.
          '"max_allowed_packet" values are too small. This may also indicate '.
          'that something used the MySQL "KILL <process>" command to kill '.
          'the connection running the query.');
        throw new AphrontConnectionLostQueryException("{$message}\n\n{$more}");
      case 1213: // Deadlock
        throw new AphrontDeadlockQueryException($message);
      case 1205: // Lock wait timeout exceeded
        throw new AphrontLockTimeoutQueryException($message);
      case 1062: // Duplicate Key
        // NOTE: In some versions of MySQL we get a key name back here, but
        // older versions just give us a key index ("key 2") so it's not
        // portable to parse the key out of the error and attach it to the
        // exception.
        throw new AphrontDuplicateKeyQueryException($message);
      case 1044: // Access denied to database
      case 1142: // Access denied to table
      case 1143: // Access denied to column
      case 1227: // Access denied (e.g., no SUPER for SHOW SLAVE STATUS).

        // See T13622. Try to help users figure out that this is a GRANT
        // problem.

        $more = pht(
          'This error usually indicates that you need to "GRANT" the '.

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Retry the transaction — this is the canonical fix; Phabricator daemons already retry deadlock exceptions automatically
  2. In custom scripts, wrap the whole unit of work and re-run it on AphrontDeadlockQueryException (new transaction, small backoff)
  3. Access rows in a consistent global order (e.g. ORDER BY id ... FOR UPDATE) to shrink deadlock windows
  4. Keep transactions short: avoid holding locks across slow computation or external calls

Example fix

// before: single attempt
$object->openTransaction(12); /* ...writes... */ $object->saveTransaction();

// after: retry the whole transaction on deadlock
$attempt = 0;
do {
  try {
    $object->openTransaction(12);
    /* ...writes... */
    $object->saveTransaction();
    break;
  } catch (AphrontDeadlockQueryException $ex) {
    $object->killTransaction();
    usleep(50000 * ++$attempt); // backoff 50ms, 100ms, ...
  }
} while ($attempt < 5);
Defensive patterns

Strategy: retry

Try / catch

try {
  $object->openTransaction(12);
  /* ...writes... */
  $object->saveTransaction();
} catch (AphrontDeadlockQueryException $ex) {
  $object->killTransaction();
  usleep(100000); // small backoff, then retry the WHOLE transaction
}

Prevention

When it happens

Trigger: Two workers updating overlapping rows in opposite orders (e.g. editing the same task's subpriority/transactions concurrently); batch scripts locking many rows in inconsistent order; transactions that read-then-write on the same keys racing each other.

Common situations: Bulk scripts adjusting task subpriorities or project memberships while users edit in the UI; heavy daemon activity on holidays/peak load; multiple queue workers processing tasks touching the same objects.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/75ef1b2365b24ac8. Report an issue: GitHub.