2

我试图对此进行研究,但找不到任何东西,所以我又回到了集体询问。

在一个相当繁忙的 MySQL 数据库中,我有一个 access_log 表,每天大约有 1000 万条记录。目标是获取昨天的记录并将它们移动到不同服务器上的不同数据库。有没有办法只从那个表中热备份昨天的数据?

谢谢你的意见,凯特

4

3 回答 3

1

鉴于您只有一个 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 表,您可以选择按天对它进行分区,这样您就可以简单地换出日常分区表。但这是一个更长的话题。

于 2013-09-20T14:24:28.960 回答
0

是的,您可以使用 cron 作业来完成。

进行 cron 作业并编写查询以将数据发送到那里的其他数据库。

这是 cron 作业的示例:http: //docs.phplist.com/CronJobExamples.html

这是教程: http: //net.tutsplus.com/tutorials/php/managing-cron-jobs-with-php-2/

于 2013-09-20T14:16:31.983 回答
0
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 拆分

于 2013-09-20T14:19:47.913 回答