欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

warning error while sending query packet. pid= 有大用 有大大用

问过 
查看 167k 次
55

我试图将一些数据插入数据库,但出现此错误“发送查询数据包时出错

$insertDeta = $conPat->prepare("insert into table1(data) VALUES(:data)");
$insertDeta->bindParam(':data',$data);
$conPat->beginTransaction();    
    $insertDeta->execute();
$conPat->commit();

但我认为问题在于数据大小超过16MB。
该列的数据类型设置为longtext,我认为它可以保持数据高达 4GB。

我不知道 PDO 是否在运行查询或将 16MB 数据传输到数据库时遇到问题。这是我唯一的猜测,因为 mysql 可能会以数据包的形式
发送数据,而数据包不能容纳 16MB 的数据。

8个答案   正确答案

50

您猜对了 MySQL 对数据大小有限制,您需要将查询分成一小组记录,或者您可以通过使用更改 1)  max_allowed_packet       SET GLOBAL max_allowed_packet=524288000;  (即500M)

2)  wait_timeout                   SET GLOBAL wait_timeout=100;

 当然我是在  my.cnf  里面改的


34

您可以通过以下几个步骤解决此问题:

1)打开你的终端窗口

2)请在您的终端中输入以下命令

ssh root@yourIP port

3)输入root密码

4) 现在使用以下命令编辑您的服务器 my.cnf 文件

nano /etc/my.cnf  

如果无法识别命令,请先执行此操作或尝试 vi,然后重复:yum install nano。

或者

  vi /etc/my.cnf 

5) 在 [MYSQLD] 部分下添加行。:

max_allowed_packet=524288000 (obviously adjust size for whatever you need) 
wait_timeout = 100

6) Control + O(保存)然后 ENTER(确认)然后 Control + X(退出文件)

7)然后通过以下命令重启你的mysql服务器

/etc/init.d/mysql stop
/etc/init.d/mysql start

8) 您可以通过进入 PHPMyAdmin 或打开 SQL 命令窗口并执行来验证:

SHOW VARIABLES LIKE 'max_allowed_packet'

这对我有用。我希望它对你有用。

16

如果变量wait_timeout太低,您也可能会遇到此错误。

如果是这样,您可以将其设置得更高:

SET GLOBAL wait_timeout=10;

在我的案例中,这是相同错误的解决方案。

  • 4
    注意此变量的低值。我花了太多时间才意识到脚本深处的某处是 sleep(70);这导致丢失数据库连接,因此“发送查询数据包时出错”。因此,要么考虑至少将其设置为几分钟,要么 ping() 您的数据库以保持连接有效。  2018 年 9 月 27 日 8:50
4

添加/etc/my.cnf

  max_allowed_packet=32M

它对我有用。您可以通过进入 PHPMyAdmin 并打开 SQL 命令窗口并执行来验证:

SHOW VARIABLES LIKE  'max_allowed_packet'
4

exec('rsync');我在 cygwin 中遇到了一种罕见的边缘情况,在查询之前的某处执行时会出现此错误。可能是一般的 PHP 问题,但我只能在 cygwin 中使用 rsync 重现此问题。

$pdo = new PDO('mysql:host=127.0.0.1;dbname=mysql', 'root');
var_dump($pdo->query('SELECT * FROM db'));
exec('rsync');
var_dump($pdo->query('SELECT * FROM db'));

产生

object(PDOStatement)#2 (1) {
   ["queryString"]=>
   string(16) "SELECT * FROM db"
}
PHP Warning:  Error while sending QUERY packet. PID=15036 in test.php on line 5
bool(false)

错误报告在https://cygwin.com/ml/cygwin/2017-05/msg00272.html

2

您不能WHEREINSERT语句中包含该子句。

insert into table1(data) VALUES(:data) where sno ='45830'

应该

insert into table1(data) VALUES(:data)


更新:您已将其从代码中删除(我假设您错误地复制了代码)。您想要增加允许的数据包大小:

SET GLOBAL max_allowed_packet=32M

