mysql_mutex_t_MySQL锁系列1

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:

while(1)

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

success

break;

else

futex(wait)

mutex_unlock:

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

futex(wakeup)

success

2. spinlock的伪代码:

spinlock_lock:

while(1)

/* spin */

if compchg(*lock,0,1)==0

success

break

spinlock_unlock:

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

success

3. rwlock的伪代码:

/* variables */

mutex_lock rw_mutex

int r_cnt;

int w_cnt;

int if_has_w_req;/* 防饿死*/

rwlock_r_lock:

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)

rwlock_r_unlock:

mutex_lock(rw_mutex)

r_cnt--;

mutext_unlock(rw_mutex)

fetex(wake_up)

rwlock_w_lock:

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:

mutex_lock(rw_mutex)

w_cnt--

mutex_unlock(rw_mutex)

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

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

1. 内存结构的锁,必须控制加锁的顺序,保证逻辑上不出现死锁

2. 事务锁,在无法保证用户的使用数据库行为的时候,需要死锁检测

附tips:

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

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

typedef structmy_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);

}

待续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值