我已通过_POST成功将数据接收到服务器客户端帐户中,但是当行数据大于约25MB时,我无法将数据插入包含longblob类型的行表。我看不到php准备好的语句/文件引发的任何错误,php文件正常关闭。我正在检查我的max_allowed_packet是否正确配置。
我没有服务器root特权和访问权,看不到my.cnf,我正在与主机进行交谈以确保both client and server max_allowed_packet设置为256M。
php文件插入部分:
$itemAttributes=$_POST['itemAttributes'];
$itemName=$_POST['itemName'];
if(!($stmt = $conn->prepare("INSERT INTO $itemTable (`itemName`, `itemAttributes`) VALUES (?, ?)")))
echo "<br/>Failed to Prepare";
else
echo "<br/>Prepare success.";
$stmt->execute([$itemName,$itemAttributes]);
echo " Success executing";
$conn->connection=null;
if($conn->connection==null)
echo "<br />Connection Closed.......";
这些是我正在执行的检查,我是否缺少任何检查以确保不会在其他位置覆盖max_allowed_packet并在所有位置正确设置?
客户端设置检查:所有这三个检查都给了我256MB max_allowed_packet:
mysql SHOW VARIABLES LIKE 'max_allowed_packet'
mysql SHOW GLOBAL VARIABLES LIKE 'max_allowed_packet'
mysql SHOW SESSION VARIABLES LIKE 'max_allowed_packet'
但是,我成功登录到mysql命令提示符(mysql --user userName --password databaseName)以检查max_allowed_packet,但显示为NULL,这是什么意思?
mysql> select @max_allowed_packet;
+---------------------+
| @max_allowed_packet |
+---------------------+
| NULL |
+---------------------+
1 row in set (0.00 sec)
服务器设置检查:如何检查服务器'max_allowed_packet'的GLOBAL和SESSION?我尝试将上面的“ mysql”替换为“ mysqld”,但没有任何结果和警告,与“ max_allowed_packet”的大小无关:
[useraccount@cloud ~]$ mysqld SHOW GLOBAL VARIABLES LIKE 'max_allowed_packet'
2020-02-12T07:47:33.832292Z 0 [Warning] Could not increase number of max_open_files to more than 1024 (request: 65536)
2020-02-12T07:47:33.832480Z 0 [Warning] Changed limits: max_connections: 214 (requested 256)
2020-02-12T07:47:33.832487Z 0 [Warning] Changed limits: table_open_cache: 400 (requested 2000)
2020-02-12T07:47:33.945335Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2020-02-12T07:47:33.945476Z 0 [Warning] Can't create test file /var/lib/mysql/cloud.lower-test
2020-02-12T07:47:33.945569Z 0 [Note] mysqld (mysqld 5.7.29) starting as process 75 ...
2020-02-12T07:47:33.947615Z 0 [Warning] Can't create test file /var/lib/mysql/cloud.lower-test
2020-02-12T07:47:33.947631Z 0 [Warning] Can't create test file /var/lib/mysql/cloud.lower-test
2020-02-12T07:47:33.948025Z 0 [ERROR] Could not open file '/var/log/mysqld.log' for error logging: Permission denied
2020-02-12T07:47:33.948066Z 0 [ERROR] Aborting
2020-02-12T07:47:33.948138Z 0 [Note] Binlog end
2020-02-12T07:47:33.948287Z 0 [Note] mysqld: Shutdown complete
mysqldump检查:最后,我尝试使用上述三个命令(即mysqldump SHOW VARIABLES LIKE'max_allowed_packet')用上面的三个命令读取mysqldump的max_allowed_packet,但我拒绝访问。或者,然后我成功登录到mysqldump以读取max_allowed_packet(mysqldump --user userName --password databaseName),并且在屏幕上出现很多垃圾滚动,因此我无法获得此值。
事实证明,这与MySQL没有直接关系。
致命错误:/home/client/public_html/phpfile.php中的第175行允许的内存大小为134217728字节已用尽(尝试分配32000179字节)
这是一条PHP错误消息,它告诉您您的脚本已选中128M memory limit。
您可以使用以下方法在配置文件或脚本中增加限制:>
ini_set('memory_limit','256M');
您可以使用
-1
作为值来完全禁用该限制。
但是-您应该避免复制大量数据。
以下情况很清楚:
$itemAttributes=$_POST['itemAttributes'];
您将32M数据复制到新变量中。现在您的脚本至少为6400万。
带有参数的execute()
方法比较棘手,我不确定以下情况是否正确:您将新数组作为参数传递
[$itemName,$itemAttributes]
此数组在传递给
execute()
之前,首先需要在内存中创建。这又消耗了至少3200万。然后由于内部实现(我不知道),每个数组元素都传递给类似bindValue()
的东西,它将再次复制所有数据。此时,您的脚本已达到128M的限制(32 * 4)。
因此,您应该执行以下操作:
删除这些行:
$itemAttributes=$_POST['itemAttributes']; $itemName=$_POST['itemName'];
准备声明:
$stmt = $conn->prepare("INSERT INTO $itemTable (`itemName`, `itemAttributes`) VALUES (?, ?)");
用bindParam绑定参数:
$stmt->bindParam(1, $_POST['itemName'], PDO::PARAM_STR); $stmt->bindParam(2, $_POST['itemAttributes'], PDO::PARAM_LOB);
[
bindParam()
正在使用call by reference,您可以在说明中看到]
。public PDOStatement :: bindParam(混合$ parameter,混合&$ variable [,整数$ data_type = PDO :: PARAM_STR [,整数$ length [,混合$ driver_options]]]):bool
&
中的[&$variable
表示将不执行任何复制,但将传递对该值的引用
注意,我通常不是按引用调用
的朋友,在不处理资源关键代码时,请避免使用它。execute([..])
在大多数情况下都可以。如果要查看已分配了多少内存,可以在脚本末尾的某个位置使用memory_get_peak_usage()。