So, from my reading of the MySQL 5.5 documentation and some experiments I did with colleagues, I understand that the following is the case:
- With InnoDB tables, a simple
SELECTstatement (one that does not useFOR UPDATEorLOCK IN SHARE MODE) will not grab any row locks on the tables that theSELECTstatement reads. This is true at all transaction isolation levels. - However, if your transaction isolation level is
REPEATABLE READor higher, anINSERT ... SELECTorCREATE TABLE AS SELECTstatement will place row locks on tables that it reads from.
Sources:
- http://dev.mysql.com/doc/refman/5.5/en/innodb-consistent-read.html
- http://dev.mysql.com/doc/refman/5.5/en/innodb-locks-set.html
If I understand this correctly (and correct me if I don't), then I'm puzzled by this difference. Why does reading a table require lock rows in the one case but not the other, when the transaction isolation level is the same? I'd like to understand the reason for this.
SELECTneeds to be a frozen snapshot for loading the table. If it were a moving target, that would require a transaction within a transaction." But how is it then that row locks are not needed when you have multiple simpleSELECTs of the same table within oneREPEATABLE READtransaction? – Luis Casillas Aug 08 '14 at 20:28INSERT INTO target SELECT blah FROM sourcedo the same, and use a transaction-level consistent MVCC snapshot just like the multiple simpleSELECTScan? (Assuming no statements in the transaction modify thesourcetable.) – Luis Casillas Aug 08 '14 at 20:41INSERT ... SELECTorCREATE TABLE AS, later statements in the same transaction can see these writes. This means that even if the isolation level isREPEATABLE READ, the transaction's reads can no longer share the snapshot established by the first read; instead, "the SELECT part acts like READ COMMITTED, where each consistent read, even within the same transaction, sets and reads its own fresh snapshot." So then the engine has to fall back on row locks to preserve theREPEATABLE READsemantics, right? – Luis Casillas Aug 08 '14 at 21:01REPEATABLE READsemantics at all. Look back at the MySQL Document in my answer. It clearly saysInnoDB uses stronger locks and the SELECT part acts like READ COMMITTED. InnoDB performs internal lock escalation to makeINSERT ... SELECTpossible. – RolandoMySQLDBA Aug 08 '14 at 21:09