mysql INSERT失败,但未引发任何错误:max_allowed_pa cket:设置显示冲突的结果

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

我已通过_POST成功将数据接收到服务器客户端帐户中,但是当行数据大于约25MB时,我无法将数据插入包含longblob类型的行表。我看不到php准备好的语句/文件引发的任何错误,php文件正常关闭。我正在检查我的max_allowed_pa​​cket是否正确配置。

我没有服务器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_pa​​cket并在所有位置正确设置?

客户端设置检查:所有这三个检查都给了我256MB max_allowed_pa​​cket:

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_pa​​cket,但显示为NULL,这是什么意思?

mysql> select @max_allowed_packet;
+---------------------+
| @max_allowed_packet |
+---------------------+
| NULL                |
+---------------------+
1 row in set (0.00 sec)

服务器设置检查:如何检查服务器'max_allowed_pa​​cket'的GLOBAL和SESSION?我尝试将上面的“ mysql”替换为“ mysqld”,但没有任何结果和警告,与“ max_allowed_pa​​cket”的大小无关:

[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_pa​​cket')用上面的三个命令读取mysqldump的max_allowed_pa​​cket,但我拒绝访问。或者,然后我成功登录到mysqldump以读取max_allowed_pa​​cket(mysqldump --user userName --password databaseName),并且在屏幕上出现很多垃圾滚动,因此我无法获得此值。

php mysql post max-allowed-packet
1个回答
0
投票

事实证明,这与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()

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