M. *_*irn 5 php mysql innodb zend-framework gearman
我在handels的系统上工作了很多更新,插入和删除请求.这就是为什么我选择INNODB作为我的存储引擎行锁的原因.我们每10分钟更新60,000条记录.我们正在使用Gearman来平衡我们在不同服务器上的工作.代码是PHP,我们使用的是Zend Framework.
所以让我们从我们问题的描述开始.我们正在记录错误,几乎每隔5-20分钟就会发生一次错误.
SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction
Run Code Online (Sandbox Code Playgroud)
简单扩展"锁定等待超时"对我们没有帮助,因为我们尝试尽快更新.
为了获得更多信息,我做了SHOW INNODB STATUS\G
.有一件事让我问 - 黑客是什么?
---TRANSACTION 0 18126657, ACTIVE 54 sec, process no 16154,
OS thread id 47956454176512 fetching rows, thread declared inside InnoDB 68 mysql tables in use 1,
locked 1 1204 lock struct(s), heap size 112624, 65338 row lock(s), undo log entries 44
MySQL thread id 3331522, query id 103362521 [ServerIP] [USER] Updating
UPDATE userproducts SET lowest_price=16.96, last_lowest_price_update='2012-09-09 20:07:30' WHERE product_id LIKE 'XXX'
Run Code Online (Sandbox Code Playgroud)
65388行被锁定,因为这个简单的更新?或者我只是想念一些东西?遵循完成此更新的PHP代码.
$this->db->beginTransaction();
try {
for($i = 0; $i < count($products); $i++)
{
if(isset($products[$i]['price_total_end']))
{
if(count($products[$i]['price_total_end']) > 1)
{
$this->db->query("UPDATE userproducts SET lowest_price=".$products[$i]['price_total_end'][1].", last_lowest_price_update='".date("Y-m-d H:i:s", time())."' WHERE product_id LIKE '".$products[$i]['p_id']."'");
} elseif(count($asin[$i]['price_total_end']) == 1) {
$this->db->query("UPDATE userproducts SET lowest_price=-1, last_lowest_price_update='".date("Y-m-d H:i:s", time())."' WHERE product_id LIKE '".$products[$i]['p_id']."'");
}
}
}
$this->db->commit();
} catch (Exception $e) {
$this->db->rollBack();
echo $e->getMessage();
}
Run Code Online (Sandbox Code Playgroud)
Array $产品在他的第一个50级参赛作品中.所以计数到50,这不应该那么多,或者这绝对是不是很大?接下来应该忘记的是,有20名工人可以同时执行这个查询.
最后一个重要信息 - 我认为 - 是mysql_report
.
MySQL 5.1.63-0+squeeze1 uptime 13 9:11:39 Sun Sep 9 20:44:50 2012
__ Key ___
Buffer used 55.00k of 16.00M %Used: 0.34
Current 2.92M %Usage: 18.28
Write hit 99.95%
Read hit 100.00%
__ Questions ___
Total 103.61M 89.6/s
DMS 90.73M 78.5/s %Total: 87.57
Com_ 8.57M 7.4/s 8.27
COM_QUIT 3.34M 2.9/s 3.22
QC Hits 922.81k 0.8/s 0.89
+Unknown 46.70k 0.0/s 0.05
Slow 2 s 9.33M 8.1/s 9.00 %DMS: 10.28 Log: ON
DMS 90.73M 78.5/s 87.57
INSERT 60.63M 52.4/s 58.51 66.82
UPDATE 17.80M 15.4/s 17.17 19.61
DELETE 9.55M 8.3/s 9.22 10.53
SELECT 2.76M 2.4/s 2.66 3.04
REPLACE 0 0/s 0.00 0.00
Com_ 8.57M 7.4/s 8.27
set_option 3.40M 2.9/s 3.28
show_fields 2.88M 2.5/s 2.78
begin 1.13M 1.0/s 1.09
__ SELECT and Sort ____
Scan 3.60M 3.1/s %SELECT: 130.54
Range 47 0.0/s 0.00
Full join 24 0.0/s 0.00
Range check 0 0/s 0.00
Full rng join 1 0.0/s 0.00
Sort scan 24.32k 0.0/s
Sort range 1.69M 1.5/s
Sort mrg pass 0 0/s
__ Query Cache ___
Memory usage 1.05M of 16.00M %Used: 6.57
Block Fragmnt 4.55%
Hits 922.81k 0.8/s
Inserts 2.11M 1.8/s
Insrt:Prune 2.36k:1 1.8/s
Hit:Insert 0.44:1
__ Table Locks ____
Waited 658 0.0/s %Total: 0.00
Immediate 90.73M 78.5/s
__ Tables ___
Open 128 of 128 %Cache: 100.00
Opened 3.95k 0.0/s
__ Connections __
Max used 301 of 300 %Max: 100.33
Total 3.34M 2.9/s
__ Created Temp ___
Disk table 2.88M 2.5/s
Table 2.89M 2.5/s Size: 32.0M
File 5 0.0/s
__ Threads ___
Running 21 of 168
Cached 6 of 8 %Hit: 97.09
Created 97.29k 0.1/s
Slow 0 0/s
__ Aborted ___
Clients 2.45k 0.0/s
Connects 2.75k 0.0/s
__ Bytes ___
Sent 11.04G 9.5k/s
Received 23.13G 20.0k/s
__ InnoDB Buffer Pool _____
Usage 82.86M of 1.46G %Used: 5.52
Read hit 100.00%
Pages
Free 90.70k %Total: 94.48
Data 4.92k 5.12 %Drty: 4.07
Misc 386 0.40
Latched 0 0.00
Reads 610.88G 528.3k/s
From file 816 0.0/s 0.00
Ahead Rnd 3 0.0/s
Ahead Sql 27 0.0/s
Writes 614.37M 531.3/s
Flushes 10.07M 8.7/s
Wait Free 0 0/s
__ InnoDB Lock ___
Waits 837060 0.7/s
Current 19
Time acquiring
Total 157140176 ms
Average 18772 ms
Max 59096 ms
__ InnoDB Data, Pages, Rows __
Data
Reads 919 0.0/s
Writes 11.96M 10.3/s
fsync 6.26M 5.4/s
Pending
Reads 0
Writes 0
fsync 0
Pages
Created 39.41k 0.0/s
Read 2.64k 0.0/s
Written 10.07M 8.7/s
Rows
Deleted 40.82M 35.3/s
Inserted 42.90M 37.1/s
Read 540.45G 467.4k/s
Updated 47.48M 41.1/s
Run Code Online (Sandbox Code Playgroud)
所以回到所有问题.为什么我们总是得到1205锁定等待超时错误?
更新:
我现在尝试了其他一些事情.首先,我将更改为INSERT ... ON DUPLICATE KEY UPDATE
更新,如果没有任何影响,程序应该执行插入操作.由于以下两个原因.1. 99.9%的此类操作是更新.我知道 - 不清楚那个伪造的 - 可能INSERT
是一个桌子锁.
但没有改变.之后我用独特的钥匙尝试了tipp.没有改变.
然后我有了这个想法,MySQL有许多"睡眠"过程.我这件事是由非常长时间运行的Gearman Scripts造成的?所以我更改了例如我之前发布的UPDATE代码.
$this->db->beginTransaction();
try {
for($i = 0; $i < count($asin); $i++)
{
if(isset($asin[$i]['price_total_end']))
{
if(count($asin[$i]['price_total_end']) > 1)
{
// Es konnten Konkurrenten ausgemacht werden
if( $asin[$i]['price_total_end'][0] > 0 )
{
// Prüfe ob der eigene Preis der günstigste ist
if( $asin[$i]['merchant_end'][0] == $merchantId )
{
// Ja der eigene Preis ist der günstigste, deshalb soll der nächste Preis der lowest sein.
$this->db->query("UPDATE userproducts SET lowest_price=".$asin[$i]['price_total_end'][1].", last_lowest_price_update='".date("Y-m-d H:i:s", time())."' WHERE product_id LIKE '".$asin[$i]['asin']."'");
} else {
$this->db->query("UPDATE userproducts SET lowest_price=".$asin[$i]['price_total_end'][0].", last_lowest_price_update='".date("Y-m-d H:i:s", time())."' WHERE product_id LIKE '".$asin[$i]['asin']."'");
}
}
} elseif(count($asin[$i]['price_total_end']) == 1) {
if( $asin[$i]['price_total_end'][0] >= 0 )
{
$this->db->query("UPDATE userproducts SET lowest_price=-1, last_lowest_price_update='".date("Y-m-d H:i:s", time())."' WHERE product_id LIKE '".$asin[$i]['asin']."'");
}
}
}
}
$this->db->commit();
} catch (Exception $e) {
$this->db->rollBack();
echo $e->getMessage();
}
**$this->db->closeConnection();**
Run Code Online (Sandbox Code Playgroud)
但没有改变.连接仍然是301和Threads在32.我的代码有什么问题.
我真的无法面对这个问题.
我们非常欢迎您的想法和想法.多谢你们.
首先尝试使用以下命令获取所有产品的主键:
SELECT primaryKey WHERE product_id LIKE '".$products[$i]['p_id']."'"
Run Code Online (Sandbox Code Playgroud)
然后循环结果并使用 WHERE 部分中的 PrimaryKey 更新它们。
对您的所有 $products 重复此操作。并在所有迭代结束后提交。
我的直觉/早期经验告诉你,你应该能够以这种方式避免僵局,但遗憾的是我无法解释原因。
归档时间: |
|
查看次数: |
432 次 |
最近记录: |