Mysql 长时间运行的innodb查询在mariadb中生成一个大的撤销文件

Mysql 长时间运行的innodb查询在mariadb中生成一个大的撤销文件,mysql,mariadb,innodb,Mysql,Mariadb,Innodb,我在php中使用MYSQLI_USE_RESULT进行了一个大查询,不将所有结果放入php内存。 因为如果我使用MYSQLI_STORE_RESULT,它会将所有结果的所有数据放入内存,这需要多GB的ram,而不是逐行获取。 它返回数百万行,每行将生成一个api请求,因此查询将运行数天。 同时,我还有其他mysql查询更新/插入与第一个查询相关的表,我认为这会导致undo日志不停地增长 我设置innodb_undo_tablespaces=2和innodb_undo_log_truncate=O

我在php中使用MYSQLI_USE_RESULT进行了一个大查询,不将所有结果放入php内存。 因为如果我使用MYSQLI_STORE_RESULT,它会将所有结果的所有数据放入内存,这需要多GB的ram,而不是逐行获取。 它返回数百万行,每行将生成一个api请求,因此查询将运行数天。 同时,我还有其他mysql查询更新/插入与第一个查询相关的表,我认为这会导致undo日志不停地增长

我设置innodb_undo_tablespaces=2和innodb_undo_log_truncate=ON 因此,撤销日志与ibdata1是分开的,但是撤销文件仍然很大,直到我终止已经运行了几天的查询

在运行长时间运行的查询之前,我执行了“SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;”,希望它能阻止undo文件的增长,但事实并非如此

正在更新/插入的其他查询具有自动提交功能

在1-2天内,撤消文件已经是40GB大小


问题:如何防止此撤消文件增加?因为我不想在查询运行时保留数据的早期版本。如果我得到的是更新的数据而不是查询时的数据,这并不重要。

无论事务隔离级别如何,给定的查询都将始终建立一个固定的快照,这要求将数据保留在查询启动时的状态

换句话说,READ-COMMITTED或READ-UNCOMMITTED允许同一事务中的后续查询看到更新的数据,但单个查询永远不会看到更改的数据集。因此,对数据的并发更新将强制将旧记录版本复制到撤消日志中,这些记录版本将保留在那里,直到长时间运行的查询完成

READ-UNCOMMITTED和READ-COMMITTED一样没有任何帮助。事实上,我从来没有因为任何原因需要使用READ-UNCOMMITTED。允许对未完成的事务进行“脏读”会破坏ACID数据库的规则,并导致异常

避免撤消日志长期增长的唯一方法是完成查询

实现这一点的最简单方法是使用多个短时间运行的查询,每个查询获取结果的一个子集。及时完成每个查询

另一种解决方案是对数百万行结果运行整个查询,并将结果存储在不受InnoDB事务隔离约束的地方

  • MyISAM表
  • 消息队列
  • 磁盘上的普通文件
  • 像Memcached或Redis这样的缓存
  • PHP内存(但是你说你不喜欢它,因为它太大了)

堆栈溢出用于编程问题。这似乎与服务器配置有关,因此更适合于。我没有否决投票,但不要太在意投票结果。人们可能会暴躁,我没有投反对票。但我注意到,当帖子中没有问题时,往往会出现反对票。在你的帖子里没有问题。你是说你有一个连续两天都在执行的查询吗?为什么?这将耗尽您在服务器上的所有资源。我进行了编辑以添加一个问题。是的,一个查询执行了好几天,这是因为我需要向api查询数百万条条目,所以我做了一个mysql查询,从mysql数据库中获取条目,然后我逐个查询api。对api执行数百万次请求需要一天的时间,因为mysql将在php处理完每一行后等待,所以不会使用服务器上的所有资源