我有几个表,它们有数千万行,并且有多个索引。当转储和重新加载数据时,由于索引的原因,重新插入需要很长时间,或者在没有索引的情况下插入然后重新索引。
我理解索引为数据库引擎提供了一种快速定位磁盘上记录的方法,并且由于数据库转储和重新加载会或可能有效地改变磁盘上数据的位置,因此索引可能会失效。但是,您似乎仍然应该能够通过连续且顺序地定位磁盘上的所有记录来优化表,然后只需让索引引用起始位置加偏移量即可。有没有人做过这类工作?
所需功能:我可以转储原始数据,将其加载到连续不间断的磁盘区域中,然后只需加载索引并告诉引擎使用新的表起始位置进行更新。在谷歌上搜索后,我什么也没看到……
答案1
MySQL 将原始数据和索引文件存储在数据目录中;每个表通常有 3 个这样的文件,每个文件的名称与表相同,但文件扩展名不同,并且都包含在一个以数据库本身名称命名的文件夹中。这些文件可以复制到其他地方进行备份(并且可以根据需要进行压缩和/或加密),就像任何其他文件一样,然而你必须要么停止数据库,要么获取所有表的读锁——如果在向表写入数据时复制表的文件,则备份可能会损坏且无法使用!(或者,停止 MySQL 或获取锁,拍摄快照(如果您足够幸运地使用 LVM),然后在进行备份时重新启动/释放锁。)
使用这些文件从备份恢复时:
- 停止 MySQL。这至关重要!在 MySQL 运行时,您无法直接修改原始表文件。请相信我。
- 将相关文件(记住维护目录结构,即数据库的目录)复制到 MySQL 的数据目录中。
- 启动 MySQL。现在您应该有数据,就像您备份时一样。
我曾多次使用此过程备份和恢复 MySQL 版本 3、4 和 5 上的数据库,没有出现任何问题。不过,为了以防万一,最好对每个恢复的表进行检查。
重要的:此程序将仅有的如果您恢复到与备份相同的主要版本,则此方法有效!也就是说,如果您以这种方式复制 MySQL 5 数据库,则必须恢复到 MySQL 5。向上(和仅有的将文件从 1 个版本复制到 4 个版本(例如,复制到 5 个版本)也应该可以正常工作,但可能需要更新文件结构,因此可能不会比转储它们的方法更快/更好。
答案2
您可能需要查看磁盘快照...和/或批量交易。
对于大多数 Linux 系统,您可以使用磁盘管理器创建当前文件系统的快照……然后对原始数据库文件进行备份/复制/移动/执行任何操作。此方法的唯一缺点是,在创建快照时,mysql 服务器需要短暂离线。这将确保您拥有正确提交到磁盘的数据库。快照完成后……您可以简单地删除快照并继续。(无需重新启动 mysql 或执行任何其他操作)恢复过程只需将原始数据文件复制/移动到正确的数据目录并启动 mysql。
您也可以使用 mysql 的“批量事务”命令来绕过所有一致性检查等。对于大多数批量事务,在重建索引时仍会有一些滞后。此方法的优点是,最后只会进行 1 次大型一致性检查,而不是对每个插入的记录进行 1 次。
说到底,真的没有伟大的处理超过 200 万条记录的数据库的方法。这时,您就会开始看到关系数据库中的缺陷,并开始寻找 nosql 替代方案。(是的,我知道在这个问题上双方都有很多争论)