AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 805257
Accepted
Andy Shulman
Andy Shulman
Asked: 2016-09-26 16:46:50 +0800 CST2016-09-26 16:46:50 +0800 CST 2016-09-26 16:46:50 +0800 CST

通过 ZFS 快照备份 MySQL 数据库

  • 772

我发现许多网站都在谈论这样做,但我错过了一些重要的细节。一般步骤是

  • 跑FLUSH TABLES WITH READ LOCK
  • 拍摄 ZFS 快照
  • 跑UNLOCK TABLES

各种消息来源报告说,我正在使用的 InnoDB 实际上并不支持FLUSH. MySQL 用户手册指出有一个FLUSH TABLES...FOR EXPORT用于 InnoDB 的变体,但这需要单独指定每个表,而不是备份整个数据库。我宁愿避免单独指定每个表,因为表列表很有可能与实际存在的表不同步。

我遇到的另一个问题是我计划做类似的事情mysql -h"$HOST" -u"$USERNAME" -p"$PASSWORD" --execute="FLUSH TABLES WITH READ LOCK"。但是,这会在会话退出后立即解除锁定。这是有道理的,但也很烦人,因为我在拍摄快照时需要持有读锁。

我的另一个想法是使用 Percona XtraBackup 之类的工具进行热备份并拍摄备份快照,但我不想支付将所有数据写入第二个位置的成本,只是为了对其进行快照。

backup mysql freebsd zfs innodb
  • 6 6 个回答
  • 6461 Views

