zoukankan      html  css  js  c++  java
  • MySQL锁系列1

     http://www.cnblogs.com/xpchild/p/3782311.html

     

    MySQL的锁:
    MySQL内部有很多种类的锁,按照用途不同,可以分为两类:
    1. 保护内存结构的锁,实现同步机制
      server层对于线程共享的变量,基本上使用mutex,rwlock来做保护。
      innodb层会增加使用spinlock自旋锁

    2. 提供或者保证事务性功能的锁
      server提供了MDL锁,表锁两种锁
      innodb实现行级锁

    原子操作:


      在单处理器系统(UniProcessor)结构中,在一个指令周期内完成的都是原子指令,因为硬中断的响应是在每一个cpu指令完成后check的。
    而在多处理器结构(Symmetric Multi-Processor)中,要想完成一个原子指令,还需要保证多个core之间的一致性,这里就引入了锁总线的步骤。

    例如:x86体系下的cmpxchg指令


    下面使用原子指令来实现mutex,rwlock,spinlock的简单伪代码

    1. mutex的伪代码:

    mutex_lock:
    1
    2
    3
    4
    5
    6
    while(1)
      if cmpxchg(*lock,0,1)==0
        success
        break;
      else
        futex(wait)

    mutex_unlock:

    1
    2
    3
    if cmpxchg(*lock,1,0)==0
      futex(wakeup)
      success

      

    2. spinlock的伪代码:

    spinlock_lock:

    1
    2
    3
    4
    5
    while(1)
      /* spin */
      if compchg(*lock,0,1)==0
        success
        break

    spinlock_unlock:

    1
    2
    if cmpxchg(*lock,1,0)==0
    success

      

    3. rwlock的伪代码:


    /* variables */

    1
    2
    3
    4
    mutex_lock rw_mutex
    int r_cnt;
    int w_cnt;
    int if_has_w_req;/* 防饿死*/

    rwlock_r_lock:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <em>mutex_lock(rw_mutex)
    while(1)
      if(!if_has_w_req && w_cnt ==0)
        success
        r_cnt++
        mutex_unlock(rw_mutex)
        return
      else
        futex(wait)</em>

    rwlock_r_unlock:

    1
    2
    3
    4
    mutex_lock(rw_mutex)
    r_cnt--;
    mutext_unlock(rw_mutex)
    fetex(wake_up)

    rwlock_w_lock:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    mutex_lock(rw_mutex)
    if_has_w_req++
    while(1)
      if(r_cnt>0 ||w_cnt >0)
        fetux(wait)
      else
        if_has_w_req--
        success
        w_cnt++;
        break
    mutext_unlock(rw_mutex)

    rwlock_w_unlock:

    1
    2
    3
    mutex_lock(rw_mutex)
    w_cnt--
    mutex_unlock(rw_mutex)

      

    下面通过几篇blog分别介绍一下MySQL事务中的表锁,mdl元数据锁,innodb锁:

    另外:关于死锁的讨论,这里先列出需要关注的两点:

    1. 内存结构的锁,必须控制加锁的顺序,保证逻辑上不出现死锁
    2. 事务锁,在无法保证用户的使用数据库行为的时候,需要死锁检测

    附tips:

      在mutex的使用上的一个小tips:

      因为thread如果已经获得了mutex, 那么如果再次lock的话,会产生死锁,要么代码能够控制好,要么可以使用下面的这个结构:

    typedef struct my_mutex{
       pthread_mutext_t mutex;
       pthread_t thread;
       unsigned count;
     }my_mutex;

    在lock之前,使用 mutex_is_owner()来判断是否已经拿到这个mutex了。

    bool mutex_is_owner( my_mutex * mutex){
      return pthread_equal(thread_self(), mutex->thread);
    }
  • 相关阅读:
    Eclipse:构造函数不提示才发现
    Java:终于找到了在alloy中的JFileChooser中的弹出式菜单不显示文字的解决办法
    java:给图片上加水印
    Asp:函数是用传值还是传址
    数据库移植注意事项
    51nod 1009 数字1的数量
    51nod1003 阶乘后面0的数量
    51nod 1002 数塔取数问题
    2017 Multi-University Training Contest
    HDU 3251 Being a Hero 最小割
  • 原文地址:https://www.cnblogs.com/zengkefu/p/5678321.html
Copyright © 2011-2022 走看看