I've read and tested row-level locks in MySQL's InnoDB but I still find it hard to actually say "I know how locks work in MySQL"!
Here's my test data:
mysql> select * from lockable;
+----+----+----+
| id | c1 | c2 |
+----+----+----+
| 1 | A | A |
| 2 | A | B |
| 3 | A | C |
| 4 | B | A |
| 5 | B | B |
| 6 | B | C |
| 7 | C | A |
| 8 | C | B |
| 9 | C | C |
+----+----+----+
9 rows in set (0.00 sec)
In order to test the MySQL's behaviour regarding row-level locks, I opened two terminals and connected to MySQL. I'm going to name them mysql1>
and mysql2>
. Here's what I executed on first terminal:
mysql1> ROLLBACK;
mysql1> BEGIN;
mysql1> SELECT id, c1, c2 FROM lockable WHERE c1 = "A" FOR UPDATE;
+----+----+----+
| id | c1 | c2 |
+----+----+----+
| 1 | A | A |
| 2 | A | B |
| 3 | A | C |
+----+----+----+
3 rows in set (0.00 sec)
Then on the second terminal:
mysql2> SELECT * FROM lockable WHERE c1 = "B" FOR UPDATE;
To my surprise the above query will be blocked by the first one! So I rolled back the first terminal and started over:
mysql1> ROLLBACK;
mysql1> BEGIN;
mysql1> SELECT id, c1, c2 FROM lockable LIMIT 3 FOR UPDATE;
+----+----+----+
| id | c1 | c2 |
+----+----+----+
| 1 | A | A |
| 2 | A | B |
| 3 | A | C |
+----+----+----+
3 rows in set (0.00 sec)
Then on the second terminal:
mysql2> SELECT * FROM lockable WHERE LIMIT 6,1 FOR UPDATE;
Again the second terminal is blocked by the first one! Is there any scenario in which not all of records of a table are locked? If not why is this called "row-level locking"?