6 个回答

  • Voted
  1. Ryan Babchishin
    2016-09-26T19:15:19+08:002016-09-26T19:15:19+08:00

    您需要一个完整的数据库锁来一致地备份(大多数)数据库。

    手册https://dev.mysql.com/doc/refman/5.5/en/backup-methods.html说FLUSH TABLES WITH READ LOCK特别适用于 ZFS 快照。

    使用文件系统快照进行备份

    如果您使用的是 Veritas 文件系统,则可以像这样进行备份:

    1. 从客户端程序中,执行FLUSH TABLES WITH READ LOCK.
    2. 从另一个 shell 执行挂载vxfs快照。
    3. 从第一个客户端,执行UNLOCK TABLES.
    4. 从快照复制文件。
    5. 卸载快照。

    类似的快照功能可能在其他文件系统中可用,例如 LVM 或 ZFS。

    他们从这些说明中忽略了您FLUSH TABLES table_a, table_b, table_c FOR EXPORT需要InnoDB的事实,这有点荒谬。必须像这样指定每个表也是愚蠢的。但正如 EEAA 所说,您可以在开始备份时相当轻松地生成一个表列表。

    至于持有锁,您必须在执行快照时保持数据库连接处于活动状态

    一般来说,我会使用 Perl 或其他可以连接、锁定数据库并在保持数据库连接的同时拍摄快照、然后解锁和断开连接的编程语言。这并不复杂。我敢打赌,已经有工具可以做到这一点,但编写一个很容易。

    我说了几次简单,不复杂等。我假设你有一些基本的编程或良好的脚本技能。

    • 14
  2. Michael Hampton
    2016-09-26T23:20:47+08:002016-09-26T23:20:47+08:00

    我在 Bash 中抄袭并改编了一个概念上简单的脚本,我在Tobia的另一篇 Server Fault帖子中找到了该脚本。它应该能让你到达那里的大约 90%。

    mysql_locked=/var/run/mysql_locked
    
    # flush & lock MySQL, touch mysql_locked, and wait until it is removed
    mysql -hhost -uuser -ppassword -NB <<-EOF &
        flush tables with read lock;
        delimiter ;;
        system touch $mysql_locked
        system while test -e $mysql_locked; do sleep 1; done
        exit
    EOF
    
    # wait for the preceding command to touch mysql_locked
    while ! test -e $mysql_locked; do sleep 1; done
    
    # take a snapshot of the filesystem, while MySQL is being held locked
    zfs snapshot zpool/$dataset@$(date +"%Y-%m-%d_%H:%M")
    
    # unlock MySQL
    rm -f $mysql_locked
    

    在这里,mysql您使用的命令在后台运行并触及文件。它在后台等待文件消失,然后退出并解锁表。同时主脚本等待文件存在,然后创建快照并删除文件。

    所指向的文件$mysql_locked需要两台机器都可以访问,你应该能够很容易地做到这一点,因为它们都可以访问一个公共数据集(尽管它们可能使用不同的路径,你应该考虑到这一点)。

    • 8
  3. Best Answer
    Gea-Suan Lin
    2016-10-01T02:57:48+08:002016-10-01T02:57:48+08:00

    如果您只对所有表使用 InnoDB 并设置innodb_flush_log_at_trx_commit为:

    • 1(InnoDB 日志缓冲区的内容在每次事务提交时被写入日志文件,并且日志文件被刷新到磁盘)或者,
    • 2(InnoDB 日志缓冲区的内容在每次事务提交后写入日志文件,并且日志文件大约每秒刷新一次到磁盘),

    那么在做快照之前你不需要 FLUSH TABLES,直接运行 ZFS 快照。InnoDB 可以从事务提交日志中恢复数据而不会丢失数据。

    参考:https ://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit

    • 7
  4. Petr Stastny
    2017-12-09T07:28:37+08:002017-12-09T07:28:37+08:00

    这是我如何在保持锁定的同时创建 ZFS 快照的解决方案:

    mysql << EOF
        FLUSH TABLES WITH READ LOCK;
        system zfs snapshot data/db@snapname
        UNLOCK TABLES;
    EOF
    
    • 4
  5. Jim Salter
    2016-09-27T10:38:49+08:002016-09-27T10:38:49+08:00

    对于 myisam,您需要 FLUSH TABLES WITH READ LOCK,因为它不是日志记录。

    IMO,您根本不需要任何用于 innodb 的东西,因为它是日志。无论如何它都会保持一致,如果在您快照的原子瞬间发生任何事情,它就会自动回滚日志。

    如果您想要应用程序级别的一致性,您的应用程序应该使用事务。如果您的应用程序使用事务和 innodb,任何快照都将一致地自动询问应用程序级别的方式。

    • 3
  6. Bodo
    2020-07-27T01:27:09+08:002020-07-27T01:27:09+08:00

    由于几年前我们在 innoDB 的 FLUSH TABLES WITH READ LOCK 上也遇到了问题,而且我们也不想依赖 innoDB 从不一致的数据文件中恢复的能力,所以我们做了以下事情:使用第二个 mariadb/mysql数据库计算机配置为辅助(以前称为“从”)。每当您想要制作 zfs 快照时,我们只需关闭辅助节点上的 mariadb/mysql,然后制作 zfs 快照,然后再次启动 mariadb/mysql。

    该设置使用 mysqld_multi 运行了大约 4 年(用于在同一台机器上但在不同端口上运行多个数据库实例),没有任何问题。此外,我们想立即将 zfs 快照用作可写的 mariaDB/mysql 实例。因此,我们立即从 zfs-snapshot 中创建一个 zfs-clone,并使用刚刚创建的 zfs-clone 作为其数据目录来启动一个 mariaDB-Docker 容器。此外,我们使用单独的 BindDNS 和路由来使 mariaDB-Docker-container 在我们的内部网络中以 DNS 名称可用。因此,我们可以从内部办公网络的任何地方访问数据库副本以进行读/写。(见https://github.com/ggtools/docker-tools/blob/master/dockerDDNS.py)

    这对我们的软件开发人员来说是一个很棒的工具:他们可以在几秒钟内请求数百 GB 甚至 TB 大的 mysqsl/mariadb 实例的完整副本,用于测试和开发目的。

    所有这些都由一些 ruby​​ 脚本自动完成,这些脚本本身作为 Jenkins/Hudson Job 提供给开发人员。通过这种方式,我们为开发人员提供了一个漂亮且易于使用的 web-UI,用于在需要时制作 DB-Copys。

    • 0

相关问题

  • 总大小(磁盘)与总大小(媒体)

  • 社区对备份解决方案的意见

  • 无法读取不同 LTO-3 驱动器上的 LTO-3 磁带

  • 使用 TSM 备份时跳过硬链接

  • 使用 rsync 维护名称更改的目录的副本

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve