存储可靠性、数据备份和恢复

BCP: 灾难恢复和业务连续性计划(Disaster Recovery and Business Continuity Plan),是任何公司都不可以忽视的一个话题。备份什么?备份的策略?如何有效的执行备份计划?备份是否有效?如何恢复数据?

1. 存储的可靠性

通过 RAID 磁盘冗余阵列保障存储的可靠性,是最基础、最简单、重要的数据保护手段。通常采用 RAID1 或者 RAID5 来保障存储的可靠性。

RAID 级别

限制

优点

RAID1

  • 两块或者以上硬盘

简单。可以无须硬件,使用操作系统本身提供的软RAID实现。

RAID5

  • 三块或者以上硬盘

  • 需要特殊硬件(RAID卡)支持

在性能和数据安全性上能够得到兼顾

在 Debian/Ubuntu 上,可以通过软件实现 RAID1:

  • 无须特殊硬件支持;

  • 两块硬盘无须大小一致;

  • 在分区时,两块硬盘划分大小一致的分区即可建立 RAID1;

因此,在服务器部署前,就应该对存储可靠性建立规划。如果硬件支持且有三块以上相同大小的硬盘,使用 RAID5。 如果硬件不支持,且有两块硬盘,建立 RAID1。

2. 备份软件

2.1. 软件安装

执行下面的命令,安装备份工具套件:

  • $ sudo aptitude install ossxp-backup

备份工具套件包括的组件有:

  • 群英汇相关软件

    • ossxp-backup: 群英汇备份工具

  • 自动安装的依赖软件

    • ossxp-linux-base: 群英汇 Linux 基础软件包

    • rdiff-backup: 镜像软件

    • flexbackup: 归档软件

    • ccrypt: 加密软件

2.2. 配置文件: /etc/cron.d/ossxp-backup

配置文件 /etc/cron.d/ossxp-backup, 定义备份任务的执行周期。

配置中包含下列计划任务:

  • 0   0  *   *   *    root  /opt/ossxp/bin/ossxp_backup -l info --set default --mirror
    0   5  *   *   *    root  /opt/ossxp/bin/ossxp_backup -l info --backup

说明:

  • 缺省该配置包含的计划任务处于注释状态(在行首用井号注释)

    • 管理员编辑该文件,删除行首的 # (井号)字符,打开相关的计划任务

  • 示例的第一行,即包含 --mirror 的行,是建立数据在本地的镜像,或者镜像数据到远程服务器,或者从远程服务器镜像数据到本地;

  • 示例的第二行,即包含 --backup 的行,是在本地建立归档。通常是将镜像数据压缩打包,以便进行光盘刻录或其他方式备份。

2.3. 配置文件: /opt/ossxp/conf/ossxp_backup_conf.py

2.3.1. 该配置文件中缺省已经定义了一个镜像任务:default

  • 缺省的镜像任务,自动扫描本机服务安装情况,自动创建需要镜像的文件和目录列表。并将这些需要镜像的文件和目录镜像到本地的 /backup/mirror/localhost

    • /!\ 注意镜像目录所在的分区是否拥有足够的磁盘空间,否则在有足够磁盘空间的卷建立镜像目录,手工创建链接到 /backup/mirror/localhost

      g_mirror['default']['dest_dir'] = '/backup/mirror/localhost'
  • 镜像目录中保存 3 个月的历史记录

    • g_mirror['default']['history'] = '3M'

