Mysql 的数据如何备份

假设将生产环境的数据库数据备份到云服务器,备份则采用同步文件的办法。

可用于备份的数据文件有两类,一是 mysqldump 出来的 sql 文件,二是 mysql 服务程序运行所依靠的文件。

同步 sql 文件的好处是可以查看和编辑,以及直接运行,是真实的数据库逻辑层文件。而坏处则是可能文件会极大,如果需要真正用文本编辑器打开这类文件的话可能会比较困难,因此实际上也只是起到一个保存的作用,并非完全可读。而采用直接备份服务程序运行所依赖的数据文件则又可能完全复刻真实 mysql 服务的运行条件,再运行一个简单实例则可以做到实时查看和执行,也不失为良策。我们这里主要用到备份数据库运行文件的办法。

假设待备份的数据库运行文件统一保存在 /var/lib/mysql 目录下。

我们需要能够找到一种方法,能够通过运行一条简单命令,将最新文件同步到远程的云服务器上。

我们用到 rsync 这个软件,结合当前的数据库服务器环境来操作。

权限问题

用户权限

运行 rsync 软件的用户为当前登录用户,它不宜直接采用 root 权限。这样做是为了采用最小的权限以尽可能保证系统安全。同时,当前登录用户亦应为启动 mysql 服务之用户,使其具有专门用途,与日常维护相区分,方便于管理。

假设 /var/lib/mysql 的所有者和所有组皆为 systemd-coredump,那么为了让当前用户获得该文件夹的所有文件的访问权,需要设置相关权限。

假设当前登录用户名为 foo。

设置 foo 的在组,使其具备 systemd-coredump 组。

sudo usermod -aG systemd-coredump foo

如果一不小心设置反了,即参数顺序搞错,那么可以利用 gpasswd 命令设置回。如

sudo gpasswd -d systemd-coredump foo

现在当前登录用户 foo 已经具备了 systemd-coredump 组的权限。但是这里还有一个问题,那就是需要当前 session 登录的所有用户退出之后,这个刚刚新加入的组别才能正式生效。如果遇到异常,可以通过重新登录一个 session 来对照着测试一下,而当使用了 tmux 软件时,需要确保 tmux 中的用户也退出登录了,再重新登录回来。

如何使当前登录用户具备对文件夹下 /var/lib/mysql 的完整备份权限,即访问和读取权限。需要特别设置一下这个文件夹下面对组的权限。

原则上让目标文件夹下面的所有文件和目录在组的权限和所有者的权限上保持一致,这样具备了组的用户则得到了同文件所有者相同的权限。

让所有文件夹都具备组的读写和执行权限。

find . -mindepth 1 -type d -exec chown g+rwx {} \;

需要注意如果文件夹不具备执行权限而只具备可读权限,那么访问该文件夹时,可能文件夹里面的内容不能获得文件名信息,表现为 ls 输出为 ?? 类型的乱码。

设置好以后,通过 ls 命令来测试对应文件夹中某些文件的读取权限。

测试用户组别,可以通过 id 命令来查看用户所属组。也可以通过 groups 命令来查看。

现在我们已经让当前登录的此目标用户得到了对于 /var/lib/mysql 文件夹目录的读取权限。接下来我们可以设置云服务器端的目标目录。

和源程序数据目录保持一致,目标目录也是 /var/lib/mysql,我们手动创建这个文件夹,并设置其所有者和组别。

通过 mkdir 命令创建 /var/lib/mysql 时,需要 root 权限,所以最初文件的所有者是 root:root,而实际上 mysql 服务器运行这些数据库文件时需要用到的用户是编号 999 的用户,根据实际情况有所差别。这个 999 用户,在不同的系统中可能有不同的用户名和组名。在当前云服务器上,999 对应的用户为 lxd, 999 对应的组别为 docker。rsync 通过参数可以同步文件属性。我们希望目标目录具备让 foo 用户访问的设置,显然在云服务器上 foo 用户和 lxd 用户不一样,我们可以通过 chown -R 命令来设置所有者。这样,传送文件所用的用户 foo 则具备了对于目标文件夹的访问写入权限。

然而需要防范云服务器上的数据库程序在重新启动后,再一次将 /var/lib/mysql 中的文件所有者改回程序默认的用户设置。可以通过指定 docker 启动的用户来绑定程序数据的用户名和组别。具体的在 docker-compose.yml 文件中可以指定 user: <用户名ID>:<组别ID 999>,如果直接指定的是用户名而非用户名ID,则可能出现 docker 容器中找不到指定用户名的情形,在 /etc/passwd 文件中。所以通过设置一个 host 系统的传输文件用的 foo 用户对应的用户名ID就可以了。

rsync 命令牵线搭桥

利用 Rsync 软件传送/同步文件。

假设远程云服务器的域名为 remotehost.com,那么

rsync -avz /var/lib/mysql/ remotehost.com:/var/lib/mysql

如备份文件和源文件两处编辑不一样的表,则可以加上 --update 选项,避免备份文件的改动被覆盖丢弃。

命令执行成功了吗,

打包 mysql docker 服务端程序可以用 zip 命令,

zip -r a.zip mysql-app/

最后一步检查传送同步到的文件是否完整,是否可用。

数据版本记录

// 运行 git commit
async function runGitVersionCommand() {
  let r = await runCommand(`ssh b.example.com 'cd /var/lib/mysql; git add . -A && git commit -m "$(TZ=Asia/Shanghai date)"'`);
  return r;
}

假设在备份服务器的数据目录根目录下 init 一个 git 仓库,用于控制数据的版本,不知是否有意义。以时间为备注信息,如

[master 4aeafb4] Sat Aug  5 09:30:07 PM CST 2023
 9 files changed, 0 insertions(+), 0 deletions(-)
关于本文如您有任何想法和意见,欢迎与我们联系,邮箱地址zhi@uqugu.com
您对本文有什么看法,喜欢或者不喜欢都可以发表意见。