在我继续之前,这纯粹是一个直觉问题。 也就是说,我不是在寻求答案来解决我的 PHP/MySQL 代码中的特定错误。 相反,我想了解在解决问题时需要考虑的可能问题范围。 为此,我不会发布代码或附加脚本 - 我将简单地解释我做了什么以及正在发生的事情。
我已经编写了PHP脚本
- 读取要插入MySQL数据库表的X条记录的CSV文本文件和/或在适用的情况下更新重复条目;
- 将所述记录插入到我称之为该数据集的"根"表中; 从"根"表中
- 选择特定字段的子集记录,然后将这些记录插入到"主"表中;以及
- 从主表创建输出导出文本文件以进行分发。
我每 30 分钟通过单独的计划克隆任务处理几个 CSV 文件。 总而言之,从各种来源来看,估计有 420,000 个从文件到根表的插入事务,另有 420,000 个通过计划任务从根表插入到主表的插入事务。
其中一项任务涉及一个包含大约 400,000 条记录的 CSV 文件。 处理不包含任何错误,但问题是:在MySQL指示已成功插入根表中的400,000条记录中,只有大约92,000条记录实际存储在根表中 - 我丢失了该计划任务中的大约308,000条记录。
其他计划任务分别处理大约 16,000 和 1,000 个事务,并且这些事务处理完美。 事实上,如果我将交易数量从 400,000 减少到 10,000,那么这些过程也很好。 显然,这不是这里的目标。
为了解决这个问题,我尝试了几种补救措施......
- 增加服务器的内存(并增加 php.ini 文件中的最大限制)
- 获取具有扩展内存的专用数据库(而不是共享VPS数据库)
- 重写我的代码以大大消除存储的数组,这些数组会消耗内存并在运行时处理 fgetcsv() 进程
- 使用 INSERT DELAY MySQL 语句(与普通 INSERT 语句相对)
。这些补救措施都没有如预期的那样奏效。
鉴于迄今采取的行动没有成功,目前应考虑采取何种补救行动? 谢谢。。。
csv 中的源数据可能有重复的记录。 即使 csv 中有 400,000 条记录,您的"插入或更新"逻辑也会将它们修剪为精简集。 更少的内存可能会导致异常等,但这种数据丢失。
我怀疑CSV文件中有问题。
我的建议:
- 打印一些内容以调试从中读取的每一行的信息.CSV。这将显示处理了多少行。
- 在每次插入/更新时,打印任何错误(如果有)
它是这样的:
<?php
$csv = fopen('sample.csv', 'r'); $line = 1;
while (($item = fgetcsv($csv)) !== false) {
echo 'Line ' . $line++ . '... ';
$sql = ''; // your SQL query
mysql_query($sql);
$error = mysql_error();
if ($error == '') {
echo 'OK' . PHP_EOL;
} else {
echo 'FAILED' . PHP_EOL . $error . PHP_EOL;
}
}
因此,如果有任何错误,您可以查看它并找到问题(CSV的哪几行有问题)。