PHP 允许的内存大小
你好!
我有一个在付费 VPS 上运行的网络应用.那里没问题.我正在将此应用程序移至我自己的专用服务器.
I have a web-app running on a paid VPS. No problem there. I'm moving this app to my own dedicated server.
当前云服务器-CS-:Centos 6 x86_64;2 Gb 内存;2个虚拟CPU
Current Cloud Server -CS-: Centos 6 x86_64; 2 Gb Ram; 2 vCPU
专用服务器上的虚拟:Centos 7 x86_64;2 Gb 内存;2个虚拟CPU
Virtual on Dedicated Server: Centos 7 x86_64; 2 Gb Ram; 2 vCPU
我部署了具有相同规格的 PC,因为如果它可以正常工作,它应该也可以工作".
I deployed the PC with the same specs because "if it works okay with that it should work with the same".
在 API 的端点上,当前 CS 返回正确的 json.新服务器返回:
On a API's endpoint the current CS returns the correct json. The new Server returns:
致命错误:/var/www/api/Components/Database.php上线439
第 439 行是:
call_user_func_array(array($stmt, 'bind_result'), $parameters);
我在这里和那里找到的搜索结果都没有帮助.有人说升级 PHP 版本,其中 90% 设置了更大的内存限制.**我做到了**.我将它设置为 256M、512M、2GB(除此之外没有可用的内存)、4GB 和 5GB.** 纳达**
The search results I found here and there were not helpful. Some said upgrade PHP version and 90% of them is set a larger memory limit. ** I did**. I set it to 256M, 512M, 2GB (beyond this there is no ram available), 4GB and 5GB. ** Nada**
此查询在另一台生产服务器上运行正常.
This query works ok on the other -and production- server.
新服务器:
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 的 LENGTH.它们是发送的 2 张图像数据.这个大小由mysql返回:
I look at the LENGTH of the base64 being queried. They're 2 images data sent. This size is returned by mysql:
select LENGTH(image_base64) from pmv where pmv.model = 1;
这就是查询.它返回 2 行.Image_base64 是 LONGTEXT.还有其他一些列,但不会增加问题.
That is the query. It returns 2 row. Image_base64 is LONGTEXT. There are some others columns but it won't add to the issue.
LENGTH(image_base64)
162678
131402
显然不接近 4Gb
我无法在 CS 上访问 php/apache conf.我唯一没有尝试过的是将 PHP 从 5.4 升级到 5.5.可以吗?我会尝试在周末访问服务器以尝试任何其他想法.
I can't access php/apache conf on the CS. The only thing I didn't try yet is upgrading PHP from 5.4 to 5.5. Could be it? I'll try to get access to the server on weekend to try out any other ideas.
编辑#1
我将 PHP 版本更新为 5.6.9.
I update the PHP Version to 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 似乎在 这个问题
Changing the column type from longtext to mediumtext seems to work as in this question
但是为什么我需要更改此服务器上的列类型呢?据我现在可以测试,无论该列上存储了多少信息.只要它是一个longtext col,它就会给出错误.
But why on earth I need to change the column type on this server? As far I can test now, no matter how much info is stored on that column. It will give the error as long as it's a longtext col.
谢谢!
推荐答案
4294967296 字节听起来确实很多.你肯定在某个地方有内存泄漏.
4294967296 bytes sounds like really a lot. You surely have a memory leak somewhere.
你应该读一下 :
人,通过 ini_set('memory_limit', '-1'); 改变 memory_limit根本不是解决方案.
People, changing the memory_limit by ini_set('memory_limit', '-1'); is NOT a solution at all.
请不要那样做.显然 php 在某处有内存泄漏,你告诉服务器只使用它想要的所有内存.问题根本没有解决
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
更新
如此错误报告中所述:
这是 ext/mysqli 在使用 libmysql(总是在 5.2 和更早版本中)以及使用 5.3 启用 libmysql 时的已知限制.原因是服务器发送的关于该列的元数据不太具体.此长文本的最大长度为 4G,ext/mysqli 尝试使用最大长度进行绑定,以确保不会发生数据丢失(数据不适合 C 级别的绑定缓冲区).
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 个解决方案:
So to fix that, you have 4 solutions :
- 您可以使用
text
或mediumtext
代替longblob
或longtext
以使用更少的内存李> - 您可以使用 PDO 连接器代替 mysqli,但我不知道在 SaskPhp 中实现它是否容易
- 你可以使用mysqli_stmt_store_result()来存储你本地数据,这也会增加您的内存使用量,但实际上更少,因为它与缓冲区大小共享.
- 您可以将 PHP 升级到高于 5.3 的版本.
- You can use a
text
ormediumtext
instead of alongblob
orlongtext
to use less memory - You can use PDO connector instead of mysqli but I don't know if it's a easy thing to implement in SaskPhp
- You can use mysqli_stmt_store_result() to store you data locally, which will also increase your memory usage but really less since it's shared with the buffer size.
- You can upgrade your PHP with a version superior to 5.3.
就我个人而言,我会选择第四个,因为如果没有强制重构代码的重要部分,拥有最新版本通常会给您带来更多优势.
Personally, I would go for the fourth one since having an recent version generally bring you many more advantages if it doesn't oblige you to refactor significant parts of your code.
相关文章