title: mysql CREATE temporary table + Transaction causes deadlock
body: <p>I have the complex query that creates a temporary table that can take 5 seconds to run or more. This seems to be causing a deadlock when running another transaction on similar tables at the same time. I cannot reproduce locally, but on production I am able to have it happen 1 time every few days. (I logged the mysql errors)</p>
  
  <p>The query is pretty complicated (shown at bottom of page); but you don't need to understand the logic; just that it selects from a bunch of tables and joins and can take awhile to run.</p>
  
  <p>I also have a transaction that inserts into many of the same tables. I get a mysql error occasionally <strong><code>1213: Deadlock found when trying to get lock; try restarting transaction.</code></strong></p>
  
  <p>Here is pseudocode for the transaction </p>
  
  <pre><code>START TRANSACTION
  INSERT INTO phppos_sales
  INSERT MANY RECORDS INTO phppos_sales_items
  INSERT MANY RECORDS INTO phppos_sales_items_taxes
  INSERT MANY RECORDS INTO phppos_sales_payments
  END TRANSACTION
  </code></pre>
  
  <p>How do I go about resolving this deadlock? I tried changing <a href="http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html" rel="noreferrer">isolation level</a> to READ UNCOMMITTED but mysql settings wouldn't allow for this; and I need to make this work in a variety of environments where I don't have control of the server.</p>
  
  <p>ERROR when changing isolation level:</p>
  
  <blockquote>
    <p>Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine
    limited to row-based logging. InnoDB is limited to row-logging when
    transaction isolation level is READ COMMITTED or READ UNCOMMITTED.</p>
  </blockquote>
  
  <p>INNODB ENGINE STATUS:</p>
  
  <pre><code>mysql&gt; SHOW ENGINE INNODB STATUS;
  | Type   | Name | Status                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
  | InnoDB |      | 
  =====================================
  140520 12:00:17 INNODB MONITOR OUTPUT
  =====================================
  Per second averages calculated from the last 15 seconds
  -----------------
  BACKGROUND THREAD
  -----------------
  srv_master_thread loops: 1766819 1_second, 1766816 sleeps, 167043 10_second, 100947 background, 100945 flush
  srv_master_thread log flush and writes: 1776023
  ----------
  SEMAPHORES
  ----------
  OS WAIT ARRAY INFO: reservation count 236559, signal count 288374
  Mutex spin waits 546890, rounds 1796579, OS waits 33216
  RW-shared spins 205374, rounds 5519210, OS waits 176937
  RW-excl spins 5661, rounds 841678, OS waits 23933
  Spin rounds per wait: 3.29 mutex, 26.87 RW-shared, 148.68 RW-excl
  ------------------------
  LATEST FOREIGN KEY ERROR
  ------------------------
  140520 11:27:44 Transaction:
  TRANSACTION 86D125F, ACTIVE 0 sec inserting
  mysql tables in use 1, locked 1
  15 lock struct(s), heap size 3112, 6 row lock(s), undo log entries 2
  MySQL thread id 1910245, OS thread handle 0x7fbf0042e700, query id 56114114 php-pos-web 10.181.16.33 phppoint update
  INSERT INTO `phppos_sales_items_taxes` (`sale_id`, `item_id`, `line`, `name`, `percent`, `cumulative`) VALUES (11763, 1115, 3, 'PST', '8.000', '0')
  Foreign key constraint fails for table `phppoint_fatpanda`.`phppos_sales_items_taxes`:
  ,
    CONSTRAINT `phppos_sales_items_taxes_ibfk_1` FOREIGN KEY (`sale_id`) REFERENCES `phppos_sales_items` (`sale_id`)
  Trying to add in child table, in index `PRIMARY` tuple:
  DATA TUPLE: 8 fields;
   0: len 4; hex 80002df3; asc   - ;;
   1: len 4; hex 8000045b; asc    [;;
   2: len 4; hex 80000003; asc     ;;
   3: len 3; hex 505354; asc PST;;
   4: len 8; hex 8000000000080000; asc         ;;
   5: len 6; hex 0000086d125f; asc    m _;;
   6: len 7; hex 00000000000000; asc        ;;
   7: len 4; hex 80000000; asc     ;;
  
  But in parent table `phppoint_fatpanda`.`phppos_sales_items`, in index `PRIMARY`,
  the closest match we can find is record:
  PHYSICAL RECORD: n_fields 11; compact format; info bits 0
   0: len 4; hex 80002df1; asc   - ;;
   1: len 4; hex 8000049a; asc     ;;
   2: len 4; hex 80000001; asc     ;;
   3: len 6; hex 0000086cfd29; asc    l );;
   4: len 7; hex f400000216012c; asc       ,;;
   5: len 0; hex ; asc ;;
   6: len 0; hex ; asc ;;
   7: len 11; hex 8000000000010000000000; asc            ;;
   8: len 11; hex 8000000000100000000000; asc            ;;
   9: len 11; hex 80000000002d0000000000; asc      -     ;;
   10: len 4; hex 80000000; asc     ;;
  
  ------------------------
  LATEST DETECTED DEADLOCK
  ------------------------
  140520 11:27:44
  *** (1) TRANSACTION:
  TRANSACTION 86D11A3, ACTIVE 2 sec fetching rows
  mysql tables in use 9, locked 9
  LOCK WAIT 364 lock struct(s), heap size 47544, 80177 row lock(s)
  MySQL thread id 1910243, OS thread handle 0x7fbeb2090700, query id 56113840 10.181.26.42 phppoint Copying to tmp table
  
  CREATE TEMPORARY TABLE phppos_sales_items_temp
          (SELECT phppos_sales.deleted as deleted,phppos_sales.deleted_by as deleted_by, sale_time, date(sale_time) as sale_date, phppos_sales_items.sale_id, comment,payment_type, customer_id, employee_id, 
          phppos_items.item_id, NULL as item_kit_id, supplier_id, quantity_purchased, item_cost_price, item_unit_price, category, 
          discount_percent, (item_unit_price*quantity_purchased-item_unit_price*quantity_purchased*discount_percent/100) as subtotal,
          phppos_sales_items.line as line, serialnumber, phppos_sales_items.description as description,
          (item_unit_price*quantity_purchased-item_unit_price*quantity_purchased*discount_percent/100)+(item_unit_price*quantity_purchased-item_unit_price*quantity_purchased*discount_percent/100)*(SUM(CASE WHEN cumulative != 1 THEN percent ELSE 0 END)/100) 
          +(((item_unit_price*quantity_purchased-item_unit_price*quanti
  *** (1) WAITING FOR THIS LOCK TO BE GRANTED:
  RECORD LOCKS space id 454941 page no 114 n bits 408 index `location_id` of table `phppoint_fatpanda`.`phppos_sales` trx id 86D11A3 lock mode S waiting
  Record lock, heap no 335 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
   0: len 4; hex 80000001; asc     ;;
   1: len 4; hex 80002df3; asc   - ;;
  
  *** (2) TRANSACTION:
  TRANSACTION 86D125D, ACTIVE 0 sec inserting
  mysql tables in use 1, locked 1
  23 lock struct(s), heap size 3112, 12 row lock(s), undo log entries 10
  MySQL thread id 1910245, OS thread handle 0x7fbf0042e700, query id 56114091 php-pos-web 10.181.16.33 phppoint update
  
  INSERT INTO `phppos_sales_items_taxes` (`sale_id`, `item_id`, `line`, `name`, `percent`, `cumulative`) VALUES (11763, 1178, 2, 'GST', '5.000', '0')
  *** (2) HOLDS THE LOCK(S):
  RECORD LOCKS space id 454941 page no 114 n bits 408 index `location_id` of table `phppoint_fatpanda`.`phppos_sales` trx id 86D125D lock_mode X locks rec but not gap
  Record lock, heap no 335 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
   0: len 4; hex 80000001; asc     ;;
   1: len 4; hex 80002df3; asc   - ;;
  
  *** (2) WAITING FOR THIS LOCK TO BE GRANTED:
  RECORD LOCKS space id 454945 page no 386 n bits 288 index `PRIMARY` of table `phppoint_fatpanda`.`phppos_sales_items_taxes` trx id 86D125D lock_mode X insert intention waiting
  Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
   0: len 8; hex 73757072656d756d; asc supremum;;
  
  *** WE ROLL BACK TRANSACTION (2)
  ------------
  TRANSACTIONS
  ------------
  Trx id counter 86E47F7
  Purge done for trx's n:o &lt; 86E45C0 undo n:o &lt; 0
  History list length 1418
  LIST OF TRANSACTIONS FOR EACH SESSION:
  ---TRANSACTION 86E47F6, not started
  MySQL thread id 1913171, OS thread handle 0x7fbeb2090700, query id 56205829 10.181.26.42 phppoint
  ---TRANSACTION 0, not started
  MySQL thread id 1913095, OS thread handle 0x7fbf005b4700, query id 56205830 localhost root
  SHOW ENGINE INNODB STATUS
  --------
  FILE I/O
  --------
  I/O thread 0 state: waiting for completed aio requests (insert buffer thread)
  I/O thread 1 state: waiting for completed aio requests (log thread)
  I/O thread 2 state: waiting for completed aio requests (read thread)
  I/O thread 3 state: waiting for completed aio requests (read thread)
  I/O thread 4 state: waiting for completed aio requests (read thread)
  I/O thread 5 state: waiting for completed aio requests (read thread)
  I/O thread 6 state: waiting for completed aio requests (write thread)
  I/O thread 7 state: waiting for completed aio requests (write thread)
  I/O thread 8 state: waiting for completed aio requests (write thread)
  I/O thread 9 state: waiting for completed aio requests (write thread)
  Pending normal aio reads: 0 [0, 0, 0, 0] , aio writes: 0 [0, 0, 0, 0] ,
   ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
  Pending flushes (fsync) log: 0; buffer pool: 0
  3599456 OS file reads, 9300371 OS file writes, 3988632 OS fsyncs
  0.27 reads/s, 16384 avg bytes/read, 13.07 writes/s, 7.27 fsyncs/s
  -------------------------------------
  INSERT BUFFER AND ADAPTIVE HASH INDEX
  -------------------------------------
  Ibuf: size 1, free list len 84, seg size 86, 55915 merges
  merged operations:
   insert 68506, delete mark 4761, delete 38
  discarded operations:
   insert 0, delete mark 0, delete 0
  Hash table size 2212699, node heap has 751 buffer(s)
  5050.86 hash searches/s, 624.09 non-hash searches/s
  ---
  LOG
  ---
  Log sequence number 184365806376
  Log flushed up to   184365806376
  Last checkpoint at  184365791715
  0 pending log writes, 0 pending chkp writes
  2149282 log i/o's done, 3.47 log i/o's/second
  ----------------------
  BUFFER POOL AND MEMORY
  ----------------------
  Total memory allocated 1098907648; in additional pool allocated 0
  Dictionary memory allocated 62951505
  Buffer pool size   65536
  Free buffers       1
  Database pages     64784
  Old database pages 23894
  Modified db pages  88
  Pending reads 0
  Pending writes: LRU 0, flush list 0, single page 0
  Pages made young 4073451, not young 0
  0.07 youngs/s, 0.00 non-youngs/s
  Pages read 3592230, created 1542046, written 6130789
  0.27 reads/s, 18.00 creates/s, 6.40 writes/s
  Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
  Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
  LRU len: 64784, unzip_LRU len: 0
  I/O sum[382]:cur[0], unzip sum[0]:cur[0]
  --------------
  ROW OPERATIONS
  --------------
  0 queries inside InnoDB, 0 queries in queue
  1 read views open inside InnoDB
  Main thread process no. 15866, id 140457065543424, state: sleeping
  Number of rows inserted 77431960, updated 1673031, deleted 160450, read 4825684197
  1103.93 inserts/s, 2.53 updates/s, 0.00 deletes/s, 7772.15 reads/s
  ----------------------------
  END OF INNODB MONITOR OUTPUT
  ============================
   |
  +-------
  </code></pre>
  
  <p>QUERY THIS IS PART OF DEADLOCK: (Along with transaction above)</p>
  
  <pre class="lang-sql prettyprint-override"><code>CREATE temporary TABLE phppos_sales_items_temp 
    (SELECT 
    phppos_sales.deleted                                              AS deleted, 
            phppos_sales.deleted_by                                   AS deleted_by, 
            sale_time, 
            Date(sale_time)                                           AS sale_date, 
            phppos_sales_items.sale_id, 
            comment, 
            payment_type, 
            customer_id, 
            employee_id, 
            phppos_items.item_id, 
            NULL                                                       AS item_kit_id, 
            supplier_id, 
            quantity_purchased, 
            item_cost_price, 
            item_unit_price, 
            category, 
            discount_percent, 
            ( item_unit_price * quantity_purchased - 
              item_unit_price * quantity_purchased * 
              discount_percent / 100 ) AS subtotal, 
            phppos_sales_items.line                                     AS line, 
            serialnumber, 
            phppos_sales_items.description                              AS description, 
            ( item_unit_price * quantity_purchased - 
              item_unit_price * quantity_purchased * 
              discount_percent / 100 ) + ( 
            item_unit_price * quantity_purchased - 
            item_unit_price * quantity_purchased * 
            discount_percent 
            / 100 ) * ( Sum(CASE 
                              WHEN cumulative != 1 THEN percent 
                              ELSE 0 
                            end) / 100 ) + ( ( ( 
            item_unit_price * quantity_purchased 
            - 
            item_unit_price * quantity_purchased 
            * 
            discount_percent / 100 ) * ( 
                                             Sum(CASE 
                                                   WHEN cumulative != 1 THEN 
                                                   percent 
                                                   ELSE 0 
                                                 end) / 100 ) + ( 
                                             item_unit_price * quantity_purchased 
                                             - 
                                                              item_unit_price * 
                                                              quantity_purchased 
                                                              * 
                                                              discount_percent / 
                                                              100 
                                                                ) 
                                       ) 
                                             * ( Sum(CASE 
                                                                              WHEN 
                                                     cumulative = 1 THEN percent 
                                                                              ELSE 
                                                     0 
                                                                              end) 
                                               ) 
                                             / 100 ) 
                                                                         AS total, 
            ( item_unit_price * quantity_purchased - 
              item_unit_price * quantity_purchased * 
              discount_percent / 100 ) * ( 
            Sum(CASE 
                  WHEN cumulative != 1 THEN percent 
                  ELSE 0 
                end) / 100 ) + ( ( ( item_unit_price * quantity_purchased - 
                                     item_unit_price * quantity_purchased * 
                                     discount_percent / 100 ) * ( Sum( 
                                                          CASE 
                                                            WHEN cumulative != 1 
                                                          THEN 
                                                            percent 
                                                            ELSE 0 
                                                          end) / 100 ) + ( 
                                   item_unit_price * quantity_purchased 
                                   - 
                                   item_unit_price * quantity_purchased 
                                   * 
                                   discount_percent / 100 ) ) * ( Sum( 
                                   CASE 
                                   WHEN cumulative = 1 THEN percent 
                                   ELSE 0 
                                   end) ) / 100 )          AS tax, 
            ( item_unit_price * quantity_purchased - 
              item_unit_price * quantity_purchased * 
              discount_percent / 100 ) - ( 
            item_cost_price * quantity_purchased )                      AS profit 
     FROM   phppos_sales_items 
            INNER JOIN phppos_sales 
                    ON phppos_sales_items.sale_id = phppos_sales.sale_id 
            INNER JOIN phppos_items 
                    ON phppos_sales_items.item_id = phppos_items.item_id 
            LEFT OUTER JOIN phppos_suppliers 
                         ON phppos_items.supplier_id = phppos_suppliers.person_id 
            LEFT OUTER JOIN phppos_sales_items_taxes 
                         ON phppos_sales_items.sale_id = 
                            phppos_sales_items_taxes.sale_id 
                            AND phppos_sales_items.item_id = 
                                phppos_sales_items_taxes.item_id 
                            AND phppos_sales_items.line = 
                                phppos_sales_items_taxes.line 
     WHERE  sale_time BETWEEN "2014-04-01 00:00:00" AND "2014-04-30 23:59:59" 
            AND phppos_sales.location_id = '1' 
            AND phppos_sales.store_account_payment = 0 
     GROUP  BY sale_id, 
               item_id, 
               line) 
    UNION ALL 
    (SELECT phppos_sales.deleted 
            AS 
            deleted 
            , 
            phppos_sales.deleted_by 
            AS deleted_by, 
            sale_time, 
            Date(sale_time) 
            AS 
            sale_date, 
            phppos_sales_item_kits.sale_id, 
            comment, 
            payment_type, 
            customer_id, 
            employee_id, 
            NULL 
            AS 
            item_id, 
            phppos_item_kits.item_kit_id, 
            '' 
            AS 
            supplier_id, 
            quantity_purchased, 
            item_kit_cost_price, 
            item_kit_unit_price, 
            category, 
            discount_percent, 
            ( item_kit_unit_price * quantity_purchased - 
              item_kit_unit_price * quantity_purchased * discount_percent / 100 ) 
            AS 
            subtotal, 
            phppos_sales_item_kits.line 
            AS 
            line, 
            '' 
            AS 
            serialnumber, 
            phppos_sales_item_kits.description 
            AS 
            description, 
            ( item_kit_unit_price * quantity_purchased - 
              item_kit_unit_price * quantity_purchased * discount_percent / 100 ) 
            + 
            ( item_kit_unit_price * quantity_purchased - 
              item_kit_unit_price * quantity_purchased * discount_percent / 100 ) *
         ( Sum(  CASE   WHEN  cumulative != 1 THEN percent    ELSE 0  end) / 100 ) 
  + ( ( (  item_kit_unit_price * quantity_purchased  - 
  item_kit_unit_price * quantity_purchased * discount_percent / 100 ) *
  ( Sum(CASE 
  WHEN cumulative != 1 THEN percent 
  ELSE 0 
        end) 
    / 
    100 ) + ( item_kit_unit_price * quantity_purchased - 
                        item_kit_unit_price * quantity_purchased * 
                        discount_percent / 100 ) ) * ( 
  Sum( 
                                 CASE 
                                   WHEN cumulative = 1 THEN percent 
                                   ELSE 0 
                                 end) ) / 100 )                         AS total, 
  ( item_kit_unit_price * quantity_purchased - 
    item_kit_unit_price * quantity_purchased * discount_percent / 100 ) * ( Sum( 
  CASE 
  WHEN cumulative != 1 THEN percent 
  ELSE 0 
  end) / 100 ) + ( ( ( item_kit_unit_price * quantity_purchased - 
                                          item_kit_unit_price * quantity_purchased 
                                          * 
                                          discount_percent 
                                          / 100 ) * ( Sum( 
                     CASE 
                       WHEN cumulative != 1 THEN percent 
                       ELSE 0 
                     end) / 100 ) + ( 
                                        item_kit_unit_price * quantity_purchased 
                                        - 
                                                   item_kit_unit_price * 
                                                   quantity_purchased 
                                                   * discount_percent / 100 ) ) * 
                   ( 
                                    Sum(CASE 
                                          WHEN cumulative = 1 THEN percent 
                                          ELSE 0 
                                        end) ) / 100 )                  AS tax, 
  ( item_kit_unit_price * quantity_purchased - 
    item_kit_unit_price * quantity_purchased * discount_percent / 100 ) - ( 
  item_kit_cost_price * quantity_purchased )                            AS profit 
   FROM   phppos_sales_item_kits 
          INNER JOIN phppos_sales 
                  ON phppos_sales_item_kits.sale_id = phppos_sales.sale_id 
          INNER JOIN phppos_item_kits 
                  ON phppos_sales_item_kits.item_kit_id = 
                     phppos_item_kits.item_kit_id 
          LEFT OUTER JOIN phppos_sales_item_kits_taxes 
                       ON phppos_sales_item_kits.sale_id = 
                          phppos_sales_item_kits_taxes.sale_id 
                          AND phppos_sales_item_kits.item_kit_id = 
                              phppos_sales_item_kits_taxes.item_kit_id 
                          AND phppos_sales_item_kits.line = 
                              phppos_sales_item_kits_taxes.line 
   WHERE  sale_time BETWEEN "2014-04-01 00:00:00" AND "2014-04-30 23:59:59" 
          AND phppos_sales.location_id = '1' 
          AND phppos_sales.store_account_payment = 0 
   GROUP  BY sale_id, 
             item_kit_id, 
             line) 
  ORDER  BY sale_id, 
            line; 
  </code></pre>