磁盘故障后SequoiaDB如何实现在线恢复

2022-03-23 00:00:00 数据 数据库 节点 磁盘 损坏

背景

近笔者在看技术大牛们编写的技术书籍时,发现了一句挺有意思的话,大概的意思是说:既然都需要带新人熟悉工作的内容,为何不将要教授的内容整理成简单的教程,让大家进行阅读和学习呢。笔者觉得这句话说得挺对,将教授的内容整理成教程,一方面可以加快新人熟悉工作内容,另一方面也可以节省部分时间用于研究感兴趣的分布式技术。于是,便有了这篇教大家在 SequoiaDB 集群中出现磁盘坏盘时,如何进行处理的教程,往后也会陆续整理 SequoiaDB 数据库使用和运维方面的文章,希望可以对大家有所帮助。

磁盘损坏检测

一般情况下,磁盘损分为以下两种类型:

• 磁盘坏道

• 磁盘扇区损坏

磁盘坏道,可以分为:0磁道坏道,逻辑坏道,硬盘坏道。磁盘坏道通常都可以将损坏的磁盘进行隔离不使用后继续使用,但建议尽快更换硬盘,因为坏道会扩散,以免出现严重的数据问题。在Linux 环境中,磁盘坏道可以通过 badblocks 或 Smartmontools 工具进行检测,这两个工具的使用说法,已超过了本教程的范围,大家可自行搜索了解。

磁盘扇区损坏可以分为两种:一种是无法修复的物理损坏,另一种是可以修复的软件错误。在 Linux 环境中该如何判断磁盘的扇区是否出现损坏了呢?可以通过 demesg | grep error 命令进行检查,通常情况下,出现类似 I/O error, dev sdb, sector 8653216 信息时表示 dev/sdb 磁盘的扇区可能出现问题了。

当磁盘出现损坏时,SequoiaDB 数据库可能会有以下现象:

• 数据库节点挂掉,手工无法拉起

• 数据读取失败,节点日志文件中出现 -1 系统IO错误 或 -10 系统错误等错误码的日志

磁盘更换流程

假设已经确认损坏的磁盘为 dev/sdb, SequoiaDB 数据库的安装目录(数据库安装目录可以通过查看 etc/default/sequoiadb 文件中 INSTALLDIR 配置的路径)为 opt/sequoiadb ,SequoiaDB 数据库的操作系统管理用户为 sdbadminn,用户组为 `sdbadmingroup`。现需要进行磁盘更换的操作,具体的操作步骤如下:

1. 确认损坏磁盘对应的数据库节点

