mysql机制总结

Innodb和myisam最大的不同就是

innodb支持事物 采用了行锁 

myisam 采用了表锁 默认就使用了表锁 

表锁:速度快 并发小 发生锁冲突高 开销小

行锁:速度慢 并发高 发生锁冲突低 开销大

myisam 只支持表锁 查看表争锁情况

    mysql> show status like 'table%';  
    +-----------------------+-------+  
    | Variable_name         | Value |  
    +-----------------------+-------+  
    | Table_locks_immediate | 2979  |  
    | Table_locks_waited    | 0     |  
    +-----------------------+-------+  
    2 rows in set (0.00 sec))  

table_locks_waited 值越高 说明 争锁情况比较严重 (单词理解:表锁等待)

myisam表的锁模式 表共享锁 表独占写锁

对Myisam表的读操作 不会阻塞其他用户对表的读请求 但是会阻塞写请求 写操作 会阻塞其他用户对同一表的读和写操作。读和写操作之间,以及写写操作直接是串行的(串行的理解:就是排队 一个一个执行)

myisam在执行查询语句前,会自动给涉及的所有表加读锁,在执行 更新 删除 插入前 会自动加写锁 不需要用户手动加 

手动加表锁:lock tables order red local,order_detail red local; 给两个表增加读锁

总体而言myisam表的读和写是串行的,在一定条件下 也可以并发进行 可以通过系统变量 concurrent_insert 设置为0 不允许并发插入 为1 如果表中没有被删除的行 另一个进程可以从表尾插入记录 这也是Mysql默认设置 为2时 无论有没有被删除的行 都允许在表尾插入记录。

 

 

 

innodb行锁模式两种类型

共享锁 就是读锁 加锁方式:select * from table where ... lock in share mode 如果给一行加了共享锁 其他的事物不能获取当前行的排他锁

排他锁 就是写锁 加索方式:select * from table where .... for update 如果给一行加了排他锁 其他的事物不能获取当前行的共享锁以及排他锁

 

如果加了锁 长时间不提交 就会报错

 

innodb行锁是通过索引上的索引加锁来实现的 也就是 只有通过索引条件检索数据,innodb才会使用行锁,否则,将使用表锁!

如果该表没有使用索引 在使用过程中给该表加了排他锁 另外的事物在获取排他锁的时候就会出现等待 这是因为innodb会默认为该表是表锁 因为没有加索引导致的。

如果该表中加了索引 但是列中出现了相同的值 innodb也会给该表使用行锁。

当表使用了索引 并且该列数据不一致 行锁中的排他锁才不会失效。

即使都使用了索引 是否使用索引来检索数据 是由Mysql通过判断不同的执行任务来决定的 如果Mysql认为全表扫描效率更高,比如一些特别小的表,Mysql就不会使用索引,这种情况下innodb使用表锁 而不是行锁 因此分析锁冲突时 别忘了检查sql的执行计划,以确认是否真正使用了索引。通过使用explain检查执行计划 

 

原文:https://blog.csdn.net/a5582ddff/article/details/79566654

posted @ 2018-05-23 11:32  幸福的波波肠  阅读(821)  评论(0编辑  收藏  举报