afox123 发表于 2018-9-26 12:59:26

也谈mysql锁问题

  锁是计算机协调多个进程或线程并发访问某一资源的机制,相对其他数据库而言,Mysql的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如Myisam和Memory存储引擎采用的是表级锁;BDB存储引擎采用的是页面锁,但也支持表级锁;Innodb存储引擎既支持行级锁也支持表级锁;以下是他们各自锁的区别:
  表级锁:开销小,加锁快;不会出现死锁;锁粒度大.发生锁冲突概率最高,并发度最低.
  行级锁:开销大,加锁慢;会出现死锁,锁粒度最小;发生锁冲突概率最高,并发度也最高.
  页面锁:开销和加锁时间界于表锁和行锁之间,会出现死锁;锁粒度界于表锁和行锁之间.
  1.Myisam 锁问题:
  查询表级锁争用情况:
  table_locks_waited       table_locks_immediate
  如果值较高,说明存在着严重的争锁情况.
  表级锁的锁模式: 共享锁和排他锁.两锁之间是冲突的,知道锁线程释放.
  在执行select前会自动为表加锁,使表具备只读,执行update/insert/delete 会自动为表加排他锁;
  mysql不支持锁升级,也就是说显示加锁后,只允许访问加锁的表,隐式加锁也一样.
  并发插入:在一定条件下.mysql支持查询与插入一同操作.
  允许并发插入相关参数设置:concurrent_insert = 0/1/2
  0:不允许并发插入.
  1:当有记录从该表删除时,表中有空洞才允许并发插入.
  2:不管有无空洞,都允许并发插入.
  查看表是否有空洞:show table status like 'table_name';
  Data_free:      这一项则表示delete删除记录后是否有空隙.
  Myisam的锁调度:
  默认情况下,写进程优先获得锁.即使读请求在写请求队列前,写请求也会优先获得锁.
  2:Innodb锁问题:
  事务的ACID属性:
  A:原子性,指事务是一个原子操作单元,其对数据的修改,要么全部执行成功,要么全部不执行.
  C:一致性,在事务开始和结束时.数据都必须保持一致状态,这意味着所有数据规则都必须应用于事务的修改,以保证事务的完整性.事务结束时,所有内部数据(如:索引)都必须正确.
  I:隔离性,提供一定的隔离机制,保证事务在不受外部并发操作影响的"独立"环境下执行,事务与事务之间是不可见的.
  D:持久性,事务完成之后,它对事务的修改是永久性的.即使出现系统的故障也能保持.
  相关事务的例子:可以想象一下银行转账.
  获取Innodb行锁争用情况:
  innodb_row_lock_waits      innodb_row_lock_time_avg
  Innodb 是通过给索引的索引项加锁来实现的.这意味着Innodb只使用索引来检索数据才会使用行锁,否则使用表锁.
  大家又可以想象,因为Innodb是为索引加锁,所以如果两个事务使用同一个索引的话,已然会出现锁等待问题.
  即使条件中使用了索引,但mysql的执行计划认为全表扫描的效率高,则会放弃使用索引,所以在分析锁冲突时不要忘记分析sql计划.
  Explain Query; 我们也可以强制mysql使用索引 force index 'index_name'.
  间隙锁:
  为范围的条件值加锁,尽管条件并不存在,避免产生幻读.

  例: select * form table_name where>  那么Innodb会为大于100的索引项加锁,尽管没有101,102....
  尽管请求一个不存在的记录时,Innodb也会为这个不存在的值索引加锁.
  在一个事务未提交前,其他并发事务不能插入满足其锁定条件的任何记录,也就是不允许出现幻读.

页: [1]
查看完整版本: 也谈mysql锁问题