以 sdbadmin 用户 ssh 登录存在磁盘损坏的主机,执行以下命令确认 dev/sdb 磁盘所对应的数据库节点

    df -h | grep /dev/sdb && sdblist -l -m local

    从上图中可以获知,/dev/sdb 磁盘对应服务端口( 对应 SvcName 列)为 11840 的数据库节点,数据节点的数据目录为
    /sdbdata/data01/sequoiadb/database/data/11840,该数据目录需要记录起来,后面手工恢复数据的步骤中需要用到。

    2. 停止数据库节点

    1)检查集群管理服务节点配置文件中 EnableWatch 参数的值是否为 TRUE,集群管理服务节点配置文件所在为路径为 opt/sequoiadb/conf/sdbcm.conf。如果为 TRUE,说明集群管理服务节点会检测节点的状态,自动将异常挂掉的节点拉起。此时在执行第 2 步检查数据库节点进程不存在时,还需要再执行一次停止数据库节点的命令,以免数据库节点再被集群管理服务节点拉起。

      cat opt/sequoiadb/conf/sdbcm.conf | grep "EnableWatch"

      从上图可以获知,集群管理服务节点配置了自动拉起异常节点并且 EnableWatch 的默认值为 TRUE。
      2)检查服务端口为 11840 的数据库节点进程是否存在,若返回的结果包含 Total: 0 关键字,表示数据库节点进程不存在,即数据库节点已停止。
        sdblist -p 11840

        Note: 

        数据库节点服务端口 11840 需要替换成 第 1 步中实际数据库节点的服务端口

        3)停止服务端口为 11840 的数据库节点,若返回的结果包括 Total: 1; Success: 1; Failed: 0 或者 Total: 0; Success: 0; Failed: 0 关键字,表示数据库节点已经停止成功。若返回Total: 1; Success: 0; Failed: 1,表示数据库节点停止失败,可重新执行停止数据库节点命令,若执行多次都无法停止,可以通过 kill -9 <PID> 将进程强杀,PID是第1步中 PID 列对应的数值。
          sdbstop -p 11840

          3. 更换磁盘

          1)从服务器磁盘卡槽中拔出损坏的磁盘,插入新的磁盘,然后 ssh 登陆主机,切换至 root 权限用户,检查操作系统是否仍可以查看到损坏磁盘的挂载目录。

            df -h | grep "/dev/sdb"

            从上图可以获知,从操作系统中仍看到损坏磁盘的挂载目录,需要进行卸载。

            2)从磁盘挂载目录中取消挂载损坏的磁盘。正常取消挂载不会有任何结果输出,若有输出 umount: sdbdata/data01: target is busy 等信息,表示有操作系统进程使用了 sdbdata/data01 目录,并且进程未退出,需要执行第3步操作,查看有哪些进程使用 sdbdata/data01 目录,并将其 kill 掉。

              umount sdbdata/data01

              3)通过 fuser 命令查看有哪些进程使用 sdbdata/data01 目录,并将其 kill -9 强杀进程。

                fuser -m sdbdata/data01

                从上图可以获知,进程号为 78422 的进程在使用 sdbdata/data01 目录,需要执行 kill -9 78422 命令将该进程强杀掉。

                4)通过 fdisk 命令查看检查操作系统是否已经识别到新插入的磁盘,若输出结果中出现对应的磁盘盘符,则表示操作系统已经识别到新插入的磁盘。

                  fdisk -l

                  从上图可以获知操作系统还未识别到新插入的磁盘,需要按照第 5 步的命令在线动态识别新插入的磁盘。
                  5)查看主机总线号, 并且重新扫描SCSI总线添加设备,注意:- - - 的 - 符号之间存在空格。
                    scsi_hosts=(`ls sys/class/scsi_host/`)
                    for scsi_host in ${scsi_hosts}
                    do
                    echo "- - -" > "/sys/class/scsi_host/${scsi_host}/scan"
                    done

                    6)再次通过 fdisk 命令查看检查操作系统是否已经识别到新插入的磁盘,若输出结果中出现对应的磁盘盘符,则表示操作系统已经识别到新插入的磁盘。

                    7)磁盘 dev/sdb 分区格式化,类型为 ext4,若磁盘的容量大于 2T,使用 parted 工具格式化,否则可以使用 fdisk 工具。此处的磁盘容量小于 2T,当输出的结果包含 Syncing disks 和 Writing superblocks and filesystem accounting information: done 字眼表示格式化完成。

                      # 磁盘容量小于 2T
                      echo -e "n\np\n1\n\n\nw" | fdisk dev/sdb
                      echo -e "y\n" | mkfs.ext4 dev/sdb
                      # 磁盘容量大于 2T
                      parted -s dev/sdb mklabel gpt
                      parted -s dev/sdb mkpart primary 0 100
                      parted -s dev/sdb print
                      echo -e "y\n" | mkfs.ext4 dev/sdb

                      8)挂载磁盘至 /sdbdata/data01 目录

                        mount /dev/sdb /sdbdata/data01


                        9)将 /sdbdata/data01 目录的拥有者设置为 SequoiaDB 数据库操作系统管理用户

                          sdbadmin:sdbadmin_group
                          chown -R sdbadmin:sdbadmin_group /sdbdata/data01


                          10)若配置 /etc/fstab 文件设置开机自动挂载磁盘,若磁盘的盘符发生了改变时,需要修改 /etc/fstab 文件的配置,具体的挂载参数配置以实际情况为主,此处的配置为示例配置。

                            /dev/sdb                     /sdbdata/data01         ext4    defaults         1


                            4.恢复数据库节点数据

                            恢复数据库节点数据有两种方式:手工复制主节点的数据文件和基于复制组主从节点间的数据同步机制。手工复制主节点的数据文件好选择数据写入较少的时间窗口执行,这样能够减少手工复制完启动节点时触发全量同步的可能性,本文提供的手工复制主节点的数据文件步骤中停止了主节点,即不能有新数据写入。基于复制组主从节点间的数据同步机制恢复数据的步骤为:启动数据库节点,此处的数据库节点服务端口为 11840 节点启动后,自动从主节点中同步数据,无需人工干预。

                              sdbstart -p 11840


                              从主节点手工复制数据文件恢复数据方式的步骤如下: 
                              1)连接数据库,注意需要将 username ,password 修改为真实的用户名和密码,若没有用户名和密码则填写空串""。
                                sdb 'db = new Sdb("localhost", 11810, "username", "password")'


                                2)查看数据库节点所属复制组名,此处数据库节点的主机名为 sdbserver1, 服务端口为 11840。

                                  sdb 'db.list(SDB_LIST_GROUPS,{"Group.HostName":"sdbserver1","Group.Service.Name":"11840"},{"GroupName":null})'

                                  从上图可以获知,数据库节点 sdbserver1:11840 所属的复制组为 group1。


                                  3)查看复制组 group1 的主节点信息。

                                    sdb 'db.getRG("group1").getMaster()'

                                    从上图可以获知,复制组的主节点为 sdbserver1:11830。


                                    4)ssh 登录到主节点所在的机器,查看主节点的数据目录,查看 DBPath 列的值。

                                    从上图可以获知主节点 sdbserver1:11830 的数据目录为 /opt/sequoiadb/database/data/11830。


                                    5)将复制组 group1 的数据和日志持久化至磁盘。

                                      sdb 'db.sync({"GroupName" : "group1"})'


                                      6)停止该主节点,输出的结果出现 DONE 或 Total: 1; Success: 1; Failed: 0 时表示节点停止成功。

                                        sdbstop -p 11830


                                        7)创建待恢复节点的数据节点目录,复制主节点的数据目录下的所有数据文件至待恢复节点的数据节点目录中。

                                          mkdir -p /sdbdata/data01/sequoiadb/database/data/11840
                                          scp -r sdbadmin@sdbserver1:/opt/sequoiadb/database/data/11830/* /sdbdata/data01/sequoiadb/database/data/11840


                                          8)手工拷贝数据完成后,启动复制组 group1 。

                                            sdb 'db.getRG("group1").start()'


                                            5. 检查集群的数据库节点状态

                                            1)统计集群的数据库节点状态是否均为正常,若返回结果只有 ServiceStatus:true 类型的统计数量 N,则表示 N 个数据节点的节点服务状态为正常,若返回结果存在ServiceStatus:false 或 ServiceStatus:null类型的统计数据量 M,则表示 M 个数据节点的节点服务状态不正常。

                                              sdb 'db.exec("select ServiceStatus, count(1as count from $SNAPSHOT_DB group by ServiceStatus")'


                                              从上图可以获知集群的 4 个数据库节点的服务状态为正常。


                                              2)如果存在服务状态不正常的节点,可以通过以下命令查看节点的详细情况。若返回的结果含有 "ServiceStatus": false 时,表示节点服务状态不正常,可通过 Status 字段了解节点具体所处的状态。若返回的结果含有 ErrNodes 信息,通常情况是连接不上该节点,对应异常码可以查看 Flag 字段的值。

                                                sdb 'db.exec("select * from $SNAPSHOT_DB where NodeName=\"sdbserver1:11840\"")'

                                                从上图可以获知sdbserver1:11810 数据库节点连接不上,应该是挂掉或者没有启动。


                                                Note: 
                                                数据库节点存在以下几种状态(Status字段值):
                                                • "Normal":正常工作状态
                                                • "Shutdown":正在关闭状态,表示节点正在被关闭
                                                • "Rebuilding":重新构建状态,如节点异常重启后,无法与其他节点进行数据同步时,节点会进入该状态,重新构建数据
                                                • "FullSync":全量同步状态
                                                • "OfflineBackup":数据备份状态
                                                详细的错误码说明详见:http://doc.sequoiadb.com/cn/sequoiadb-cat_id-1432190985-edition_id-304

                                                总结

                                                分布式数据库中,磁盘损坏是常有的事,更换损坏的磁盘后,只需要简单的几个步骤,即可以自动恢复 SequoiaDB 数据库节点的数据。 如果您有哪些疑问想与我们交流欢迎留言,同时欢迎报名参加10月22日举行的SequoiaDB v5.0新版本发布会,了解我们更多的技术特性。

                                                相关文章