2024 4 23 02:22 AM 20 次查看
分类:数据库 标签:性能
为缩短篇幅,本文假定读者已知晓 transaction isolation level(事务隔离级别)的基础知识。
MySQL 的默认事务隔离级别是 repeatable read(可重复读),而在都市传说中,各个互联网大厂都会将其改为 read committed(读已提交),这是为什么呢?
从字面上理解,可重复读满足了一个事务在读取某行后,如果另一个事务修改了该行,再次读取它时,能保持第一次读到的值。可是,这又有什么意义呢?谁会在一个事务里多次读取同一行呢?
其实它的实现是这样:当事务开始后,从它第一次读取数据时,就创建了一个快照,之后都是对这个快照进行查询,直到这个事务结束。也就是说,可重复读的主要作用是让事务只访问这个事务和它之前已有的数据,而不是字面上的读同一行不会变。
而读已提交只需要在每次读取时创建一个快照,读取完这个快照就用不到了。
由此可见,可重复读需要维护一个较长的快照,这自然要消耗更多的资源。
不过现实中我们不会这样简单地使用事务。一个正常的事务如果要基于读取到的数据来修改,会使用 SELECT ... FOR UPDATE
的形式来加锁。
如果这里可以利用唯一索引的话,MySQL 会对唯一索引中满足条件的行添加行锁,否则需要加 gap lock 和 next-key lock,这两把锁会增加被锁定的范围。例如表 test
有一个被索引的列 a
,有一行 a
为 100 的数据。当执行 SELECT * FROM test WHERE a = 1 FOR UPDATE
后,其他事务无法插入任何 a < 100
的数据,因为被这两把锁给锁住了。
而读已提交则不会添加这两种锁,并且当需要锁住的行不存在时,并不会对其加锁,而是允许其他事务插入。
由此可见,可重复读可能锁住了更多的数据,更容易造成死锁。
2024 4 2 10:47 PM 658 次查看
分类:编程 标签:无
最近发现 VSCode 里安装的 AI 编程插件越来越多,也不知道会不会有冲突,所以想选一个最好的留下。
本次参与评测的选手有:tabnine、Codeium、CodeGeeX、fittencode、Baidu Comate、TONGYI Lingma 和 Cody(按我安装的顺序排序,有些不好用的我直接卸载了,不参与评测)。
鉴于免费的已经够我用了,收费的就不参与评测了,正好避免恰饭嫌疑。
2023 11 21 12:35 PM 51 次查看
分类:Web 标签:nginx
最近项目中遇到一个需求:
用户在使用 seafile 上传文件,希望将其分享出去。
seafile 自己生成的分享链接类似于 https://seafile.xxx.com/f/23cc6812408e44f8b63e/
,若未过期且密码正确时会将其重定向到类似 http://seafile.yizhisec.com/seafhttp/files/e1687864-8a12-46db-9708-b4240df346be/1.txt
的地址。
产品希望能对这个分享链接进行鉴权,并且最好不暴露实际的文件地址和避免发起重定向的请求。
2023 3 24 05:22 PM 135 次查看
分类:Go 标签:Go
4 年前我用 Python 写了个叫 delayed 的任务队列,经过几年发展后,公司有了 Go 和 Python 相互调用的需求。
目前的 delayed 实现是用 pickle 来做序列化的,其实之前也写过用 JSON 来做序列化的版本,但是遇到了几个问题:
- JSON 会丢失一些对象类型,例如无法区分 tuple 和 list。
- JSON 无法直接编码二进制字符串(bytes)。
- JSON 不支持原本 pickle 能支持的很多类型。
当时因为这些问题我就放弃了,但是现在看来,这些问题有的可以解决,有的可以容忍,所以还是决定开发 Go 的版本。
2022 11 1 06:49 PM 198 次查看
分类:Go 标签:Go
Russ Cox 曾经写过一个《Memory Models》系列,今年 6 月 Go 官网也更新了他写的 《The Go Memory Model》。这两篇都是非常值得一读的文章,网上也有不少翻译。因为这些文章的信息量较大,我还是尝试解读一下吧。
2022 10 31 04:36 PM 167 次查看
分类:Go 标签:Go
今天在读 sync.Once 的源码时,突然发现了一个有意思的提交,让它的性能提升了一倍。
2022 10 26 12:35 PM 174 次查看
分类:Go 标签:Go
昨天在压测公司的项目时发现,sync.(*Map).Store()
抛了个异常,日志如下:
fatal error: sync: unlock of unlocked mutex
goroutine 63756060 [running]:
runtime.throw({0xbeeca9, 0xb45120})
#011/usr/local/go/src/runtime/panic.go:1198 +0x71 fp=0xc0010f13a0 sp=0xc0010f1370 pc=0x4336d1
sync.throw({0xbeeca9, 0xb2dd40})
#011/usr/local/go/src/runtime/panic.go:1184 +0x1e fp=0xc0010f13c0 sp=0xc0010f13a0 pc=0x45ecfe
sync.(*Mutex).unlockSlow(0x11d45a0, 0xffffffff)
#011/usr/local/go/src/sync/mutex.go:196 +0x3c fp=0xc0010f13e8 sp=0xc0010f13c0 pc=0x47851c
sync.(*Mutex).Unlock(...)
#011/usr/local/go/src/sync/mutex.go:190
sync.(*Map).Store(0x11d45a0, {0xae4960, 0xc0012f4350}, {0xae40e0, 0xc000026078})
#011/usr/local/go/src/sync/map.go:163 +0x465 fp=0xc0010f1480 sp=0xc0010f13e8 pc=0x476fa5
要知道这可是 Go 的官方库,sync.Map
可是专门为并发安全而设计的,难道直接调用它的接口也会出现线程冲突?
2022 9 11 06:19 PM 219 次查看
分类:Docker 标签:Docker
公司的服务是 Docker 搭建的,给客户升级时存在一个问题:镜像太大了。
虽然我已经找了很多方法,甚至对于 Go 服务而言,已经全换成 scratch 镜像 + 单可执行文件的方式了,但是对于 Python 服务却没啥办法。大部分的 Python 库是有 C 库依赖的,因此不能用 scratch 镜像,甚至因为 alphine 镜像不是用 libc,也会出现很多兼容性问题。而在 Ubuntu 的基础上安装完依赖后,就轻松超过 300 MB 了。
因为不能在客户那搭建一个 docker repository 把镜像推过去,那只能想些奇技淫巧来实现了。
2021 4 17 06:09 PM 406 次查看
分类:Python 标签:Python
今天在看 functools.cache
的源码时发现参数列表有个诡异的 /
:
def cache(user_function, /):
'Simple lightweight unbounded cache. Sometimes called "memoize".'
return lru_cache(maxsize=None)(user_function)
翻了下文档才发现这个叫 Positional-Only Parameters。
2020 12 1 01:44 PM 472 次查看
分类:Docker 标签:Docker
在使用 GitLab CI 时,我经常被漫长的构建时间影响工作效率,尤其是在一台机器上已经 docker build
过的镜像,另一台机器上却需要重新构建,没法利用缓存。
查了一番文档后,我发现 docker build
还能使用外部缓存来加速构建。