前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >POSTGRESQL 跳动在PG内存中的锁 - spin lock

POSTGRESQL 跳动在PG内存中的锁 - spin lock

作者头像
AustinDatabases
发布2022-12-12 18:43:14
8060
发布2022-12-12 18:43:14
举报
文章被收录于专栏:AustinDatabasesAustinDatabases

最近有点颓废了,不过看到WANG---JIA----LIANG的精神,做人还是要有战斗的精神,瞬间元神又回归了。

我们都知道锁在数据库中存在是在内存中,对于POSTGRESQL 来说锁在内存中的具体的实现方式是怎样的,这里从 spin lock 作为一个切入点,因为在逃离了理论上的各种行锁,死锁,锁等待,实际上在内存中的锁是什么样子的。

spin lock 本身中文的名称也叫做自旋锁,自旋锁的功能,主要在保护共享资源在并发的情况下如何被使用,防止不恰当的对数据修改造成的逻辑错误。所以spin lock 主要的面对的工作对象或者客户是,线程/进程,在一个时间内只能有一个线程获取到 spin lock,只有持有这个锁的线程或进程释放了锁后,下一个线程或进程才能获得这个锁。

那么为什么会产生spin lock 这样的锁,并且spin lock也是系统中的基础锁,同时 spin lock 有以下的一些特点:

1 使用spinlock的线程,在获取锁后,再次释放他的时间很短

2 在使用spinlock 中并没有等待队列和死锁的检测机制

3 spin lock 是基础锁,作为其他逻辑上高级锁的物理实现形式之一

4 spin lock 是与硬件和操作系统交互的锁

产生自旋锁,也是由于硬件的架构的问题产生的这样的锁,其中的主要特点是通过自旋锁来最大化的利用CPU的资源,在CPU的使用中如果频繁的进行工作的切换,将不是一个好的事情,这样会将大量的时间浪费在上下文的交换过程,而CPU大量的时间都是在等待下一个资源的进入,SPIN LOCK 的特点就是不切换,而是通过等待,切入下一个工作,而不需要CPU 来进行上下文的切换。通过这样的方法来有效的利用CPU。

所以自旋锁工作的位置也主要在于,系统状态变化的临界控制,同时有多个进程要对状态进行获取的工作情景。

下面是张关于spin lock 工作的图,这里可以描述成两个进程,其中左边的是在已经获取到spin lock的进程,在自旋的过程中达到中间点的时候如果他释放了锁,则他就失去了对这个锁的掌控权,则我们定义为0,而另一个进程在此时终于等到了释放的自旋锁,此时在掌握到锁,变为1, 在掌握锁的过程中,如同右边的原型,在掌控锁的时间内,一直在掌控,并等待工作完毕后,释放锁,🔒也在等待下一个掌握他的进程的到来。

内存的锁spin lock 本身是一个原子性的操作,他对其他的对他正在拥有的内存位置是互斥的,如果他在修改这个内存位置的值,则其他的修改都不能操作。

从锁的实现上,实际上是一个判断和上锁的工作模式

代码语言:javascript
复制
void Lock(boolean *lock) {     while (test_and_set(lock) == 1); }
注明:test_and_set 是汇编语言中的命令,具有原子性。

从上面的代码可以看到其中自旋锁的逻辑代码中只有一个循环,循环中是一个判断。同时如果使用 test_and_set 命令则需要CPU 支持相关的编译指令,否则否则就需要通过其他的手段来完成相关的指令。

POSTGRESQL对于自旋锁的调用有统一的接口,位置在src/backend/storage/lmgr/s_lock.c在通过test and set的编译命令来实现spin lock 的时候,需要注意硬件系统中是有寄存器的,如果获取值是在寄存器中,则多个线程同时要变更值,则内存和寄存器中的值可能是不同步的,所以自旋锁中的值的获取,必须是在内存中而不是在寄存器中,获取的。

同时操作获取SPIN LOCK的进程,在无法获得SPIN LOCK 后并不是出于阻塞的模式,而是在次判断是否可以获得锁,当尝试到一定次数还无法获得则无法获得SPIN LOCK的进程会进入 SLEEP 的模式,等待约定的时间后,在此尝试。

下面从源代码中也可以看到,针对不同机器的类型(CPU)架构,会针对test and set 有不同的代码,在编译的时候,会根据你的机器的类型,来选择对应的代码来完成。

参考相关文章: https://blog.actorsfit.com/a?ID=01700-b73b70b9-f34e-499e-8093-c01015e59796https://github.com/postgres/postgres/blob/master/src/include/storage/s_lock.hhttps://www.cnblogs.com/flying-tiger/p/9762886.htmlhttps://postgrespro.com/blog/pgsql/5968022

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-09-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AustinDatabases 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档