25、数据备份全攻略:从光盘到数据库

数据备份全攻略:从光盘到数据库

1. 光盘刻录验证

在完成 CD 或 DVD 刻录后,验证刻录内容能否正确读取是很有必要的。因为光盘介质可能存在缺陷,或者在刻录过程中计算机受到碰撞,导致激光偏离轨道。

验证刻录的正确方法有两种:一是比较刻录的扇区与硬盘上的扇区;二是生成这些扇区的校验和并进行比较。这两种方法都只能用于实际的数据扇区,而不是填充扇区。

以下是一个 bash 脚本,当原始 ISO 镜像文件可用时,它可以轻松完成验证工作:

#!/bin/bash
if [[ $# -lt 1 ]] ; then
    echo "usage: isomd5 <file_or_device> ..." 1>&2
    exit 1
fi
for name in "$@" ; do
    isoinfo -di "${name}" 1>/dev/null || exit 1
done
for name in "$@" ; do
    count=( $( isoinfo -di "${name}"    \
        | egrep "^Volume size is: " ) )
    count="${count[3]}"
    bsize=( $( isoinfo -di "${name}"    \
        | egrep "^Logical block size is: " ) )
    bsize="${bsize[4]}"
    md5=$( dd                           \
        if="${name}"                    \
        ibs="${bsize}"                  \
        obs=4096 count="${size}"        \
        2>/tmp/isomd5.$$.err            \
        | md5sum )
    if [[ $? != 0 ]] ; then
        cat /tmp/isomd5.$$.err
        rm -f /tmp/isomd5.$$.err
        exit 1
    fi
    rm -f /tmp/isomd5.$$.err
    echo "${md5:0:32}" "" "${name}"
done

这个脚本通过获取 ISO 文件系统在镜像文件中使用的扇区数量来工作。它将读取到 MD5 校验和哈希程序中的扇区数量精确限制为实际使用的数量,避免读取可能数量不同的填充扇区。

我们将这个脚本命名为 isomd5 。使用时,提供 ISO 镜像文件的名称以及通常用于读取 CD - R 的 CD 设备名称(插入新刻录的 CD - R),你会得到类似以下的结果:

amy@desk12:~$ isomd5 backup.iso /dev/sr0
d41d8cd98f00b204e9800998ecf8427e backup.iso
d41d8cd98f00b204e9800998ecf8427e /dev/sr0
amy@desk12:~$

MD5 程序生成的校验和是 32 个字符的十六进制部分。如果 ISO 镜像文件和 CD - R 驱动器内容的校验和不同,则刻录存在缺陷。

如果刻录失败,可按以下步骤尝试解决:
1. 使用另一张空白光盘重新刻录。
2. 降低刻录速度。
3. 使用不同批次或品牌的空白光盘。

如果问题仍然存在,可能是刻录驱动器有缺陷。

2. 磁带备份与 Amanda

磁带仍然是一种流行的备份介质。Advanced Maryland Automated Network Disk Archiver(Amanda)是一个开源软件包,用于管理磁带备份。它由马里兰大学开发,包含在许多 Linux 发行版中,如 Debian。

Amanda 具有以下特点:
- 使用传统的 Unix 备份格式,如 tar 和 dump。
- 可通过局域网运行,将客户端数据备份到中央磁带服务器。
- 支持通过文件共享备份 Windows 客户端。
- 支持标准磁带设备以及许多磁带更换器、自动加载器和堆叠器。
- 能够在多天的备份周期内平衡全量备份。
- 支持增量备份,记录每日更改。
- 可在客户端或服务器上进行数据压缩,也支持具有硬件压缩功能的设备。
- 防止意外覆盖错误的介质。
- 采用存储磁盘策略,允许分阶段或延迟写入介质。
- 通过 Kerberos 或其自身的认证方案进行身份验证。
- 对不安全网络上的数据进行加密保护。

2.1 安装 Amanda

Amanda 有客户端和服务器组件。客户端用于需要备份数据的系统,服务器用于执行备份工作并将数据写入磁带。

在备份服务器上安装 Amanda,运行以下命令:

# apt-get install amanda-server

在每个 Linux 客户端机器上安装 Amanda,运行以下命令:

# apt-get install amanda-client

安装这些软件包时,会自动包含所需的其他软件包。如果需要使用 Amanda 中的 amplot 程序,则还需要安装 gnuplot 软件包。

Amanda 使用多个不同目录中的文件,这些设置可以配置,默认设置如下:
| 目录 | 说明 |
| ---- | ---- |
| /etc/amanda | 配置文件(服务器) |
| /root | /root/.amandahosts 文件 |
| /usr/man/man8 | 手册页 |
| /usr/share/doc/amanda - common | 文档文件 |
| /usr/share/doc/amanda - client | 客户端特定的文档文件 |
| /usr/lib | Amanda 程序使用的共享库 |
| /usr/lib/amanda | 守护程序和内部实用程序 |
| /usr/sbin | 命令程序 |
| /var/lib/amanda | 运行状态、日志和其他文件 |

2.2 配置 Amanda

2.2.1 编辑 /etc/services 文件

该文件应包含以下名称和端口号的条目。如果这些条目不存在,需要编辑 /etc/services 文件并在末尾添加它们,注释是可选的:

amanda          10080/udp       # amanda backup services
amandaidx       10082/tcp       # amanda backup services
amidxtape       10083/tcp       # amanda backup services
2.2.2 编辑 /etc/inetd.conf 文件

该文件应包含以下条目:

# 客户端
amanda    dgram  udp wait   backup /usr/sbin/tcpd /usr/lib/amanda/amandad
# 服务器
amandaidx stream tcp nowait backup /usr/sbin/tcpd /usr/lib/amanda/amindexd
amidxtape stream tcp nowait backup /usr/sbin/tcpd /usr/lib/amanda/amidxtaped

名为 amanda 的条目是所有客户端都需要的,另外两个条目仅服务器需要。如果这些行不存在,需要编辑 /etc/inetd.conf 文件并在末尾添加它们。

Amanda 在初始通信后使用随机端口,因此建议仅通过 VPN 在互联网上使用 Amanda,这样可以避免从互联网向局域网开放大量端口。

Amanda 以用户 backup 的身份运行,具有磁盘组权限。需要为所有要备份的文件设置访问权限,以便 Amanda 能够读取它们。

Amanda 服务器需要与本地网络良好连接,具备足够的带宽来传输数据。它应该有一个非常大的存储磁盘,其空间应足够容纳最大单次转储大小的两倍。如果服务器要进行软件压缩,还需要一个快速的 CPU。

Amanda 支持多种配置,每个配置由 /etc/amanda 子目录中的三个文件组成:
- amanda.conf:主配置文件,用于指定磁盘列表(见下一项)、磁带设备、备份频率、电子邮件地址、报告格式等大量选项。
- disklist:指定要备份的主机和磁盘。
- tapelist:列出活动磁带,包括每次写入的日期。Amanda 会管理这个文件,你可以查看但不要编辑它。

2.3 恢复 Amanda 备份的文件

Amanda 使用标准的 Unix 备份格式(tar 或 dump),你可以在配置文件中指定。这意味着即使没有 Amanda 系统,备份磁带也可用于恢复系统文件,这在完全磁盘故障后恢复文件时至关重要。

Amanda 还提供索引恢复工具,允许恢复选定的文件。确保配置 index yes 以让 Amanda 创建所需的索引文件, amrecover 手册页提供了详细信息。

2.4 DVD 备份

本节中介绍的步骤主要针对 CD 介质,但 DVD 介质也可以使用 cdrecord cdrtools 软件包中的相同软件以类似方式进行刻录。一些 DVD 介质,如罕见的 DVD - RAM,可以像硬盘一样工作,但需要支持这种操作模式的特殊驱动器。

以下是 Amanda 备份的流程图:

graph LR
    A[安装 Amanda 服务器和客户端] --> B[配置 /etc/services 文件]
    B --> C[配置 /etc/inetd.conf 文件]
    C --> D[设置文件访问权限]
    D --> E[配置 Amanda 服务器参数]
    E --> F[创建 Amanda 配置文件]
    F --> G[进行备份操作]
    G --> H[生成备份报告]
    H --> I[定期审查报告]
    I --> J{是否需要恢复文件}
    J -- 是 --> K[使用索引恢复工具恢复文件]
    J -- 否 --> L[继续备份循环]

3. MySQL 数据备份

到目前为止,我们讨论了文件和目录的备份。数据库有一些特殊的情况需要处理。我们的示例使用 MySQL,但相同的原则也适用于 PostgreSQL 和其他关系型数据库。

3.1 离线备份

如果你的 MySQL 服务器不需要 24x7 可用,一种快速简单的离线原始备份方法如下:
1. 停止 MySQL 服务器:

# /etc/init.d/mysqld stop
  1. 复制 MySQL 的数据文件和目录。例如,如果你的 MySQL 数据目录是 /var/lib/mysql ,并想将其保存到 /tmp/mysql - backup
# cp -r /var/lib/mysql /tmp/mysql-backup

你也可以使用 rsync tar gzip 或本章前面提到的其他命令代替 cp
3. 再次启动服务器:

# /etc/init.d/mysqld start

3.2 在线备份

在线备份更复杂。如果你的 MyISAM 表相互独立(没有外键或事务),可以依次锁定每个表,复制其文件,然后解锁。但你可能有 InnoDB 表,或者有人可能会写入涉及多个表的事务。幸运的是,有几种合理的非商业解决方案,包括 mysqlhotcopy mysqlsnapshot 、复制和 mysqldump

3.2.1 mysqlhotcopy

mysqlhotcopy 是一个 Perl 脚本,用于对 ISAM 或 MyISAM 表进行在线原始备份。手册页包含许多选项,以下是如何备份名为 drupal 的单个数据库的示例:

# mysqlhotcopy -u user -p password drupal /tmp

运行结果可能如下:

Locked 57 tables in 0 seconds.
Flushed tables (`drupal`.`access`, `drupal`.`accesslog`, `drupal`.`aggregator_category`, `drupal`.`aggregator_category_feed`, `drupal`.`aggregator_category_item`, `drupal`.`aggregator_feed`, `drupal`.`aggregator_item`, `drupal`.`authmap`, `drupal`.`blocks`, `drupal`.`book`, `drupal`.`boxes`, `drupal`.`cache`, `drupal`.`client`, `drupal`.`client_system`, `drupal`.`comments`, `drupal`.`contact`, `drupal`.`file_revisions`, `drupal`.`files`, `drupal`.`filter_formats`, `drupal`.`filters`, `drupal`.`flood`, `drupal`.`forum`, `drupal`.`history`, `drupal`.`locales_meta`, `drupal`.`locales_source`, `drupal`.`locales_target`, `drupal`.`menu`, `drupal`.`node`, `drupal`.`node_access`, `drupal`.`node_comment_statistics`, `drupal`.`node_counter`, `drupal`.`node_revisions`, `drupal`.`permission`, `drupal`.`poll`, `drupal`.`poll_choices`, `drupal`.`poll_votes`, `drupal`.`profile_fields`, `drupal`.`profile_values`, `drupal`.`role`, `drupal`.`search_dataset`, `drupal`.`search_index`, `drupal`.`search_total`, `drupal`.`sequences`, `drupal`.`sessions`, `drupal`.`system`, `drupal`.`term_data`, `drupal`.`term_hierarchy`, `drupal`.`term_node`, `drupal`.`term_relation`, `drupal`.`term_synonym`, `drupal`.`url_alias`, `drupal`.`users`, `drupal`.`users_roles`, `drupal`.`variable`, `drupal`.`vocabulary`, `drupal`.`vocabulary_node_types`, `drupal`.`watchdog`) in 0 seconds.
Copying 171 files...
Copying indices for 0 files...
Unlocked tables.
mysqlhotcopy copied 57 tables (171 files) in 1 second (1 seconds overall).
3.2.2 mysqlsnapshot

mysqlsnapshot 更简单。它将服务器上的所有 ISAM 或 MyISAM 表备份到每个数据库一个 tar 文件:

# ./mysqlsnapshot -u user -p password -s /tmp --split -n

运行结果可能如下:

checking for binary logging... ok
backing up db drupal... done
backing up db mysql... done
backing up db test... done
snapshot completed in /tmp

你可以在 http://jeremy.zawodny.com/mysql/mysqlsnapshot 找到 mysqlsnapshot

3.2.3 复制备份

如果你为 24x7 可用性设置了 MySQL 复制,可以使用前面描述的方法从从服务器进行备份。你还需要保存复制信息(日志、配置文件等)。具体细节可参考 Jeremy D. Zawodny 和 Derek J. Balling 所著的《High Performance MySQL》的第 7 章和第 9 章。

为了防止硬件损坏(但不能防止人为错误),可以设置复制并为从服务器(和/或主服务器)提供 RAID 1(镜像)磁盘。

3.2.4 mysqldump

mysqldump 通常是大多数文档中首先提到的方法。它不是进行原始复制,而是生成指定数据库和表的 ASCII 转储。它适用于所有 MySQL 表类型,包括 InnoDB。它相对较慢,生成的文本文件较大,但压缩效果较好。定期创建这些转储很有用,因为它们包含从头重新创建数据库和表的简单脚本。你可以使用编辑器、 grep 和其他文本工具来搜索或修改转储文件。

要锁定所有表并将它们转储到单个文件,输入:

# mysqldump -u user -ppassword -x --all - databases > /tmp/mysql.dump

你可以通过 gzip 管道输出以节省时间和空间:

# mysqldump -u user -ppassword -x --all - databases | gzip > /tmp/mysql.dump.gz
3.2.5 Zmanda Recovery Manager for MySQL

一个名为 Zmanda Recovery Manager for MySQL 的新开源工具(免费下载,付费支持)为上述许多方法提供了一个有用的前端。Zmanda 网站 http://www.zmanda.com/backup - mysql.html 提供了详细信息,以下是它的一些显著特点:
- 具有命令行界面。
- 备份本地数据库或通过 SSL 备份远程数据库。
- 通过电子邮件发送备份过程的状态。
- 处理所有表类型,包括 InnoDB。
- 不提供任何新的备份方法,而是在 mysqldump mysqlhotcopy 、MySQL 复制或 LVM 快照中进行选择。
- 支持恢复到特定的事务或时间点。

Zmanda 为许多 Linux 发行版提供 .tar.gz .rpm 文件。关于在 Debian 上的安装指南,请参考 http://www.howtoforge.com/mysql_zrm_debian_sarge

以下是 MySQL 数据备份方法的比较表格:
| 备份方法 | 适用场景 | 优点 | 缺点 |
| ---- | ---- | ---- | ---- |
| 离线备份 | MySQL 服务器不需要 24x7 可用 | 简单快速 | 需要停止服务器,影响服务可用性 |
| mysqlhotcopy | ISAM 或 MyISAM 表在线备份 | 速度较快 | 仅适用于 ISAM 或 MyISAM 表 |
| mysqlsnapshot | ISAM 或 MyISAM 表在线备份 | 操作简单 | 仅适用于 ISAM 或 MyISAM 表 |
| 复制备份 | 24x7 可用性场景 | 可在不影响主服务器的情况下备份 | 需要额外的服务器资源和配置 |
| mysqldump | 所有 MySQL 表类型 | 可生成 ASCII 转储,便于处理 | 速度慢,生成文件大 |
| Zmanda Recovery Manager for MySQL | 综合备份需求 | 提供前端工具,支持多种备份方法和恢复方式 | 需要付费支持 |

以下是 MySQL 数据备份的流程图:

graph LR
    A{是否需要 24x7 可用} -- 否 --> B[离线备份]
    A -- 是 --> C{表类型}
    C -- ISAM 或 MyISAM --> D{备份方式选择}
    D -- 简单快速 --> E[mysqlhotcopy]
    D -- 更简单 --> F[mysqlsnapshot]
    C -- 包含 InnoDB --> G[mysqldump]
    H[设置复制] --> I[复制备份]
    J[使用 Zmanda] --> K[Zmanda 综合备份]
    B --> L[完成备份]
    E --> L
    F --> L
    G --> L
    I --> L
    K --> L

4. bash 脚本示例

4.1 添加用户脚本

如果你有大量人员流动(例如在大学,每年有一批或几批新学生入学),这个脚本可以帮助你快速将他们添加到系统中。它读取一个列出每个用户信息的文件,并使用正确的参数调用 useradd

#!/bin/bash
expiredate=2009 - 02 - 18
if [[ -z "$1" ]] ; then
    echo ""
    echo "Please give exactly one file name."
    echo "The file will have one user per line."
    echo "Each line will have:"
    echo "    username"
    echo "    group"
    echo "    personal real name"
    echo ""
    echo "Sample line:"
    echo "alfredo marketing Alfredo de Darc"
    exit 1
fi
cat "$1" | while read username groupname realname
do
    # Skip blank lines.
    if [[ -z $username || -z $groupname || -z $realname ]]; then
        continue
    fi
    # Check whether the user already exists.
    # If so, report this and skip this user.
    result=$( egrep "^$username:" < /etc/passwd )
    if [[ -n "$result" ]] ; then
        echo "User '$username' already exists"
        continue
    fi
    # Check whether the group already exists.
    # If not, add the group.
    result=$( egrep "^$groupname:" < /etc/group )
    if [[ -z "$result" ]] ; then
        groupadd "$groupname"
    fi
    # Add the user.
    useradd    -c "$realname" \
        -d "/home/$username"  \
        -e "$expiredate"      \
        -f 365                \
        -g "$groupname"       \
        -m                    \
        -s /bin/bash          \
        "$username"
    if [[ $? == 0 ]]; then
        echo "Successfully added user '$username'."
    else
        echo "Error adding user '$username' (group \
             '$groupname', real name '$realname')"
        exit 1
    fi
done

4.2 随机密码生成器脚本

这是一个生成任意长度 ASCII 字符密码的脚本:

#!/bin/bash
n="$1"
[[ -n "$n" ]] || n=12
if [[ $n -lt 8 ]]; then
    echo "A password of length $n would be too weak"
    exit 1
fi
p=$( dd if=/dev/urandom bs=512 count=1 2>/dev/null \
    | tr -cd 'a-zA-Z0-9' \
    | cut -c 1 - $n )
echo "${p}"

这个脚本的工作原理如下:
1. 脚本以通常的起始注释开始,告诉系统运行 bash 解释器。
2. 将第一个参数字符串分配给变量 n ,它将是要生成的字符数。如果脚本在没有参数的情况下运行, n 可能是一个空字符串,因此我们将其放在引号中。
3. 测试该字符串是否为空。 -n 参数表示“非零长度”,如果给出了字符串,测试为真。
4. 如果测试失败,将执行后面的赋值,强制密码的默认长度为 12。
5. 接下来的四行检查给定的长度是否太小,我们认为最小长度应该是 8。
6. 循环体中的第一个语句使用三个系统命令的管道生成一个试验密码。管道中的所有三行都放在 $( ) 中,以将输出捕获为字符串,然后分配给变量 p
7. 为了生成随机密码,我们需要一个随机数据源,系统通过将各种统计源组合到 /dev/urandom 伪设备中来提供。 dd 命令从该设备读取一些二进制数据。
8. tr 命令使用 -cd 选项删除不在 a - z A - Z 0 - 9 范围内的所有字符。
9. 管道中的最后一个命令 cut 提取所需数量的字符。

在编写这样的脚本时,应该留下描述代码目的的注释。注释应分为两部分:头部的概述(例如,说明传递给脚本的参数应该指定什么,以及任何默认值),以及在难以理解的过程附近的明确解释。

综上所述,无论是光盘刻录验证、磁带备份、MySQL 数据备份还是编写实用的 bash 脚本,掌握这些数据备份和管理的方法和工具,能够帮助我们更好地保护重要数据,应对各种可能的数据丢失风险。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值