MySQL 每晚将更新转储到本地 VM
MySQL dump update every night to local VM
为什么
我的公司将到达 PHP 的每个请求都记录到我们在 AWS 中的数据库中,因为我们发现它在跟踪我们系统中的错误时非常有用。不幸的是,我们每天收到大约 200,000 个请求,每个请求插入 3-5 table 秒(取决于请求是否有错误),因此存储我们日志的 table 会定期清除。
但是,我们希望将日志数据保留更长的时间,最好的方法是开始将其存储在本地,而不是存储在 AWS 上。但是让 PHP 为每个请求在本地连接是不可行的。 (会导致系统严重减速)
如何
我决定处理这个问题的最佳方法是基本上只将日志 table 过去 24 小时的数据转储到本地机器,然后清除从生产中转储的数据。生产永远不会有超过 24 小时的数据,我们可以在本地保存数据长达 6 个月。
问题
理想情况下,我宁愿不编写 PHP 脚本来在 2 个数据库之间传输大量数据。我认为可以使用 mysqldump
将特定 table 的更新从 1 个数据库转储到另一个数据库,但我不知道如何操作。 (bin 日志也是一样)
我的问题: 我如何使用 mysqldump
或 bin 日志来 仅添加来自特定 [= 的行 36=] 从 AWS 到本地数据库?
要使用二进制日志, 您可以将所有二进制日志下载到您的本地实例并使用 mysqlbinlog
将它们转换为 SQL,然后使用它来加载它们到您的本地数据库。参见 https://dev.mysql.com/doc/refman/5.7/en/mysqlbinlog.html
然后您可以在生产环境中截断 tables ,而无需 将截断 table 添加到 binlog。这样,您在生产环境中的 table 将被截断,但是当您针对本地 MySQL 重放二进制日志时,本地 MySQL 不会被截断。
SET SESSION sql_log_bin=0;
TRUNCATE TABLE <tablename>;
SET SESSION sql_log_bin=1;
但这是有风险的,因为即使有一天您忘记跳过 TRUNCATE TABLE 语句的二进制日志,它也会截断本地 MySQL 中那个 table 的所有数据!
如果您不能从 binlog 中省略 TRUNCATE TABLE,则可以在本地重放 binlog 时使用 sed
过滤掉 TRUNCATE TABLE 语句。
mysqlbinlog <binlogs> | sed -e '/^TRUNCATE TABLE/d' | mysql ...
这只是一个例子。您可能需要更彻底地了解该模式。我没有测试过。
到 mysqldump, 你可以只转储数据,没有通常添加到转储的 DROP TABLE / CREATE TABLE 语句。
mysqldump --single-transaction --no-create-info mydatabase mytable ...
那么转储应该只包含很多 INSERT 语句,您可以针对本地 MySQL 重放它。随着您每天插入转储,它会积累越来越多的数据。
为什么
我的公司将到达 PHP 的每个请求都记录到我们在 AWS 中的数据库中,因为我们发现它在跟踪我们系统中的错误时非常有用。不幸的是,我们每天收到大约 200,000 个请求,每个请求插入 3-5 table 秒(取决于请求是否有错误),因此存储我们日志的 table 会定期清除。
但是,我们希望将日志数据保留更长的时间,最好的方法是开始将其存储在本地,而不是存储在 AWS 上。但是让 PHP 为每个请求在本地连接是不可行的。 (会导致系统严重减速)
如何
我决定处理这个问题的最佳方法是基本上只将日志 table 过去 24 小时的数据转储到本地机器,然后清除从生产中转储的数据。生产永远不会有超过 24 小时的数据,我们可以在本地保存数据长达 6 个月。
问题
理想情况下,我宁愿不编写 PHP 脚本来在 2 个数据库之间传输大量数据。我认为可以使用 mysqldump
将特定 table 的更新从 1 个数据库转储到另一个数据库,但我不知道如何操作。 (bin 日志也是一样)
我的问题: 我如何使用 mysqldump
或 bin 日志来 仅添加来自特定 [= 的行 36=] 从 AWS 到本地数据库?
要使用二进制日志, 您可以将所有二进制日志下载到您的本地实例并使用 mysqlbinlog
将它们转换为 SQL,然后使用它来加载它们到您的本地数据库。参见 https://dev.mysql.com/doc/refman/5.7/en/mysqlbinlog.html
然后您可以在生产环境中截断 tables ,而无需 将截断 table 添加到 binlog。这样,您在生产环境中的 table 将被截断,但是当您针对本地 MySQL 重放二进制日志时,本地 MySQL 不会被截断。
SET SESSION sql_log_bin=0;
TRUNCATE TABLE <tablename>;
SET SESSION sql_log_bin=1;
但这是有风险的,因为即使有一天您忘记跳过 TRUNCATE TABLE 语句的二进制日志,它也会截断本地 MySQL 中那个 table 的所有数据!
如果您不能从 binlog 中省略 TRUNCATE TABLE,则可以在本地重放 binlog 时使用 sed
过滤掉 TRUNCATE TABLE 语句。
mysqlbinlog <binlogs> | sed -e '/^TRUNCATE TABLE/d' | mysql ...
这只是一个例子。您可能需要更彻底地了解该模式。我没有测试过。
到 mysqldump, 你可以只转储数据,没有通常添加到转储的 DROP TABLE / CREATE TABLE 语句。
mysqldump --single-transaction --no-create-info mydatabase mytable ...
那么转储应该只包含很多 INSERT 语句,您可以针对本地 MySQL 重放它。随着您每天插入转储,它会积累越来越多的数据。