MySQL锁——MyISAM锁

来源:互联网 发布:js淘宝购物车的实现 编辑:程序博客网 时间:2024/06/05 21:49

MySQL锁机制:不同的存储引擎支持不同的锁机制。

  1. 表级锁:开销小、加锁快;不会出现死锁;锁粒度大,发生锁冲突的概率高,并发度低。
  2. 页面锁:性能和并发性都介于表级锁和行级锁之间。
  3. 行级锁:开销大、加锁慢;会出现死锁;锁粒度小,发生锁冲突的概率低,并发度高。

由于锁的特点不同,不同的锁机制适合不同的应用:
a. 表级锁适合于以查询为主,只有少量按照索引更新的应用,如web应用。
b. 行级锁适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用。

MyISQM表锁:
table_locks_waited状态变量表示不能立即加锁,需要等待锁的次数,也就意味着锁等待。
table_locks_immediate状态变量表示可以立即获得锁的次数
table_locks_waited/table_locks_immediate值越高说明数据库的并发性越低,当该值达到一定程度,改用InnoDB存储引擎。
MySQL MyISAM的表锁:表共享读锁和表独占写锁

对MyISAM表的读操作不会阻塞其他用户对表的读请求,但是会阻塞对MyISAM表的写请求;对MyISAM表的写操作会阻塞其他用户对表的读请求和写请求。MyISAM在执行查询语句(select)前会自动给所有涉及的表加表共享读锁,在执行更新操作(update、delete、insert)前会自动给所有涉及的表加表独占写锁。

显式加锁:

        读锁:lock table t read;            或者             lock table t read local;        写锁:lock table t write;

因为MySQL不支持锁升级,加锁时需要取得所有涉及表的表锁,所以加锁之后,此会话在释放锁之前只能操作被加锁的表,这就是为什么MyISAM的表锁不会出现死锁。

此外,如果对表加读锁,当前用户只能对锁定表执行查询(select)语句,其他用户可以对表加读锁,但是不可以对此表加写锁,也就是说只能对该表查询(select),不能更新(update、insert 、delete);如果对表加写锁,当前用户可以对锁定的表做任何操作,其他用户不可以对此表加任何锁,也就是说不可以对该表执行任何(select、update、insert、delete )操作。

MyISAM表下lock table t read和lock table t read local的区别:
当前对话lock table t read local后,根据concurrent_insert参数的值决定其他用户可不可以并发插入。但是如果可以动态插入,不会影响当前对话的查询结果。
concurrent_insert参数:
值为0:不允许并发插入
值为1:如果MyISAM表中没有空洞(表的中间没有被删的行),允许在表尾并发插入
值为2:不论有没有空洞都允许在表尾并发插入

MyISAM的锁调度:
MyISAM中,写进程比读进程会优先获得锁,从而可能到出现大量的更新操作使得查询操作很难获得读锁,造成读进程饿死,同样如果正在执行一个耗时的查询操作,也可能出现写进程饿死的情况。
解决方法:
1 》通过设置调度行:
通过制定insert、update、delete语句的low_priority属性,调整更新语句的优先级。
2 》通过给系统参数max_write_lock_count设置一个合适的值,当一个表的读锁达到这个值后,MySQL就会降低写锁请求的优先级,给读进程获得资源的机会。
3 》将复杂的SQL查询语句分解为若干个耗时较小的SQL语句。

原创粉丝点击