我试图对此进行研究,但找不到任何东西,所以我又回到了集体询问。
在一个相当繁忙的 MySQL 数据库中,我有一个 access_log 表,每天大约有 1000 万条记录。目标是获取昨天的记录并将它们移动到不同服务器上的不同数据库。有没有办法只从那个表中热备份昨天的数据?
谢谢你的意见,凯特
我试图对此进行研究,但找不到任何东西,所以我又回到了集体询问。
在一个相当繁忙的 MySQL 数据库中,我有一个 access_log 表,每天大约有 1000 万条记录。目标是获取昨天的记录并将它们移动到不同服务器上的不同数据库。有没有办法只从那个表中热备份昨天的数据?
谢谢你的意见,凯特
鉴于您只有一个 access_log 表,选择这些记录很简单。您必须将它们拉入客户端程序,然后将它们推送到另一个表。
SELECT *
FROM access_log
WHERE logtime >= CURRENT_DATE() - INTERVAL 1 DAY
AND logtime < CURRENT_DATE();
然后
DELETE
FROM access_log
WHERE logtime >= CURRENT_DATE() - INTERVAL 1 DAY
AND logtime < CURRENT_DATE();
(避免使用BETWEEN
来选择时间/日期范围;它在您选择的范围结束时会做错事。)
但这有点像性能猪。一方面,该表应该使用 MyISAM 存储引擎,而不是 InnoDB,这样您就不会背负事务开销。
如果它是 InnoDB 并且您无法更改它,您可能需要编写一个程序来读取然后删除较小块中的数据。例如,其中一个块可能是:
SELECT *
FROM access_log
WHERE logtime >= CURRENT_DATE() - INTERVAL 1 DAY + INTERVAL 1 HOUR
AND logtime < CURRENT_DATE() - INTERVAL 1 DAY + INTERVAL 2 HOUR
或者,如果您能承受午夜一两秒的停机时间,您可以将 access_log 表重命名为昨天的 access_log,并为今天创建一个新表。然后您可以保存昨天的表格而不会与生产性能发生冲突。
您可以使用以下语句执行午夜日志交换操作:
CREATE TABLE `access_log_new` (
/* whatever columns you have in your access_log table, I made this stuff up */
`log_id` INT(11) NOT NULL AUTO_INCREMENT,
`item` VARCHAR(255) NOT NULL,
`logtime` TIMESTAMP NOT NULL ,
PRIMARY KEY (`log_id`)
) ENGINE=MYISAM;
DROP TABLE access_log_old;
RENAME TABLE access_log TO access_log_old;
RENAME TABLE access_log_new TO access_log;
这里的最后两个语句,RENAME TABLE
语句,非常快。没有access_log表的时间很短,但远不到一秒。这个想法是很好地设置所有内容,然后快速翻转日志文件。
这可能是一个非常好的策略;它可以让您为实时 access_log 表使用编写成本低、搜索成本高的 ARCHIVE 存储引擎。
如果您可以选择重组您的 access_log 表,您可以选择按天对它进行分区,这样您就可以简单地换出日常分区表。但这是一个更长的话题。
是的,您可以使用 cron 作业来完成。
进行 cron 作业并编写查询以将数据发送到那里的其他数据库。
这是 cron 作业的示例:http: //docs.phplist.com/CronJobExamples.html
这是教程: http: //net.tutsplus.com/tutorials/php/managing-cron-jobs-with-php-2/
SELECT rows
INTO OUTFILE '/tmp/backup.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM test_table WHERE date=curdate()-1;
如果您没有日期,请考虑给他们一个自动增量 id 并按 id 拆分