PHP mysqli 允许的内存大小

问题描述 投票:0回答:2

你好!

我有一个在付费 VPS 上运行的网络应用程序。那里没问题。我正在将此应用程序移至我自己的专用服务器。

当前云服务器-CS-: Centos 6 x86_64; 2 GB 内存; 2 个虚拟CPU

专用服务器上的虚拟: Centos 7 x86_64; 2 GB 内存; 2 个虚拟CPU

我部署了具有相同规格的电脑,因为“如果它可以正常工作,那么它应该可以使用相同的规格”。

在 API 的端点上,当前 CS 返回正确的 json。新服务器回归:

致命错误:第439行中
/var/www/api/Components/Database.php

中允许的内存大小536870912字节已耗尽(尝试分配4294967296字节)

第 439 行是:

call_user_func_array(array($stmt, 'bind_result'), $parameters);

我在这里和那里找到的搜索结果没有帮助。有人说升级PHP版本,其中90%是设置了更大的内存限制。 **我做到了**。我将其设置为 256M、512M、2GB(除此之外没有可用的内存)、4GB 和 5GB。 ** 纳达**

此查询在其他生产服务器上运行正常。

新服务器:

Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips mod_fcgid/2.3.9        

PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 
X-Powered-By: PHP/5.4.16

CS:

 Server: Apache 
 X-Powered-By: PHP/5.5.22

我查看正在查询的base64的长度。它们是发送的 2 个图像数据。这个大小是由mysql返回的:

select LENGTH(image_base64) from pmv where pmv.model = 1;

这就是查询。它返回 2 行。 Image_base64 是长文本。还有一些其他专栏,但不会增加问题。

LENGTH(image_base64)
162678
131402

明显不接近4Gb

我无法访问 CS 上的 php/apache conf。我唯一没有尝试过的是将 PHP 从 5.4 升级到 5.5。可能是吗?我将尝试在周末访问服务器以尝试任何其他想法。

编辑#1

我将PHP版本更新到5.6.9。

同样的错误:

<b>Fatal error</b>:  Allowed memory size of 536870912 bytes exhausted (tried to allocate 4294967296 bytes) in <b>/var/www/api/Components/Database.php</b> on line <b>439</b><br />

编辑#2

将列类型从longtext更改为mediumtext似乎与这个问题

中一样工作

但是我到底为什么需要更改该服务器上的列类型?据我现在可以测试,无论该列上存储了多少信息。只要是长文本列就会报错。

谢谢!

php mysql mysqli out-of-memory
2个回答
2
投票

4294967296 字节听起来确实很多。您肯定在某个地方存在内存泄漏。

你应该读一下

大家,通过 ini_set('memory_limit', '-1'); 改变 memory_limit;根本不是解决方案。

请不要这样做。显然 php 在某处存在内存泄漏,并且您告诉服务器只使用它想要的所有内存。问题还没有完全解决

更新

此错误报告中所述:

这是 ext/mysqli 在使用 libmysql(始终在 5.2 及更早版本中)以及使用 5.3 启用 libmysql 时的已知限制。原因是服务器发送的有关该列的元数据不太具体。该长文本的最大长度为 4G,ext/mysqli 尝试以最大长度进行绑定,以确保不会发生数据丢失(数据不适合 C 级别的绑定缓冲区)。

因此,要解决这个问题,您有 4 个解决方案:

  • 您可以使用
    text
    mediumtext
    代替
    longblob
    longtext
    来使用更少的内存
  • 您可以使用 PDO 连接器代替 mysqli,但我不知道在 SaskPhp 中实现是否容易
  • 您可以使用 mysqli_stmt_store_result() 在本地存储数据,这也会增加您的内存使用量,但实际上会更少,因为它与缓冲区大小共享。
  • 您可以将 PHP 升级到高于 5.3 的版本。

就我个人而言,我会选择第四个,因为如果不要求您重构代码的重要部分,最新版本通常会给您带来更多优势。


-1
投票

thisSO答案所示,您可以尝试以下操作:

ini_set('memory_limit', -1);

但是,你应该尝试找到记忆的去向,修复总是比忘记更好!

在本例中这一点更为重要,因为您的使用量超过 4GB,这就是严重的内存泄漏。

© www.soinside.com 2019 - 2024. All rights reserved.