MySQL进阶之MyISAM引擎的锁处理

作者: 怀老师 | 来源:发表于2020-04-13 21:36 被阅读0次

MyISAM支持表锁

    InnoDB支持行级锁(row-level locking)也支持表级锁,但默认采用行级锁。

表锁和行锁的区别

    表级锁:开销小,加锁快,不会出现死锁,锁定粒度大,发生所冲突的概率最高,并发度最低。

    行级锁:开销大,加锁慢,会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

    表锁更适合于以查询为主,只有少量按索引条件更新数据的应用。

    行级锁更适合于大量按索引条件并发更新少量不同数据,同时又有并发查询的应用。

MyISAM的两种锁模式

    读锁和写锁(全称表共享读锁和表独占写锁)

    读锁

    当前读锁时,允许读请求,但是会阻塞写请求。

    写锁

    当前写锁时,不能读也不能写。(当一个线程获得一个表的写锁后,只有持有锁的线程可以对表进行更新操作。其他线程的读写都会等待。)

如何加锁?

    MyISAM在执行查询语句前,会自动给涉及的所有表加读锁,在执行更新操作前,会自动给涉及的表加写锁。

    因此用户一般不用lock table  test write;这样显式加锁

    给MyISAM表显式加锁,一般是为了模拟事务操作,实现对某一个时间点,多个表的一致性读取。

加锁时的并发请求处理

    给表加读锁时加上local,可以允许在读取的时候进行尾部并发插入。

    lock table test read local;

    如果查询时用了别名,那么加锁是也要把别名带上。

    local table test as a read local;

    这个并发插入是MyISAM的一个系统变量Concurrent Inserts.当值为1或者2的的时候允许插入。(值为1时要求表中间没有被删除的行)

    local只是允许了并发时的末尾插入,但是其他操作还是不行的。

MyISAM的锁调度

    MyISAM的读锁和写锁时互斥的,读写操作是串行的。

    当读锁请求和写锁请求并发时,或者读锁先一步进入锁队列,系统还是会优先写请求,因为一般认为写请求比较重要。这也是MyISAM不适合大量更新操作的应用原因 。因为大量更新的系统很难获得读锁,从而可能永远阻塞请求。

那么如何解决锁调度导致的阻塞问题呢?

    可以通过执行命令set low_priority_updates=1使该连接发出的更新请求优先级降低。

    或者启动时加上low-priority-updates参数,使MyISAM引擎默认给与读请求优先的权利。

扩展:一些需要长时间运行的查询操作,会使进程饿死,所以复杂查询应该空闲时间执行,一般情况应使用简单的查询或者中间表来解决。

相关文章

网友评论

    本文标题:MySQL进阶之MyISAM引擎的锁处理

    本文链接:https://www.haomeiwen.com/subject/uydomhtx.html