【问题标题】:mysqldump without interrupting live production INSERTmysqldump 不中断现场生产 INSERT
【发布时间】:2012-04-11 22:19:14
【问题描述】:

我即将将我们的生产数据库迁移到另一台服务器。它大约有 38GB 大,并且使用的是 MISAM 表。由于我无法物理访问新的服务器文件系统,我们只能使用 mysqldump。

我已经浏览了这个网站,看看mysqldump在线备份是否会导致我们的生产网站崩溃。来自这篇文章:Run MySQLDump without Locking Tables,它说显然 mysqldump 会锁定数据库并阻止插入。但是经过几次测试后,我很想知道它是否显示。

如果我使用

mysqldump -u root -ppassword --flush-logs testDB > /tmp/backup.sql

mysqldump 最终会默认执行一个 '--lock-tables',这是一个 READ LOCAL 锁 (refer to mysql 5.1 doc),其中并发插入仍然可用.我已经做了一个 for 循环,每秒插入一个表,而 mysqldump 需要一分钟才能完成。在此期间,每一秒都会插入一条记录。这意味着,mysqldump 不会中断生产服务器,INSERT 仍然可以继续

有没有人有不同的经历?我想在继续我的生产服务器之前确保这一点,所以很高兴知道我是否做错了什么导致我的测试不正确。

[我的mysql-server版本是5.1.52,mysqldump是10.13]

【问题讨论】:

  • 您应该获得对新服务器 FIRST 的访问权限,并且可能正在寻找 mysql 复制来解决迁移问题。 记住:您可以转储并安装到新服务器,但是在您转储数据后,将会有 MORE 新的写入,您如何将新写入同步到新服务器?
  • 后续的新数据写入,我们将使用mysqlbinlog解决,请注意。现在我主要关心的是第一次使用 mysqldump 进行备份。我只是想确定 mysqldump 是否会阻止 INSERT。根据我的测试,它没有显示它会。只是想确定其他体验如何。

标签: mysql mysqldump


【解决方案1】:

现在,您可能有一个包含分离表的数据库,或者一个数据仓库——其中所有内容都没有(完全)标准化,并且表之间没有任何链接。在这种情况下,任何转储都可以工作。

我假设,包含 38G 数据的生产数据库包含某种形式的图形(BLOB),然后 - 无处不在 - 你有来自其他表的链接。对吧?

因此,据我所知,您可能会丢失表之间的严重链接(通常是主键/外键对),因此,您可以在更新/插入时捕获一个表,而它的依赖(使用该表作为其主要来源)尚未更新。因此,您将失去所谓的数据库完整性。

很多时候,重建完整性非常麻烦,最常见的原因是使用/生成/维护数据库系统的系统还没有成为面向事务的系统,因此无法跟踪数据库中的关系除了通过主/外键关系。

因此,您肯定可以在没有锁的情况下复制您的表以及上面的许多其他建议 - 但您有烫伤手指的风险,并且取决于系统操作的敏感程度 - 您可能严重烧伤自己或只是表面划伤。

示例:如果您的数据库是一个关键任务数据库系统,其中包含 ICU 中生命支持设备的推荐心率,那么在进行迁移之前,我会三思而后行。

但是,如果数据库包含来自 facebook 或类似网站的图片 = 您可能能够承受从 0 到 129,388 个丢失链接的任何后果 :-)。

现在 - 分析这么多。解决方案:

您必须创建一个软件,该软件以完整的完整性为您进行转储,一个表集一个表集,一个元组一个元组。您需要识别可以从当前在线 24/7/365 基地复制到新基地的数据集群,然后执行此操作,然后标记它已被复制。

IFFF 现在对您已复制的记录发生更改,您将需要对这些记录进行后续复制。这样做可能会很棘手。

IFFF 您正在运行更高级的 MYSQL 版本 - 您实际上可以创建另一个站点和/或副本,或分布式数据库 - 然后就可以摆脱它,以这种方式。

IFFF 您有一个 10 分钟的窗口,您可以根据需要创建它,然后您也可以只复制位于驱动器上的物理文件。我说的是 .stm .std - 等等 - 文件 - 然后你可以关闭服务器几分钟,然后复制。

现在是一个基本问题:

您需要不时对您的机器进行维护。你的系统没有空间来进行这种操作吗?如果不是 - 那么当硬盘崩溃时你会怎么做。注意“何时”而不是“如果”。

【讨论】:

  • 38 GB 的数据库大小如何暗示图形或 BLOB 内容?
【解决方案2】:

1) 使用--opt 与指定--add-drop-table--add-locks--create-options--disable-keys--extended-insert--lock-tables--quick 相同,和--set-charset--opt 代表的所有选项也默认打开,因为--opt 默认打开。

2) mysqldump 可以逐行检索和转储表内容,也可以从表中检索整个内容并在转储前将其缓冲在内存中。如果要转储大型表,则在内存中缓冲可能会成为问题。要逐行转储表,请使用--quick 选项(或--opt,它启用--quick)。默认情况下启用--opt 选项(因此--quick),因此要启用内存缓冲,请使用--skip-quick

3) --single-transaction 此选项在从服务器转储数据(事务表InnoDB)之前发出BEGIN SQL 语句。

如果您的架构是 InnoDBMyISAM 的组合,以下示例将对您有所帮助:

    mysqldump -uuid -ppwd --skip-opt --single-transaction --max_allowed_packet=512M db > db.sql

【讨论】:

    【解决方案3】:

    我以前从未这样做过,但您可以在倾倒时尝试--skip-add-locks

    虽然可能需要更长的时间,但您可以转储几个补丁,每个补丁都需要很短的时间来完成。添加--skip--add-drop-table 将允许您将这些多个较小的转储上传到同一个表中,而无需重新创建它。使用--extended-insert 会使 sql 文件更小,无法启动。

    可以尝试mysqldump -u -p${password} --skip-add-drop-table --extended-insert --where='id between 0 and 20000' test_db test_table > test.sql 之类的方法。您需要先转储表结构并上传它们才能这样做,或者删除 --skip-add-drop-table 以进行第一次转储

    【讨论】:

    • 嗨,感谢您的建议。但目前我主要关心的是不要试图减少 mysqldump 时间,因为数据太多了。我的意图是找出mysqldump 在运行时是否会阻止 INSERT。寻找以前做过这个的人。
    【解决方案4】:

    mysqldump 默认不添加 --lock-tables。尝试使用 --lock-tables 让我知道它是否有帮助

    顺便说一句 - 您还应该使用添加锁,这将使您的导入更快!

    【讨论】:

    • 你好,我再次测试,确认mysqldump默认会发出--lock-tables。两点来证明。首先,mysqldump --help|grep lock 将显示 'lock-tables' 为 TRUE。其次,在mysqldump发生期间使用mysql>show open tables;,'In_use'列将指示1,而另一个mysql INSERT不会使其变为2,因此表明它是LOCK READ LOCAL。所以我的问题是,还有其他人让他们的 mysqldump 锁定表并阻止 INSERT 吗?因为我没有。
    猜你喜欢
    • 1970-01-01
    • 2017-05-12
    • 1970-01-01
    • 1970-01-01
    • 2021-01-21
    • 2016-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多