Atuin ZFS下卡顿问题解决

最近一段时间在使用 fish + atuin 组合时,发现偶尔会出现卡顿,不是必现。表象就是当你输 ip ahtop 等低消耗命令时,系统感觉卡了几秒,这明显有问题。

作为一个 N 年的 Linux 用户,从来没有在终端里面被这么卡过,是可忍孰不可忍。一开始我以为是什么审计模块的锅,仔细查看进程,并没有发现异常。

电脑环境也没有做什么特别变化操作,几乎所有东西都是自己定制的,也不可能有问题,马上意识到可能是新使用 atuin 的问题,毕竟 fish 都出来好多年了,不至于卡成这个鬼样。

在 google 里面搜索 atuin lag,第一条记录即命中要害:https://github.com/atuinsh/atuin/issues/952

粗略读了一遍上面的 issues,问题出现在 atuin 离线模式使用 SQLite 存储 history 记录,SQLite 在 ZFS 中就存在这种问题。

踩雷的用户不多,首先你要用 ZFS,再次要用 atuin + SQLite

issues 里面的解决方式有几种,要么修改 atuin 的源码,要么等 ZFS 或者 SQLite 修复。

上述方式都不是很轻松,个人觉得点赞最多的这个解决方式最轻松(略有修改)。

1sudo zfs create -V 500MB rpool/atuin
2sudo zfs list -o name,encryption | grep atuin # ensure encryption for the zvol
3sudo mkfs.ext4 /dev/zvol/rpool/atuin
4mv ~/.local/share/atuin ~/.local/share/atuin-backup
5mkdir ~/.local/share/atuin
6sudo mount /dev/zvol/rpool/atuin ~/.local/share/atuin
7sudo chown -R ${USER}: ~/.local/share/atuin
8cp -rv ~/.local/share/atuin-backup/* ~/.local/share/atuin

唯一不好的地方这里的 mount 是临时的,重启后就丢失了,得把他写入/etc/fstab 开机自动加载。

操作过程解释记录如下:

1. 创建 Zvolumes datasets 等

1➜  ~ sudo zfs create -V 500MB rpool/atuin
2[sudo] password for mephisto:
3cannot create 'rpool/atuin': dataset already exists

因为我已经创建过了,所以会提示已存在,正常首次创建不会有问题的。

为了照顾不熟悉 ZFS 的读者必须上一张图

zfs overview

重点关注 zpool 这一层,ZFS 相比传统的文件系统,多了一层抽象,在软件行业,一般多一层抽象的,都感觉很厉害的样子,遇事不决加一层 😅

zpools 里面包含 各种类型的 dataset,Zvolumes datasets 便是其中的一种,它可以被格式化成 ext4,能分区,能挂载,就好像一个块设备一样,真的厉害。

格式化

1sudo mkfs.ext4 /dev/zvol/rpool/atuin

查看结果

 1➜  ~ ls -al /dev/zvol/rpool/atuin
 2lrwxrwxrwx 1 root root 9 Feb 26 18:42 /dev/zvol/rpool/atuin -> ../../zd0
 3➜  ~ sudo fdisk -l
 4[sudo] password for mephisto:
 5Disk /dev/sda: 476.94 GiB, 512110190592 bytes, 1000215216 sectors
 6Disk model: SanDisk SD8SN8U-
 7Units: sectors of 1 * 512 = 512 bytes
 8Sector size (logical/physical): 512 bytes / 4096 bytes
 9I/O size (minimum/optimal): 4096 bytes / 4096 bytes
10Disklabel type: gpt
11Disk identifier: 05A996E7-F044-4E59-9DED-F0C891E163CE
12
13Device       Start        End   Sectors   Size Type
14/dev/sda1     2048    1050623   1048576   512M EFI System
15/dev/sda2  1050624    5244927   4194304     2G Linux swap
16/dev/sda3  5244928    9439231   4194304     2G Solaris boot
17/dev/sda4  9439232 1000215182 990775951 472.4G Solaris root
18
19
20Disk /dev/zd0: 500 MiB, 524288000 bytes, 1024000 sectors
21Units: sectors of 1 * 512 = 512 bytes
22Sector size (logical/physical): 512 bytes / 16384 bytes
23I/O size (minimum/optimal): 16384 bytes / 16384 bytes

后续的步骤都很简单,不再一一演示。

 1➜  ~ mount -v |grep atuin
 2/dev/zd0 on /home/mephisto/.local/share/atuin type ext4 (rw,relatime,stripe=4)
 3➜  ~ df -h ~/.local/share/atuin
 4Filesystem      Size  Used Avail Use% Mounted on
 5/dev/zd0        452M  5.8M  412M   2% /home/mephisto/.local/share/atuin
 6➜  ~ ls -al ~/.local/share/atuin
 7total 5865
 8drwxr-xr-x  4 mephisto mephisto    4096 Feb 27 15:42 ./
 9drwx------ 83 mephisto mephisto      93 Feb 27 16:53 ../
10drwxrwxr-x  2 mephisto mephisto    4096 Feb 26 16:43 atuin/
11-rw-r--r--  1 mephisto mephisto 4550656 Feb 27 17:12 history.db
12-rw-r--r--  1 mephisto mephisto   32768 Feb 27 17:12 history.db-shm
13-rw-r--r--  1 mephisto mephisto 1384352 Feb 27 17:12 history.db-wal
14-rw-rw-r--  1 mephisto mephisto      48 Feb 26 16:43 key
15drwx------  2 mephisto mephisto   16384 Feb 26 16:41 lost+found/

换成 ext4 后,真的很丝滑,再也没卡过。

2. 开机自动挂载

查询 uuid

1➜  ~ sudo blkid /dev/zd0
2/dev/zd0: UUID="6a16a600-bd7c-4b6f-b371-d0fb2306263a" BLOCK_SIZE="4096" TYPE="ext4"

备份/etc/fstab,不备份万一搞坏了,文件系统都加载不了,处理起来有点麻烦的。

1sudo cp /etc/fstab /etc/fstab_bak

最后一行是添加的的,其它地方不要动,除非你知道它们是干什么用的,每个人的系统环境不一样。uuid 填上面查询的,tab 分隔。

1➜  ~ cat /etc/fstab | egrep -v '^#'
2UUID=742C-0CA0  /boot/efi       vfat    umask=0022,fmask=0022,dmask=0022      0       1
3/boot/efi/grub  /boot/grub      none    defaults,bind   0       0
4UUID=fd8b7e16-9901-48c0-b8dc-ab7da1459126       none    swap    sw      0       0
5UUID=6a16a600-bd7c-4b6f-b371-d0fb2306263a       /home/mephisto/.local/share/atuin       ext4    defaults        0       0

这样开机启动就设置好了,重启后自动挂载正常。

想进一步了解 ZFS 文件系统的可查看 Gentoo 的 zfs 文档

或者查看帮助文档

1man zfs
2man zpool

最后友情提示,zfs 操作的是 datasets,zpool 操作的 zpolls(ZFS storage pools),不要搞混了敲错命令。

最后修改于: Tuesday, February 27, 2024
欢迎关注微信公众号,留言交流。

相关文章:

翻译: