【问题标题】:WordPress: Deadlock on some queries without transaction?WordPress:一些没有事务的查询死锁?
【发布时间】:2022-01-08 22:54:05
【问题描述】:

最近,在较高的流量期间,我开始遇到这些 PHP 错误:

Got error 'PHP message: Deadlock found when trying to get lock; try restarting transaction
INSERT INTO `wp_48_cf7dbplugin_submits` (`submit_time`, `form_name`, `field_name`, `field_value`, `field_order`) VALUES ('1641679333.361248', 'order', 'y_flat', '10', '8')

require('wp-blog-header.php'), wp, WP->main, WP->parse_request, do_action_ref_array('parse_request'), WP_Hook->do_action, WP_Hook->apply_filters, rest_api_loaded, WP_REST_Server->serve_request, WP_REST_Server->dispatch, WP_REST_Server->respond_to_request, WPCF7_REST_Controller->create
_feedback, WPCF7_ContactForm->submit, WPCF7_Submission::get_instance, WPCF7_Submission->proceed, WPCF7_Submission->before_send_mail, do_action_ref_array('wpcf7_before_send_mail'), WP_Hook->do_action, WP_Hook->apply_filters, CFDBIntegrationContactForm7->saveFormData, CF7DBPlugin->saveFormData

这会持续几个,但不是全部,更多的查询。它是带有 WPCF7DB 插件的 WordPress。

我检查了,WordPress 或插件中没有任何交易。

插件遍历每个字段,然后使用简单的wpdb::preparewpdb::query 组合:

$parametrizedQuery = "INSERT INTO `$tableName` (`submit_time`, `form_name`, `field_name`, `field_value`, `field_order`) VALUES (%s, %s, %s, %s, %s)";

$wpdb->query($wpdb->prepare($parametrizedQuery,
  $time,
  $title,
  $nameClean,
  $valueClean,
  $order++));
}

表结构:

CREATE TABLE `wp_48_cf7dbplugin_submits` (
  `submit_time` decimal(16,6) NOT NULL,
  `form_name` varchar(127) CHARACTER SET utf8 DEFAULT NULL,
  `field_name` varchar(127) CHARACTER SET utf8 DEFAULT NULL,
  `field_value` longtext CHARACTER SET utf8 DEFAULT NULL,
  `field_order` int(11) DEFAULT NULL,
  `file` longblob DEFAULT NULL,
  KEY `submit_time_idx` (`submit_time`),
  KEY `form_name_idx` (`form_name`),
  KEY `field_name_idx` (`field_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

奇怪的是,它只发生在循环中每次不同的几个字段中。

数据库引擎是 5.5.5-10.5.9-MariaDB-1:10.5.9+maria~buster 和 PHP 7.4。

您知道是什么原因造成的吗?

引擎状态报告:

=====================================
2022-01-10 13:27:13 0x7fd4b0066700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 69 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 95869 srv_active, 0 srv_shutdown, 20734661 srv_idle
srv_master_thread log flush and writes: 20829772
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 30716
OS WAIT ARRAY INFO: signal count 16274
RW-shared spins 274138, rounds 2338467, OS waits 886
RW-excl spins 952, rounds 16506, OS waits 360
RW-sx spins 102, rounds 1188, OS waits 34
Spin rounds per wait: 8.53 RW-shared, 17.34 RW-excl, 11.65 RW-sx
------------
TRANSACTIONS
------------
Trx id counter 4055001
Purge done for trx's n:o < 4055001 undo n:o < 0 state: running
History list length 10
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 422025324769496, not started
0 lock struct(s), heap size 1128, 0 row lock(s)
--------
FILE I/O
--------
Pending normal aio reads:
Pending flushes (fsync) log: 0; buffer pool: 0
37144192 OS file reads, 2402390 OS file writes, 2249175 OS fsyncs
21.38 reads/s, 16372 avg bytes/read, 1.22 writes/s, 1.28 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 17, free list len 77, seg size 95, 3690 merges
merged operations:
 insert 136065, delete mark 309, delete 171
discarded operations:
 insert 9389, delete mark 13, delete 13
0.00 hash searches/s, 4840.34 non-hash searches/s
---
LOG
---
Log sequence number 5800939056
Log flushed up to   5800939056
Pages flushed up to 5773682207
Last checkpoint at  5773682207
0 pending log flushes, 0 pending chkp writes
2147483 log i/o's done, 1.22 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 167772160
Dictionary memory allocated 3290232
Buffer pool size   8065
Free buffers       0
Database pages     8065
Old database pages 2957
Modified db pages  2027
Percent of dirty pages(LRU & free pages): 25.130
Max dirty pages percent: 90.000
Pending reads 0
Pending writes: LRU 0, flush list 0
Pages made young 1979022, not young 1458024765
21.80 youngs/s, 2893.80 non-youngs/s
Pages read 37142927, created 257902, written 250427
21.38 reads/s, 0.06 creates/s, 0.00 writes/s
Buffer pool hit rate 998 / 1000, young-making rate 1 / 1000 not 149 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 8065, unzip_LRU len: 0
I/O sum[1474]:cur[0], unzip sum[0]:cur[0]
--------------
ROW OPERATIONS
--------------
0 read views open inside InnoDB
Process ID=0, Main thread ID=0, state: sleeping
Number of rows inserted 26238521, updated 97796, deleted 3496, read 1479166152
1.13 inserts/s, 0.01 updates/s, 0.00 deletes/s, 4830.65 reads/s
Number of system rows inserted 48, updated 0, deleted 48, read 101
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================

【问题讨论】:

  • 死锁是用户应用程序需要解决的问题。这个percona article 描述了它。需要show create table wp_48_cf7dbplugin_submits 和冲突中其他事务的详细信息。这也是您问题中的插入语句是 SQL 事务中的唯一语句吗?您能否包含有关上次检测到的死锁的SHOW ENGINE INNODB STATUS 位?
  • @danblack 每个表单提交大约有 25 个插入与此查询。最让我烦恼的是事务从未在代码中启动。这可能是由于启用了自动提交吗?我用表结构更新了我的问题,一旦获得使用查询的权限就会添加 innodb 状态
  • 我建议在该表上定义一个自增主键。那些假死锁是个谜,但过去我已经在一个使用客户端生成的 UUID 作为主键的应用程序中目睹了它们,并且它们随着服务器生成的自动增量而消失了。如果你不定义主键,Innodb 会定义一些隐含的东西,而且这个东西可能不像自动增量主键那样久经考验。此外,主键是正确的东西,即使你现在不使用它们,你可能在将来。
  • @VladislavVaintroub 谢谢,我可能会这样做。无论如何,插件的支持都被放弃了。我试图将整个循环包装到一个实际的事务中,但错误仍然存​​在。

标签: php mysql wordpress mariadb


【解决方案1】:

解决这些假死锁的方法是为表创建一个主自动递增键:

ALTER TABLE wp_48_cf7dbplugin_submits ADD id int NOT NULL AUTO_INCREMENT primary key;

【讨论】:

    猜你喜欢
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多