32M根据需要向上/向下更改(32 兆字节)。这是有关该主题的 MySQL 文档的链接。

  • SET GLOBAL max_allowed_packet=32M 在 mysql 中不起作用,它表示参数无效。但是如果我触发查询 SET GLOBAL max_allowed_packet=524288000; 我收到此错误“检查与您的 MySQL 服务器版本对应的手册,了解在第 1 行的‘SET GLOBAL max_allowed_packet=524288000’附近使用的正确语法”  2015 年 6 月 10 日 12:32 
  • 您可以运行SHOW VARIABLES LIKE 'max_allowed_packet'以查看您的最大值实际是多少。你在共享主机上吗?如果是,那么它可能会为您禁用。 
    – 奇山
     2015 年 6 月 10 日 12:43
  • 这是持久性的还是您必须在 mysql 重新启动后再次执行此操作?  2016 年 10 月 12 日 8:38
  • 1
    @cjhill 很抱歉,让我先阅读整个文档,然后再问一个随意的常见问题,该问题将在此处回答时更快地帮助人们。  2016 年 10 月 12 日 12:25
  • 1
    这是错误的-即使您链接的页面也明确指出“在服务器启动时设置变量时可以使用用于指定值乘数的后缀,但不能在运行时使用 SET 设置值”换句话说,你可以做32*1024*1024不能 32M  2017 年 3 月 7 日 17:08 
0

max_allowed_packet如果由于数据库服务器的设置导致插入“太多数据”失败,则会引发以下警告:

SQLSTATE[08S01]: Communication link failure: 1153 Got a packet bigger than 
'max_allowed_packet' bytes

如果此警告被捕获为异常(由于设置的错误处理程序),则数据库连接(可能)丢失但应用程序不知道这一点(失败的插入可能有多种原因)。下一个查询,可以很简单:

SELECT 1 FROM DUAL

然后将失败并出现此 SO 问题开始的错误:

Error while sending QUERY packet. PID=18486

用于重现我的解释的简单测试脚本,尝试使用和不使用错误处理程序以查看影响的差异:

set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) {
    // error was suppressed with the @-operator
    if (0 === error_reporting()) {
        return false;
    }

    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});

try
{
    // $oDb is instance of PDO
    var_dump($oDb->query('SELECT 1 FROM DUAL'));

    $oStatement = $oDb->prepare('INSERT INTO `test` (`id`, `message`) VALUES (NULL, :message);');
    $oStatement->bindParam(':message', $largetext, PDO::PARAM_STR);
    var_dump($oStatement->execute());
}
catch(Exception $e)
{
    $e->getMessage();
}
var_dump($oDb->query('SELECT 2 FROM DUAL'));
0

在 php 命令行中执行分叉时遇到这样的问题。在我的例子中,php 有时会杀死子进程。要解决此问题,只需使用命令pcntl_wait($status) 等待进程完成即可;

这是一个可视化示例的一段代码:

    #!/bin/php -n
    <?php
    error_reporting(E_ALL & ~E_NOTICE);
    ini_set("log_errors", 1);
    ini_set('error_log', '/media/logs/php/fork.log');
    $ski = substr(str_shuffle(str_repeat("0123456789abcdefghijklmnopqrstuvwxyz", 5)), 0, 5);
    error_log(getmypid().' '.$ski.' start my php');

    $pid = pcntl_fork();
    if($pid) {
    error_log(getmypid().' '.$ski.' start 2');
    // Wait for children to return. Otherwise they 
    // would turn into "Zombie" processes
    // !!!!!! add this !!!!!!
    pcntl_wait($status);
    // !!!!!! add this !!!!!!
    } else {
    error_log(getmypid().' '.$ski.' start 3');
    //[03-Apr-2020 12:13:47 UTC] PHP Warning:  Error while sending QUERY packet. PID=18048 in /speed/sport/fortest.php on line 22457
    mysqli_query($con,$query,MYSQLI_ASYNC);
error_log(getmypid().' '.$ski.' sleep child');
  sleep(15);
    exit;
    } 

   error_log(getmypid().' '.$ski.'end my php');
    exit(0);
    ?>

您的答案


来自  https://stackoverflow.com/questions/30753674/error-while-sending-query-packet


Asked 
Viewed 167k times
55

i was trying to insert some data into the database but i got this error "Error while sending QUERY packet"

$insertDeta = $conPat->prepare("insert into table1(data) VALUES(:data)");
$insertDeta->bindParam(':data',$data);
$conPat->beginTransaction();    
    $insertDeta->execute();
