{"record":{"id":"75e1392c8e20ab67","repo":"phacility/phabricator","slug":"1205","errorCode":"1205","errorMessage":"#%d: %s","messagePattern":"#%d: %s","errorType":"exception","errorClass":"AphrontLockTimeoutQueryException","httpStatus":null,"severity":"warning","filePath":"src/infrastructure/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php","lineNumber":340,"sourceCode":"  }\n\n  private function throwCommonException($errno, $error) {\n    $message = pht('#%d: %s', $errno, $error);\n\n    switch ($errno) {\n      case 2013: // Connection Dropped\n        throw new AphrontConnectionLostQueryException($message);\n      case 2006: // Gone Away\n        $more = pht(\n          'This error may occur if your configured MySQL \"wait_timeout\" or '.\n          '\"max_allowed_packet\" values are too small. This may also indicate '.\n          'that something used the MySQL \"KILL <process>\" command to kill '.\n          'the connection running the query.');\n        throw new AphrontConnectionLostQueryException(\"{$message}\\n\\n{$more}\");\n      case 1213: // Deadlock\n        throw new AphrontDeadlockQueryException($message);\n      case 1205: // Lock wait timeout exceeded\n        throw new AphrontLockTimeoutQueryException($message);\n      case 1062: // Duplicate Key\n        // NOTE: In some versions of MySQL we get a key name back here, but\n        // older versions just give us a key index (\"key 2\") so it's not\n        // portable to parse the key out of the error and attach it to the\n        // exception.\n        throw new AphrontDuplicateKeyQueryException($message);\n      case 1044: // Access denied to database\n      case 1142: // Access denied to table\n      case 1143: // Access denied to column\n      case 1227: // Access denied (e.g., no SUPER for SHOW SLAVE STATUS).\n\n        // See T13622. Try to help users figure out that this is a GRANT\n        // problem.\n\n        $more = pht(\n          'This error usually indicates that you need to \"GRANT\" the '.\n          'MySQL user additional permissions. See \"GRANT\" in the MySQL '.\n          'manual for help.');","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/infrastructure/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php#L322-L358","documentation":"MySQL errno 1205 'Lock wait timeout exceeded', translated into AphrontLockTimeoutQueryException. Unlike a deadlock, this fires when a transaction waited longer than innodb_lock_wait_timeout (default 50s) for a lock held by ANOTHER still-running transaction — typically a long-running transaction, a stuck connection holding row locks, or a metadata lock from a pending DDL. It is retriable in the sense that retrying once the lock holder finishes usually succeeds.","triggerScenarios":"A long transaction (bulk edit, migration, paused debugger session) holds row locks while other writers touch the same rows; a schema change (ALTER TABLE) waiting on a metadata lock blocks writers behind it; a forgotten 'START TRANSACTION' in a manual session pinning locks.","commonSituations":"Long-running admin scripts updating thousands of objects; bin/storage upgrade/adjust running during traffic; a developer's open MySQL client with an uncommitted transaction blocking production writers.","solutions":["Find and finish/kill the blocking transaction: SHOW ENGINE INNODB STATUS, SELECT ... FROM information_schema.innodb_trx ordered by trx_started","Retry the failed write once the blocker is gone","Shrink the offending transaction — batch large updates into smaller commits so locks are held briefly","Schedule DDL migrations during low traffic to avoid metadata-lock pileups","Optionally raise innodb_lock_wait_timeout if legitimate long lock waits are expected"],"exampleFix":"-- diagnose: find long-running transactions holding locks\nSELECT trx_id, trx_started, trx_mysql_thread_id\n  FROM information_schema.innodb_trx\n  ORDER BY trx_started LIMIT 5;\n\n-- then either commit/kill the blocker, or retry the timed-out write once it clears","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  $object->openTransaction(12);\n  /* ...writes... */\n  $object->saveTransaction();\n} catch (AphrontLockTimeoutQueryException $ex) {\n  $object->killTransaction();\n  // first identify/finish the blocking transaction, then retry once\n}","preventionTips":["Watch information_schema.innodb_trx for long-running transactions when these appear","Batch large bulk-edits into small committed chunks so locks are released quickly","Run schema migrations outside peak traffic to avoid metadata-lock queues","Close uncommitted manual MySQL sessions before running bulk operations"],"tags":["database","mysql","lock-timeout","concurrency","phabricator"],"backgroundTag":"mysql-lock-wait-timeout","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}