【Mysql】元数据锁锁

  
  

  
  <>强语句(声明)粒度
  <强>事务(事务)粒度 <强>即只有事务结束时才会释放元数据锁。
  
  
  
  
  
  
  
  
     

     
      <李>   session1   李   <李>   mysql>开始事务;
      查询好,0行影响(0.00秒)
      
      
      mysql>select * test1中id=1;,,
      + - - - - - - - - - - - - + +
      | id,| |名称
      + - - - - - - - - - - - - + +
      |,1 | 1大敌;,|
      + - - - - - - - - - - - - + +
      1行集(0.00秒)   李   <李>   
      
      李   <李>   session2   李   <李>   
         
        <李>   设置profilingon
           李   <李>   查询好0行影响000秒   李   <李>      李   <李>      李   <李>      李   <李>   c2 int | | alter table test1添加列,
        6根| | |,localhost零| |查询,|,,0 |空,,,,,,,,,,,,|显示完整processlist大敌;,,,,,,|
        + - - - + - - - + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
        
        
           李   <李>      李   <李>      李   <李>   |,,
        |查询结束,,,,,0.000031,| |
        |关闭表,,,| 0.000285 |
        |释放物品,,,0.002271,| |
        |清理,,,,0.000073,| |
        + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +
        15行集(0.00秒)
        
        

        可以看的到,卡住的那一步是在重命名结果表,MySQL后台将改变保存变成连续操作“<>强创建临时新表→插入老表的数据→临时新表取到老表(重命名)强”,即实际的变化老表的操作在重命名阶段才发生。而这一步即是被阻塞的那一步。所以可以确认,<强>   

        

        基于此,我们可以验证ALTER TABLE,重命名表,删除表都会被元数据锁的影响,验证步骤与上类似,省略。   

        

        值得注意的是,创建一个已存在的表也会被元数据锁影响。如果在一个事务中用到了锁表的元数据(如选择了该表)且事务未完成,那么创建同名的表也会被卡住。所参考的文章中提及这一点。有兴趣可参看:讨论页,,这里不作讨论。   

        

        元数据锁的另一个副作用:如上例中,改变表应元数据锁被阻塞后,这导致后续其他事务针对该表的选择也会被阻塞!即ALTER TABLE的操作会影响到其他选择操作,根据上述示例:   

        

           

        

        此步一直处于等待状态时,新会话中查询表。   

        

        ,#一直等待   

        

        
           

        

           

        

        中第一个会话提交后,Session2, Session3也成功执行。看看Session3的选择在哪个步骤需要等待:   

        

           

        

        可以看到选择语句首先检查查询缓存,没有命中,然后在打开表阶段卡住。   

        

        这引出了另一个特点,基于上述场景,如果后续的选择能够在查询缓存中命中,那么不会被ALTER TABLE卡住,因为不需要打开表操作。命中缓存选择的显示配置文件如下:   

        

        mysql>,显示配置文件;
        + - - - - - - - - - - - - + - - - +
        | Status ,,,,,,,,,,,,,,,,,,,,,,,| |时间
        + - - - - - - - - - - - - + - - - +
        | starting ,,,,,,,,,,,,,,,,,,,,,| 0.000017 |
        |等待查询缓存lock ,| 0.000004 |
        检查查询缓存查询| | 0.000006 |
        cached  |查看权限;| 0.000004 |
        |检查permissions ,,,,,,,,,| 0.000007 |
        |发送缓存结果clien | 0.000011 |
        |登录缓慢query ,,,,,,,,,,,| 0.000002 |
        |清洁up ,,,,,,,,,,,,,,,,,,| 0.000003 |
        + - - - - - - - - - - - - + - - - +
        8行集(0.00秒)   

        
        
        
           李   
         
      
      李   
     

  

  <强>遗留问题1。为什么第二次查询,记录没有发生变化,但结果集返回空?   

  

  这个问题在这个页面进行了讨论,确认原因是:   

【Mysql】元数据锁锁