$conPat->commit();

but what i think the problem is that size of the data is over 16MB.
the data type of the column is set as longtext, which i think can keep data as big as 4GB.

I dont know if PDOs is having problems running the query or transfering 16MB of data to the database.
Thats the only guess i can make as mysql might send the data in packets and the packet cannot hold data as large as 16MB.

8 Answers

50

You guessed right MySQL have limitation for size of data, you need to break your query in small group of records or you can Change your   max_allowed_packet  by using SET GLOBAL max_allowed_packet=524288000;

  • 1
    i set max_allowed_packet to 256M in my.ini file, but it didnt work.  Jun 10, 2015 at 11:39
  • and if i fire a query to SET GLOBAL max_allowed_packet=524288000; i get this error "check the manual that corresponds to your MySQL server version for the right syntax to use near 'SET GLOBAL max_allowed_packet=524288000' at line 1"  Jun 10, 2015 at 11:42 
  • 1
    Is there anyway to log the query which triggered this warn?  Jul 24, 2018 at 12:52
  • 2
    wow cool, it works for me. i though it is from the logs, and also make sure to check your post_max_size and upload_max_filesize in php.ini  Nov 5, 2018 at 8:30
34

You can solve this problem by following few steps:

1) open your terminal window

2) please write following command in your terminal

ssh root@yourIP port

3) Enter root password

4) Now edit your server my.cnf file using below command

nano /etc/my.cnf  

if command is not recognized do this first or try vi then repeat: yum install nano.

OR

  vi /etc/my.cnf 

5) Add the line under the [MYSQLD] section. :

max_allowed_packet=524288000 (obviously adjust size for whatever you need) 
wait_timeout = 100

6) Control + O (save) then ENTER (confirm) then Control + X (exit file)

7) Then restart your mysql server by following command

/etc/init.d/mysql stop
/etc/init.d/mysql start

8) You can verify by going into PHPMyAdmin or opening a SQL command window and executing:

SHOW VARIABLES LIKE 'max_allowed_packet'

This works for me. I hope it should work for you.

  • 1
    The default value for wait_timeout is 28800 seconds. Why would you lower it to 100?  Nov 23, 2017 at 21:01
  • 1
    Any answer to the comment above? I'd be interested in learning why 100 only... I have 500MB in max_allowed_packet, wait_timeout 100 and it is still crashing with the same error message. What could it be?  Jun 20, 2018 at 15:25
  • Perhaps,100 is higher than some host's custom default value? But that is just a guess. 
    – Jake N
     Dec 17, 2020 at 9:10
  • Note If you're on AWS: I had to do sudo vi /etc/my.cnf and to restart mysql I had to instead do sudo service mysqld restart 
    – Curtis
     Apr 18, 2021 at 6:06
16

You may also have this error if the variable wait_timeout is too low.

If so, you may set it higher like that:

SET GLOBAL wait_timeout=10;

This was the solution for the same error in my case.

  • 4
    Watch out for low values with this variable. I spent way too much time only to realize that somewhere deep in a script was sleep(70); which was causing lost DB connection and therefore “Error while sending QUERY packet”. So either consider setting it up at least as minutes or ping() your DB to keep the connection alive. 
    – Mirous
     Sep 27, 2018 at 8:50
4

In /etc/my.cnf add:

  max_allowed_packet=32M

It worked for me. You can verify by going into PHPMyAdmin and opening a SQL command window and executing:

SHOW VARIABLES LIKE  'max_allowed_packet'
4

I encountered a rare edge case in cygwin, where I would get this error when doing exec('rsync'); somewhere before the query. Might be a general PHP problem, but I could only reproduce this in cygwin with rsync.

$pdo = new PDO('mysql:host=127.0.0.1;dbname=mysql', 'root');
var_dump($pdo->query('SELECT * FROM db'));
exec('rsync');
var_dump($pdo->query('SELECT * FROM db'));

produces

object(PDOStatement)#2 (1) {
   ["queryString"]=>
   string(16) "SELECT * FROM db"
}
PHP Warning:  Error while sending QUERY packet. PID=15036 in test.php on line 5
bool(false)

Bug reported in https://cygwin.com/ml/cygwin/2017-05/msg00272.html

2