2.3.2. 您也可以创建新的镜像任务

  • 创建新的任务集合 task1

    • g_mirror['task1'] = {}
  • 不保留历史数据,即只镜像最新数据

    • (!) 如果备份的数据源本身是一个包含历史数据的镜像目录,就直接备份最新拷贝即可

      g_mirror['task1']['history'] = '1B'
  • 设置镜像源的主机地址。(本例镜像源位于远程服务器)

    • (!) 本例使用 myaccount 用户,登录主机 192.168.0.100 的 SSH 端口

      g_mirror['task1']['src_host'] = 'myaccount@192.168.0.100'
  • 设置镜像源的目录

    • (!) 本例的目录,实际上是位于远程主机 192.168.0.100 的目录

      g_mirror['task1']['src_dir'] = '/backup/mirror/localhost'
  • 设置镜像源的目的地址

    • (!) 设置为 None 则为本机。

      g_mirror['task1']['dest_host'] = None
      g_mirror['task1']['dest_dir'] = '/backup/mirror/192.168.0.100'
  • 如果远程主机需要动态打开 SSH 端口,在备份执行前,需要先执行一条命令动态触发远程主机打开端口

    • g_mirror['task1']['precmd'] = 'curl -L -u username:password 192.168.0.100/ssh_open'
  • 综上,建立新的镜像任务的配置示例如下:

    • g_mirror['task1'] = {}
      ## The mirror source already has 3 months backup, so just 1B at here.
      g_mirror['task1']['history'] = '1B'
      g_mirror['task1']['src_host'] = 'myaccount@192.168.0.100'
      g_mirror['task1']['src_dir'] = '/backup/mirror/localhost'
      g_mirror['task1']['dest_host'] = None
      g_mirror['task1']['dest_dir'] = '/backup/mirror/192.168.0.100'
      g_mirror['task1']['options'] = '--no-eas --no-acls --no-carbonfile -b'
      g_mirror['task1']['precmd'] = 'curl -L -u username:password 192.168.0.100/ssh_open'

2.3.3. 数据归档相关参数设置

  • 每个归档目录保存多长时间的数据(缺省一个月)

    • # Backup period in every backup step. abbrivations:
      # m:minute, h:hour, D:Day, W:Week, M:Month, Y:year
      g_backup_period = '1M'
  • 总共建立几个归档目录?(缺省三个)

    • (!) 依次在这几个归档目录内进行循环备份,旧的备份数据会被新的备份数据替换

      # Backup rotate every backup period. How many backup copies for backup rotate.
      g_backup_copies = 3
  • 缺省每隔5个差异备份,建立一个增量备份

    • # How many incremental backup between every differential backups
      g_backup_diff_freq = 5
  • 归档的目标目录。(缺省归档目录为 /backup/archives)

    • /!\ 注意归档目录所在的分区是否拥有足够的磁盘空间,否则在有磁盘空间的卷建立归档目录,手工创建链接到 /backup/archives

      # parent backup directory
      g_backup_parent_dir = '/backup/archives'
  • 归档是否加密,以及加密的口令。(缺省使用内置口令加密)

    • ## if not set encrypt_passwd, using default secret
      g_backup_encrypt_passwd = 'secret'
      
      # encrypt backup files if True. (default False)
      g_backup_encrypt = True
  • 是否通过邮件发送镜像/备份通知?(缺省不发送邮件通知)

    • # Logger options:
      g_log_file = None
      g_log_mail = None
      #g_log_mail = {
      # 'host': 'localhost',
      # 'from': 'root@foo.bar',
      # 'to'  : 'root@foo.bar',
      # 'sub' : 'Backup log',
      # }
  • 缺省将整个 /backup/mirror 目录进行归档、打包

    • 如果要重新指定归档的源路径,修改配置文件 /etc/flexbackup.conf。修改方法参见 flexbackp 的帮助

3. 设定要备份的内容

