Query OK, 0 rows affected (0.00 sec)
--加入local选项是说明,在表满足并发插入的前提下,允许在末尾插入数据
当前进程不能进行插入和更新操作
mysql> insert into first_test(age) values(15);
ERROR 1099 (HY000): Table 'first_test' was locked
with a READ lock and can't be updated
?
mysql> update first_test set age=200 where id =1;
ERROR 1099 (HY000): Table 'first_test' was locked
with a READ lock and can't be updated
其他进程可以进行插入,但是更新会等待:
mysql> insert into first_test(age) values(15);
Query OK, 1 row affected (0.00 sec)
?
mysql> update first_test set age=200 where id =2;
等待.....
当前进程不能不能访问其他进程插入的数据
?
mysql> select * from first_test;
+----+------+
| id | age |
+----+------+
| 1 | 100 |
| 2 | 11 |
| 3 | 12 |
| 4 | 13 |
| 5 | 14 |
| 6 | 14 |
+----+------+
6 rows in set (0.00 sec)
释放锁以后皆大欢喜
mysql> unlock table;
Query OK, 0 rows affected (0.00 sec)
插入的和更新的都出来的:
?
mysql> select * from first_test;
+----+------+
| id | age |
+----+------+
| 1 | 100 |
| 2 | 200 |
| 3 | 12 |
| 4 | 13 |
| 5 | 14 |
| 6 | 14 |
| 7 | 15 |
+----+------+
7 rows in set (0.00 sec)
mysql> update first_test set age=200 where id =2;
Query OK, 1 row affected (1 min 39.75 sec)
Rows matched: 1 Changed: 1 Warnings: 0
?
需要注意的:
并发插入是解决对同一表中的查询和插入的锁争用。
如果对有空洞的表进行并发插入会产生碎片,所以在空闲时可以利用optimize table命令回收因删除记录产生的空洞。
锁调度
?
在MyISAM中当一个进程请求某张表的读锁,而另一个进程同时也请求写锁,Mysql会先让后者获得写锁。即使读请求比写请求先到达锁等待队列,写锁也会插入到读锁之前。
因为Mysql总是认为写请求一般比读请求重要,这也就是MyISAM不太适合有大量的读写操作的应用的原因,因为大量的写请求会让查询操作很难获取到读锁,有可能永远阻塞。
?
处理办法:
1、指定Insert、update、delete语句的low_priority属性,降低其优先级。
2、指定启动参数low-priority-updates,使得MyISAM默认给读请求优先的权利。
3、执行命令set low_priority_updates=1,使该连接发出的请求降低。
?
4、指定max_write_lock_count设置一个合适的值,当写锁达到这个值后,暂时降低写请求的优先级,让读请求获取锁。
?
但是上面的处理办法造成的原因就是当遇到复杂的查询语句时,写请求可能很难获取到锁,这是一个很纠结的问题,所以我们一般避免使用复杂的查询语句,如果如法避免,则可以再数据库空闲阶段(深夜)执行。