你好!
我有一个在付费 VPS 上运行的网络应用程序。那里没问题。我正在将此应用程序移至我自己的专用服务器。
当前云服务器-CS-: Centos 6 x86_64; 2 GB 内存; 2 个 vCPU
专用服务器上的虚拟: Centos 7 x86_64; 2 GB 内存; 2 个 vCPU
我部署了具有相同规范的电脑,因为“如果它可以正常工作,那么它应该可以使用相同的规范”。
在 API 端点上,当前 CS 返回正确的 json。新服务器返回:
fatal error :/var/www/api/Components/Database.php行中允许的内存大小 536870912 字节已耗尽(尝试分配 4294967296 字节) b>439
第 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似乎与this question中一样工作。
但是我到底为什么需要更改该服务器上的列类型?据我现在可以测试,无论该列上存储了多少信息。只要是长文本列就会报错。
谢谢!
最佳答案
4294967296 字节听起来确实很多。您肯定在某个地方存在内存泄漏。
People, changing the memory_limit by ini_set('memory_limit', '-1'); is NOT a solution at all.
Please don't do that. Obviously php has a memory leak somewhere and you are telling the server to just use all the memory that it wants. The problem has not been fixed at all
更新
如 this bug report 中所述:
This is a known limitation of ext/mysqli when using libmysql (always in 5.2 and previous) and when libmysql is enabled with 5.3 . The reason is that the server sends not too specific metadata about the column. This longtext has a max length of 4G and ext/mysqli tries to bind with the max length, to be sure no data loss occurs (data doesn't fit in the bind buffer on C level).
为了解决这个问题,你有 4 个解决方案:
- 您可以使用
text
或mediumtext
而不是longblob
或longtext
使用更少的内存 - 您可以使用 PDO 连接器代替 mysqli,但我不知道在 SaskPhp 中实现是否容易
- 您可以使用mysqli_stmt_store_result()在本地存储数据,这也会增加内存使用量,但实际上会减少,因为它与缓冲区大小共享。
- 您可以将 PHP 升级到高于 5.3 的版本。
就我个人而言,我会选择第四个,因为如果不要求您重构代码的重要部分,最新版本通常会给您带来更多优势。
关于PHP 允许的内存大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30812919/