0

我们正在使用 MySQL,并且有一个大约 110 万条记录的 InnoDB 表,其中整个表必须每天两次用 CSV 中的数据替换。

到目前为止,我一直在做的是截断表格,然后使用 mysqlimport 每天两次从新鲜的 CSV 重新填充表格。这导致大约 160 秒的停机时间,我最初被告知这很好,但现在情况不再如此。

我能想到的唯一方法是拥有一个临时表和一个生产表。实时查询将投入生产,当我需要重新填充数据库时,我将截断 staging,然后 mysql 将 CSV 导入其中,完成后我将交换名称,以便 staging 拥有旧数据库,生产将包含新导入的 CSV。我想我需要一个中间名称,比如 production 变成 production2,staging 变成 production,然后 production2 变成 staging。

有没有人有替代解决方案?表需要尽快导入,这就是我使用 mysqlimport 的原因,而且停机时间必须极短。

4

2 回答 2

3

我认为您已经有了最佳解决方案。只需确保进行原子重命名,即“将表生产重命名为生产2,暂存为生产”。这样,它将对应用程序/用户透明。需要注意的一件事是是否有引用该表的外键,因为这些键仍将引用重命名的旧表。但我想既然你可以在没有任何问题的情况下截断它,你就没有任何问题。

编辑:我对 StackOverflow 的评论很新,所以我不知道这是否是最好的地方,但我只想评论 eggyal 发布的答案 - TRUNCATE 会导致隐式提交,所以建议的解决方案赢了'不像描述的那样工作(即,即使在加载新数据之前,用户/应用程序也会看到更改)。

于 2012-05-02T07:01:40.627 回答
0

在事务中执行DELETEand LOAD DATAmysqlimport无论如何都是这样)操作:MySQL 将自动为您执行暂存过程,而无需付出任何努力。

START TRANSACTION;
DELETE FROM foo;
LOAD DATA INFILE '/path/to/bar' INTO TABLE foo;
COMMIT;

注意:正如@JohannTagle 所指出的,TRUNCATE会导致隐式提交,因此需要使用它DELETE

于 2012-05-02T07:23:19.767 回答