我有一个配置了二进制日志的 MySQL 服务器实例。我没有进行任何复制,但二进制日志是我们恢复计划的一部分 - 能够重播自上次完整备份以来的所有事务。
不久前,我们注意到一个运行了几周的系统上的 MySQL 错误日志已经增长到超过 5 GB 的异常大小。查看日志,几乎写入日志的每一行都是关于“向二进制日志写入不安全语句”的警告。
现在,我无法控制使用数据库的应用程序,因此我无法尝试使这些语句“安全”。因此,作为“修复”,我配置了binlog_format到混合, 而不是陈述.这告诉 MySQL 使用陈述尽可能记录,但要回退到排使用不安全的语句进行日志记录。这样做成功地将错误日志的大小保持在可管理的大小。
然而,现在二进制日志正在增长很多比以前更快(我看到3 GB今天仅在几个小时内就记录了日志文件的许多信息),大概是因为现在系统正在将受影响的每一行(对于“不安全”的语句)写入日志,而对于影响大量行的语句,嗯,你明白了。
因此,我发现自己处于进退维谷的境地。如果我使用陈述格式,二进制日志是可管理的,但我在错误日志中收到大量警告。如果我使用混合格式,错误日志很好,但是二进制日志增长得足够快,甚至可能在一天之内填满分区。
这让我想到了一个问题:这些“不安全”语句究竟会带来什么后果?就像我说的,我没有进行任何复制,所以我不必担心一台服务器与另一台服务器完全相同。我只需要确保在我们需要从备份中恢复的情况下,所有数据都在那里。记录“不安全”语句是否会导致数据丢失,或者是否只会出现某些行顺序不同(可能具有不同的主键 ID)的情况?如果这不是什么大问题,那么我可以禁用错误日志中的警告(尽管这似乎有些过分)。
否则,我可能会被迫完全取消二进制日志记录,而只是依靠可能过时的完整备份来制定恢复计划。
对于这种情况有什么建议吗?
答案1
基于行的复制格式实际上比基于语句的复制格式占用更多磁盘空间。这很简单,因为在 binlog 中,您将拥有插入/更新的所有数据,而不仅仅是语句。因此,如果语句要求插入 100 行,则如果 binlog_format=STATEMENT 则只会插入一条语句,但如果是 ROW,则实际上将包含所有条目。
因此,为了节省磁盘空间,您必须恢复为基于 STATEMENT 的。在混合模式下,mysql 将尝试将 STATEMENT 写入 binlog,但如果出现不安全的语句,则会恢复为基于 ROW 的 binlog。在您的例子中,似乎您有许多不安全的语句,因此您最终会得到基于 ROW 的 binlog。
你可以做几件事
将其保留为 ROW 并执行清理作业,该作业将在一段时间后清除日志,您需要计算适合您系统的日志。在删除日志之前,您应该将它们复制到其他地方,以免丢失。
通过第二个系统实现复制,并再次在主服务器上进行清理工作(确保从属服务器同步,否则可能会丢失数据)
仔细查看可能不安全的语句,这可能需要与应用程序开发人员的合作。