1

我有一个数据库,出于备份原因,我打算复制它(目前性能不是问题)。

我们已经正确设置了复制并对其进行了测试,一切都很好。

然后我们意识到它会将所有写入复制到临时表中,这实际上意味着对于空闲的从站而言,一天的数据复制需要将近两个小时。

原因是我们每 15 分钟通过 cronjob 重新计算数据库中的一些数据以确保它同步(总共需要大约 3 分钟,因此在 Web 请求期间执行这些操作是不可接受的;相反,我们只是在 Web 请求中存储修改而不尝试重新计算任何内容,然后批量完成所有工作)。为了有效地处理这些数据,我们使用临时表(因为有很多相互依赖关系)。

现在,第一个问题是,如果我们在从属服务器正在处理使用该临时表的事务时重新启动它,那么临时表不会持久存在。这可以通过不使用临时表来避免,尽管这有其自身的问题。

更严重的问题是,如果不是所有重新计算(它一个接一个地进行,所以每 15 分钟重建一次数据没有任何好处),奴隶可以在不到半小时的时间内轻松赶上......你可以从字面上看到它停留在 1115,只是为了快速赶上并停留在 1130 等)。

我们提出的一种解决方案是将所有重新计算从复制的数据库中移出,这样从站就不会复制它。但它的缺点是我们必须修剪它最终更新的表,使我们的奴隶实际上被“阉割”,即。在我们真正使用它之前,我们必须重新计算它上面的所有内容。

有没有人遇到过类似的问题和/或您将如何解决?我错过了一些明显的东西吗?

4

2 回答 2

3

我想出了解决方案。它利用了 Nick 提到的 replicate-do-db。在这里写下来以防有人遇到类似问题。

在这种情况下仅使用 replicate-(wild-)do* 选项的问题(就像我说的,我们使用临时表重新填充中央表)是您忽略临时表并重新填充没有数据的中央表(这会导致进一步的问题,因为依赖于中央表是最新的所有查询都会产生不同的结果)或者你忽略了有类似问题的中央表。更不用说,在将这些选项中的任何一个添加到 my.cnf 后,您必须重新启动 mysql。我们想要的东西可以涵盖所有这些情况(以及未来的情况),而无需进一步重新启动。

因此,我们决定将数据库拆分为“真实”数据库和“工作区”数据库。仅复制“真实”数据库(我想您可以决定用于复制野生执行表语法的表名约定)。

所有临时表工作都发生在“workarea”数据库中,为了避免上述依赖问题,我们不会通过 INSERT ... SELECT 或 RENAME TABLE 填充中央表(位于“真实”数据库中),但是而是查询 tmp 表以在活动表上生成一种差异(即,为新行生成 INSERT 语句,为旧行生成 DELETE 并在必要时进行更新)。

这样,唯一被复制的查询就是所需的更新,没有别的,即。一些(大多数?)每十五分钟发生一次的重新计算查询甚至可能不会进入从属服务器,而那些做的查询将是最小的并且根本不计算昂贵,只是简单的 INSERT 和 DELETE。

于 2008-09-26T11:51:18.600 回答
2

在 MySQL 中,我相信从 5.0 开始,您可以使用表通配符来复制特定的表。可以设置许多命令行选项,但您也可以通过 MySQL 配置文件进行设置。

[mysqld]
replicate-do-db    = db1
replicate-do-table = db2.mytbl2
replicate-wild-do-table= database_name.%
replicate-wild-do-table= another_db.%

这个想法是您告诉它不要复制除您指定的表之外的任何表。

于 2008-09-22T18:13:32.780 回答