Dan*_*ano 10 php mysql php-5.3
当我使用PHP从资源(查询)获取行时,我得到一个非常奇怪,毫无意义且完全随机的错误.
我的开发机器是带有Apache 2.2的Windows XP SP3,而MySQL运行在虚拟机上,使用ubuntu 10.04,带有768mb的RAM,100GB的HDD和4个逻辑内核(Intel q6600).但是这个问题与Windows上的PHP无关,因为我在数据库机器上运行代码时遇到了同样的错误.
我正在使用mysql
扩展(不是mysqli
或者mysqlnd
),但环顾四周我创建了一个关于这个与mysqlnd扩展相关的错误的补丁,所以,我可能会尝试.
主要的问题是,当我执行这个查询(一个带有几个派生表和超过20个连接的真正大的查询)并且处理结果很快并且一切顺利时,但是当我的代码花费大约15/20秒来处理块时行(我需要从它们之间以非常特殊的方式链接的行块构建一个对象,我不能改变它,数据库不是我的,并且从这个对象生成一些PDF)一段时间后(随机时间)我收到此错误"空行数据包正文".
我使用无缓冲的查询来减少内存消耗(如果我启用缓冲,我得到大约260MB的已用内存),但这应该不是问题.
小智 19
我遇到了同样的错误.我正在使用PDO,但基本上应该是同样的事情.
你在MyISAM桌上操作吗?如果是这样,问题可能与引擎使用的锁定模型有关:它锁定整个表,用于使用共享锁读取,用于使用独占锁写入.
这就是我想要做的:读取一个没有缓冲的大结果集,并更新同一个表中的一些行.由于您在同一连接上保存无缓冲的结果集时无法发出语句,因此我尝试使用另一个连接进行更新.阅读进行得很顺利,直到第一次更新,此时脚本停滞了大约一分钟,然后我得到了"空行数据包正文"错误.
您会看到,在读取无缓冲时,将保留共享锁,直到读取整个结果集或关闭光标.在此期间,表使用共享锁锁定,因此其他连接可以获取表上的共享锁(换句话说,从中读取),但是必须等待独占锁(用于写入).如果这发生在同一个脚本中,它将会死锁.
现在,为了防止无休止的死锁,MySQL会在一段时间后强行释放你的共享锁(IIRC受table_lock_wait_timeout的值影响),转储结果集并允许带有等待的独占锁的写语句轮到它.
所以,虽然在我的情况下,它是相同的脚本,并且因此在超时到期之前停止,也可能是某些其他脚本正在尝试对表执行写操作具有相同的效果,这可能是您在案件.
解决这个问题的原因是将表类型更改为InnoDB,因为该引擎使用行级而不是表级锁.但是,既然您说数据库不是您的,那么您可能无法做到这一点.
实际问题是PHP 和 MySQL 之间的连接中断(=在PHP接收到所有数据之前停止)。
当 PHP (PDO) 执行 MySQL 查询时,它会在打开的连接上发送查询,然后等待响应。响应由一组标头和一个正文组成,有点像 HTTP 请求。
如果在 PDO 未收到所有标头时连接中断,那么您将收到警告“读取结果集标头时出错”,这意味着 PDO 无法解释响应,因为它只是部分(标头)。
如果在解析正文时连接中断,则 PDO 将产生“空行数据包正文”,对应于您的错误。有关其他信息,请参阅此 Github PR
所以解决方法是找出连接被终止的原因:
不久前出现此错误,我通过增加的值来解决它
net_read_timeout = 360
net_write_timeout = 360
Run Code Online (Sandbox Code Playgroud)
当写入时打开连接时,等待另一个查询结束以继续插入,此操作超时,给出一个空的行数据包。我正在处理非常大的数据集,使用的值超过360。您的值将取决于您的用例。
归档时间: |
|
查看次数: |
11024 次 |
最近记录: |