You cannot have the WHERE clause in an INSERT statement.

insert into table1(data) VALUES(:data) where sno ='45830'

Should be

insert into table1(data) VALUES(:data)


Update: You have removed that from your code (I assume you copied the code in wrong). You want to increase your allowed packet size:

SET GLOBAL max_allowed_packet=32M

Change the 32M (32 megabytes) up/down as required. Here is a link to the MySQL documentation on the subject.

  • SET GLOBAL max_allowed_packet=32M isnt working in mysql, it says invalid argument. but if i fire a query to SET GLOBAL max_allowed_packet=524288000; i get this error "check the manual that corresponds to your MySQL server version for the right syntax to use near 'SET GLOBAL max_allowed_packet=524288000' at line 1"  Jun 10, 2015 at 12:32 
  • You can run SHOW VARIABLES LIKE 'max_allowed_packet' to see what your max value actually is. Are you on a shared host? If yes then it might be disabled for you. 
    – cjhill
     Jun 10, 2015 at 12:43
  • Is this persistent or do you have to do this again after mysql restarts?  Oct 12, 2016 at 8:38
  • 1
    @cjhill Well sorry about that, let me read the entire docs first before I ask a casual common question that is going to help people faster when answered here.  Oct 12, 2016 at 12:25
  • 1
    this is wrong - even the page you linked says specifically "Suffixes for specifying a value multiplier can be used when setting a variable at server startup, but not to set the value with SET at runtime". In other words you can do 32*1024*1024 but not 32M.  Mar 7, 2017 at 17:08 
0

If inserting 'too much data' fails due to the max_allowed_packet setting of the database server, the following warning is raised:

SQLSTATE[08S01]: Communication link failure: 1153 Got a packet bigger than 
'max_allowed_packet' bytes

If this warning is catched as exception (due to the set error handler), the database connection is (probably) lost but the application doesn't know about this (failing inserts can have several causes). The next query in line, which can be as simple as:

SELECT 1 FROM DUAL

Will then fail with the error this SO-question started:

Error while sending QUERY packet. PID=18486

Simple test script to reproduce my explanation, try it with and without the error handler to see the difference in impact:

set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) {
    // error was suppressed with the @-operator
    if (0 === error_reporting()) {
        return false;
    }

    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});

try
{
    // $oDb is instance of PDO
    var_dump($oDb->query('SELECT 1 FROM DUAL'));

    $oStatement = $oDb->prepare('INSERT INTO `test` (`id`, `message`) VALUES (NULL, :message);');
    $oStatement->bindParam(':message', $largetext, PDO::PARAM_STR);
    var_dump($oStatement->execute());
}
catch(Exception $e)
{
    $e->getMessage();
}
var_dump($oDb->query('SELECT 2 FROM DUAL'));
0

Had such a problem when executing forking in php for command line. In my case from time to time the php killed the child process. To fix this, just wait for the process to complete using the command pcntl_wait($status);

here's a piece of code for a visual example:

    #!/bin/php -n
    <?php
    error_reporting(E_ALL & ~E_NOTICE);
    ini_set("log_errors", 1);
    ini_set('error_log', '/media/logs/php/fork.log');
    $ski = substr(str_shuffle(str_repeat("0123456789abcdefghijklmnopqrstuvwxyz", 5)), 0, 5);
    error_log(getmypid().' '.$ski.' start my php');

    $pid = pcntl_fork();
    if($pid) {
    error_log(getmypid().' '.$ski.' start 2');
    // Wait for children to return. Otherwise they 
    // would turn into "Zombie" processes
    // !!!!!! add this !!!!!!
    pcntl_wait($status);
    // !!!!!! add this !!!!!!
    } else {
    error_log(getmypid().' '.$ski.' start 3');
    //[03-Apr-2020 12:13:47 UTC] PHP Warning:  Error while sending QUERY packet. PID=18048 in /speed/sport/fortest.php on line 22457
    mysqli_query($con,$query,MYSQLI_ASYNC);
error_log(getmypid().' '.$ski.' sleep child');
  sleep(15);
    exit;
    } 

   error_log(getmypid().' '.$ski.'end my php');
    exit(0);
    ?>

Your Answer

来自  https://stackoverflow.com/questions/30753674/error-while-sending-query-packet




普通分类: