Pika磁盘容量满恢复方案

背景

Pika 实例硬盘容量满,清理数据后,Pika 仍然保持错误的状态,需要重启才能恢复

解决方案

由于 RocksDB 在磁盘满了之后会进入写保护状态,此时不接受任何写请求,所以这种情况下如果 Pika 在清理掉磁盘空间进行接收写请求时,由于 RocksDB 还是处于写保护状态,这时候依然不能进行写响应,我们之前的一个方案是为 Pika 新增加一个线程,每过 5s 对磁盘进行检测,如果在预计容量内,则遍历整个 slot 对写请求状态进行恢复,但是由于这种操作每次需要遍历整个 DB 和 整个 slot,有上锁解锁操作,我们后面决定以一个命令的形式对这一情况进行解决,Diskcovery 命令,这个命令用于恢复对 RocksDB 的写保护状态,同时恢复 Pika 中写 binlog 错误的状态,在当前磁盘容量小于 write-buffer-size 的时候不进行恢复,只有在当前磁盘容量大于 write-buffer-size 的时候进行恢复,这里的 write-buffer-size 指 Memtable 的大小,设置为 256M. 以下是设计方案的代码:

截屏2023-08-07 10 56 37

复现方式

  1. 我们首先创建一个 1GB 大小的虚拟磁盘 (Centos环境),并查看是否成功

    dd if=/dev/zero of=my_virtual_disk.img bs=1G count=1

    ls -lh my_virtual_disk.img

截屏2023-08-02 20 31 54
  1. 然后执行命令来对文件进行格式化为特定的文件系统(ext4)

mkfs.ext4 my_virtual_disk.img

截屏2023-08-02 14 59 28
  1. 把虚拟文件系统挂载到目录 /mnt/vfs

sudo mkdir -p /mnt/my_disk

sudo mount -o loop my_virtual_disk.img /mnt/my_disk

df -h

截屏2023-08-02 20 18 23
  1. 我们对 pika.conf 里面的 log-path 和 db-path 进行修改,改成我们创建的虚拟文件系统路径
截屏2023-08-02 15 24 02
  1. 启动 Pika 并进行压测,我们先记录一下压测前磁盘的使用情况
截屏2023-08-02 20 11 58
  1. 等到压测到磁盘上限时我们可以发现此时执行 set 操作(写操作)时已经不能正常执行,我们调用 Diskrecovery 命令可以看到此时的磁盘使用情况(此时这种情况是不能恢复的,因为磁盘 free 的大小小于 write-buffter-size)
截屏2023-08-02 16 11 50
  1. 我们继续更改 pika.conf 的 log-path 和 db-path 然后把 之前的一个 db 文件删掉,继续启动 Pika 进行测试
截屏2023-08-02 20 17 29
  1. 在磁盘再次被打满时,我们依然不能执行 set 操作,此时我们把之前的 db 文件夹删掉,然后执行一次 Diskrecovery 命令,发现再次执行 set 操作时已经可以正常执行了
截屏2023-08-02 20 16 36

相关 PR: #1843

相关 Issue: #1150