编辑:看起来问题出现在我的C代码中,因为当我将所有SQL打印到文件中,然后通过命令行输入时,mysqld内存消耗是稳定的。它必须是我发布的代码段中遗漏的东西,但是根据MYSQL文档,mysql_store_result应该从服务器中提取整个结果。
上下文的原始问题,C代码段如下:
我有100个MYSQL表,每个表有1017列,每行有630,000行。我知道通常有这么多列绝对是错误的方法,但对于个人项目,它是我需要跟踪的最简单的解决方案。
我正在执行INSERT ... ON DUPLICATE KEY UPDATE语句,在我的C程序的每次运行中每行设置大约5列,并使用主键来解决它们。我以1k到350k的批量进行这些更新。
这样做没有插入,因为我所处理的所有行都已存在。
大约20分钟后,MYSQL进程内存增长非常明显,因为我的交换开始被越来越多地使用,并且性能降低了爬行速度。您可以观察mysqld进程内存使用情况,即使只需几分钟,也可以通过top缓慢攀升。在此过程中,我的调用程序的内存使用量不会增加,因为MYSQL最终会在90%以上的范围内,其余的则在交换中。
此外,即使我终止我的调用C程序并让所有查询完成执行,mysqld仍然保持大量内存,似乎没有一个被释放,甚至没有被释放。
每个查询完成后,我运行此代码以清除结果(我不会将它们用于任何事情):
while (mysql_next_result(mysql) == 0)
{
MYSQL_RES *res;
res = mysql_store_result(mysql);
mysql_free_result(res);
}
我的一个UPDATE语句的示例,仅用于3行:
INSERT INTO data.test1_t1 (pkey,v1,v2,v3,v4,v5) VALUES
(100000,1,1,1,1,1),
(100001,2,2,2,2,2),
(100002,3,3,3,3,3)
ON DUPLICATE KEY UPDATE v1=VALUES(v1),v2=VALUES(v2),v3=VALUES(v3),v4=VALUES(v4),v5=VALUES(v5)
我的机器是专用的Ubuntu 16.04安装,具有32GB RAM和32GB交换,带有MYSQL版本5.7.17,配置文件中包含以下修改选项:
innodb_buffer_pool_size = 6G
innodb_log_file_size = 1G
innodb_flush_log_at_trx_commit = 0
我正在使用C API,使用mysql_real_query发出查询。这个程序是唯一访问数据库的程序,问题不难重现,因此很容易测试。任何建议都会非常受欢迎。