3.1. 缺省备份的内容

  • 缺省备份整个 /etc 目录,以及群英汇部署的相关服务的数据。

  • 群英汇相关服务会在目录 /opt/ossxp/lib/packages/ 下自动创建相关配置文件,在该配置文件中定义了需要备份的文件。

  • 例如 ossxp-redmine 会创建配置文件 /opt/ossxp/lib/packages/ossxp-redmine.conf。其中包含如下的设置,会被备份软件自动识别。

    directory: /opt/redmine/files
    type: backup
    desc: User upload files...
    
    directory: /opt/redmine/web/config
    type: backup
    desc: Redmine config files
    
    directory: /opt/redmine/web/db
    type: backup
    desc: Default SQLite database
  • 查看缺省的镜像数据源目录,使用命令 /opt/ossxp/bin/ossxp_pkgadmin.py list_backup。示例如下:

    • $ sudo /opt/ossxp/bin/ossxp_pkgadmin.py list_backup
      /etc
      /opt/cosign/conf
      /opt/cosign/factor
      /opt/cosign/lib
      /opt/gosa/conf
      /opt/mailman/archives
      /opt/mailman/conf
      /opt/mailman/lists
      /opt/moin/conf
      /opt/moin/sites
      /opt/ossxp/conf
      /opt/ossxp/demoCA
      /opt/pysvnmanager
      /opt/redmine/files
      /opt/redmine/web/config
      /opt/redmine/web/db
      /opt/statsvn/conf
      /opt/svn/conf
      /opt/svn/svnroot
      /opt/testlink/upload
      /opt/testlink/web/config_db.inc.php
      /opt/testlink/web/custom_config.inc.php
      /opt/trac/conf
      /opt/trac/sites
      /opt/websvn/conf
      /var/lib/ldap
      /var/lib/mysql

3.2. 手动创建新的备份配置项

在目录 /etc/ossxp/packages/ 目录下的 *.conf 文件,是用户自定义的软件配置文件,可以参照 /opt/ossxp/lib/packages/ 下的文件创建。

例如:subversion 的备份目录除了缺省的 /opt/svn/svnroot 外,假如还包括 /opt/svn/svnroot2 目录。可以在 /etc/ossxp/packages/ 下创建文件 subversion.conf,内容如下:

  • directory: /opt/svn/svnroot2
    type: backup

4. 数据镜像

4.1. 本地镜像

: 为什么要在本机建立数据镜像?难道 RAID5 不是已经足够安全了么?

: 管理员对配置文件的错误配置,或者管理员对文件的误删除,会导致无法数据无法恢复。这时,如果有本机的数据镜像,管理员可以非常方便的从镜像的数据恢复误删除或者配置错误的文件。

编辑配置文件 /etc/cron.d/ossxp-backup,打开相关行的注释,如下所示:

  • 0   0  *   *   *    root  /opt/ossxp/bin/ossxp_backup -l info --set default --mirror

于是,就会在每天晚上 0:00 执行缺省(default)镜像集的镜像

4.2. 远程镜像

远程镜像支持:

  • 将远程服务器的数据,镜像到本地

  • 将本地数据,镜像到远程服务器

修改配置文件 /opt/ossxp/conf/ossxp_backup_conf.py,建立新的镜像集,如前所述,可以实现上述功能。

5. 数据归档

虽然镜像实现了数据的本地多份拷贝,也能实现双机异地备份,但是镜像的数据没有加密,也没有打包存档,不便于光盘刻录或者导入到其他外部的备份设备中。

5.1. 执行数据归档

编辑配置文件 /etc/cron.d/ossxp-backup,打开相关行的注释,如下所示:

  • 0   5  *   *   *    root  /opt/ossxp/bin/ossxp_backup -l info --backup

于是,就会在每天晚上 5:00 执行对目录 /backup/mirror 的归档,归档自动保存在 /backup/archives 目录下。归档的具体配置参见之前的描述。

5.2. 数据归档的下载

  • 权限分配

    • 使用群英汇的用户管理平台,为备份管理员设定 backup 权限。

  • 设置 web folder 目录名称

    • 在配置文件 /etc/apache2/include/https/web_folder.conf 中设定备份目录的 web folder 名称。

      • Alias /backup-20091122 "/backup/archives/"
  • 管理员用资源管理器打开 Web folder: https://hostname/backup-20091122

    • 可以直接通过资源管理器将归档文件下载到本地。

  • 数据归档缺省加密存储,加密口令由管理员在配置文件中设定。具体参见之前的描述。

