DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 

(mysql.info) innodb-deadlocks

Info Catalog (mysql.info) innodb-deadlock-detection (mysql.info) innodb-transaction-model
 
 14.2.10.11 How to Cope with Deadlocks
 .....................................
 
 Deadlocks are a classic problem in transactional databases, but they
 are not dangerous unless they are so frequent that you cannot run
 certain transactions at all. Normally, you must write your applications
 so that they are always prepared to re-issue a transaction if it gets
 rolled back because of a deadlock.
 
 `InnoDB' uses automatic row-level locking. You can get deadlocks even
 in the case of transactions that just insert or delete a single row.
 That is because these operations are not really `atomic'; they
 automatically set locks on the (possibly several) index records of the
 row inserted or deleted.
 
 You can cope with deadlocks and reduce the likelihood of their
 occurrence with the following techniques:
 
    * Use `SHOW ENGINE INNODB STATUS' to determine the cause of the
      latest deadlock. That can help you to tune your application to
      avoid deadlocks.
 
    * Always be prepared to re-issue a transaction if it fails due to
      deadlock. Deadlocks are not dangerous. Just try again.
 
    * Commit your transactions often. Small transactions are less prone
      to collision.
 
    * If you are using locking reads (`SELECT ... FOR UPDATE' or `...
      LOCK IN SHARE MODE'), try using a lower isolation level such as
      `READ COMMITTED'.
 
    * Access your tables and rows in a fixed order. Then transactions
      form well-defined queues and do not deadlock.
 
    * Add well-chosen indexes to your tables. Then your queries need to
      scan fewer index records and consequently set fewer locks. Use
      `EXPLAIN SELECT' to determine which indexes the MySQL server
      regards as the most appropriate for your queries.
 
    * Use less locking. If you can afford to allow a `SELECT' to return
      data from an old snapshot, do not add the clause `FOR UPDATE' or
      `LOCK IN SHARE MODE' to it. Using the `READ COMMITTED' isolation
      level is good here, because each consistent read within the same
      transaction reads from its own fresh snapshot.
 
    * If nothing else helps, serialize your transactions with
      table-level locks. The correct way to use `LOCK TABLES' with
      transactional tables, such as `InnoDB' tables, is to set
      `AUTOCOMMIT = 0' and not to call `UNLOCK TABLES' until after you
      commit the transaction explicitly. For example, if you need to
      write to table `t1' and read from table `t2', you can do this:
 
           SET AUTOCOMMIT=0;
           LOCK TABLES t1 WRITE, t2 READ, ...;
           ... DO SOMETHING WITH TABLES T1 AND T2 HERE ...
           COMMIT;
           UNLOCK TABLES;
 
      Table-level locks make your transactions queue nicely, and
      deadlocks are avoided.
 
    * Another way to serialize transactions is to create an auxiliary
      `semaphore' table that contains just a single row. Have each
      transaction update that row before accessing other tables. In that
      way, all transactions happen in a serial fashion. Note that the
      `InnoDB' instant deadlock detection algorithm also works in this
      case, because the serializing lock is a row-level lock. With MySQL
      table-level locks, the timeout method must be used to resolve
      deadlocks.
 
    * In applications that use the `LOCK TABLES' command, MySQL does not
      set `InnoDB' table locks if `AUTOCOMMIT=1'.
 
Info Catalog (mysql.info) innodb-deadlock-detection (mysql.info) innodb-transaction-model
automatically generated byinfo2html