6. 数据恢复

实际上数据镜像采用的格式为 rdiff-backup 格式。恢复数据可以直接拷贝,或者使用 rdiff-backup 命令。

  • 最新数据的恢复

    • 镜像数据的目录结构和源数据的目录结构相同,最新数据可以直接从相应目录拷贝即可。 例如恢复文件: /opt/moin/sites/default/data/edit-log:

      $ sudo cp /backup/mirror/localhost/data/opt/moin/sites/default/data/edit-log .
  • 查看某个文件的镜像版本历史

    • $ sudo rdiff-backup -l /backup/mirror/localhost/data/opt/moin/sites/default/data/edit-log
      Found 11 increments:
          edit-log.2009-11-12T00:00:02+08:00.diff.gz   Thu Nov 12 00:00:02 2009
          edit-log.2009-11-13T00:00:01+08:00.diff.gz   Fri Nov 13 00:00:01 2009
          edit-log.2009-11-14T00:00:01+08:00.diff.gz   Sat Nov 14 00:00:01 2009
          edit-log.2009-11-15T00:00:02+08:00.diff.gz   Sun Nov 15 00:00:02 2009
          edit-log.2009-11-16T00:00:01+08:00.diff.gz   Mon Nov 16 00:00:01 2009
          edit-log.2009-11-17T00:00:02+08:00.diff.gz   Tue Nov 17 00:00:02 2009
          edit-log.2009-11-18T00:00:01+08:00.diff.gz   Wed Nov 18 00:00:01 2009
          edit-log.2009-11-19T00:00:02+08:00.diff.gz   Thu Nov 19 00:00:02 2009
          edit-log.2009-11-20T00:00:02+08:00.diff.gz   Fri Nov 20 00:00:02 2009
          edit-log.2009-11-22T00:00:02+08:00.diff.gz   Sun Nov 22 00:00:02 2009
          edit-log.2009-11-23T00:00:01+08:00.diff.gz   Mon Nov 23 00:00:01 2009
      Current mirror: Tue Nov 24 00:00:01 2009
  • 查看某个目录最近5天更改的历史

    • $ sudo rdiff-backup --list-changed-since 5D /backup/mirror/localhost/data/opt/moin/sites/default/data/user
      changed data/opt/moin/sites/default/data/user/1252857373.54.51824
      changed data/opt/moin/sites/default/data/user/1252906648.24.36529
      changed data/opt/moin/sites/default/data/user/1252994123.2.11621
      changed data/opt/moin/sites/default/data/user/1252995917.56.41998
  • 恢复某个文件的某个版本

    • 恢复最新版本

      • $ sudo rdiff-backup -r now /backup/mirror/localhost/data/opt/moin/sites/default/data/edit-log /tmp/edit-log
        $ sudo diff /tmp/edit-log  /opt/moin/sites/default/data/edit-log
        1342a1343,1344
        > 1259028246000000      00000058        SAVE    (e7a094e58f91e983a8e694afe587bae4b880e8a788e8a1a82f)Others      192.168.0.66    192.168.0.66    1252906648.24.36529
        > 1259028278000000      00000059        SAVE    (e7a094e58f91e983a8e694afe587bae4b880e8a788e8a1a82f)Others      192.168.0.66    192.168.0.66    1252906648.24.36529

        (!) 之所以恢复出来的文件和当前文件不一致,是因为镜像数据是上一次镜像执行时(0:00)的数据,新的数据已经变更。

    • 恢复 10 天前的版本

      • $ sudo rdiff-backup -r 10D /backup/mirror/localhost/data/opt/moin/sites/default/data/edit-log /tmp/edit-log

更多相关帮助,参见: http://rdiff-backup.nongnu.org/


群英汇帮助类