- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有独立的服务器和 2000 个在线用户(不是很多)。带有表 request_action 的 MySQL DB 5.6(没有自动增量的复合 PK 但增量在触发器中,您可以在下面看到它):
CREATE TABLE `request_action` (
`ra_id` bigint(20) NOT NULL,
`cl_id` int(11) NOT NULL DEFAULT '0',
`ra_r_id` bigint(20) NOT NULL,
`ra_tr_id` bigint(20) DEFAULT '0',
`ra_ss_id` bigint(20) NOT NULL DEFAULT '0',
`ra_h_id` int(11) NOT NULL DEFAULT '0',
`ra_uch_id` bigint(20) DEFAULT '0',
`ra_u_id` int(11) DEFAULT '0',
`ra_datetime` datetime NOT NULL,
`ra_uct_id` int(11) NOT NULL DEFAULT '0',
`ra_text` longtext NOT NULL,
`ra_datetime_reply` datetime NOT NULL,
`ra_reply` longtext NOT NULL,
`ra_line_breaks` tinyint(4) NOT NULL DEFAULT '0',
`ra_plan` tinyint(4) NOT NULL DEFAULT '0',
`ra_shw` tinyint(4) NOT NULL DEFAULT '1',
`ra_to_u_id` int(11) DEFAULT '0',
`ra_created_at` datetime DEFAULT NULL,
`ra_seen` tinyint(4) NOT NULL DEFAULT '0',
`ra_seen_u_id` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`cl_id`,`ra_id`),
KEY `rm_r_id` (`ra_r_id`),
KEY `ra_u_id` (`ra_u_id`),
KEY `ra_plan` (`ra_plan`),
KEY `ra_rat_id` (`ra_ss_id`),
KEY `ra_h_id` (`ra_h_id`),
KEY `ra_tr_id` (`ra_tr_id`),
KEY `ra_id` (`ra_id`),
KEY `ra_datetime` (`ra_datetime`,`ra_seen`),
KEY `ra_shw` (`ra_shw`,`ra_seen`,`ra_to_u_id`),
KEY `ra_r_id` (`ra_r_id`,`ra_tr_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
在此表上触发(插入前):
if (cast(NEW.ra_id as UNSIGNED) = 0) then
SET NEW.ra_id = (SELECT COALESCE(MAX(ra_id)+1, 1) FROM request_action WHERE cl_id = NEW.cl_id);
end if
而且我一天有很多次死锁((例如,一天有 100 次。
LATEST DETECTED DEADLOCK
------------------------
2019-02-21 21:09:34 7f5e11f3b700
*** (1) TRANSACTION:
TRANSACTION 2947112777, ACTIVE 0 sec inserting
mysql tables in use 11, locked 11
LOCK WAIT 5 lock struct(s), heap size 1184, 3 row lock(s)
MySQL thread id 19952598, OS thread handle 0x7f5e10e38700, query id 248552715 192.168.0.7 vh_uon_com_ru
insert into request_action (
ra_r_id,
ra_u_id,
ra_datetime,
ra_text,
ra_datetime_reply,
ra_reply,
ra_plan,
cl_id,
ra_tr_id,
ra_ss_id,
ra_h_id,
ra_uch_id,
ra_to_u_id,
ra_uct_id,
ra_shw
) values (
40053,
906,
'2019-02-21 21:09:34',
'Звонок',
'2019-02-21 21:09:34',
'',
'0',
698,
0,
0,
0,
171114,
0,
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 2320 page no 546708 n bits 104 index `PRIMARY` of table `request_action` trx id 2947112777 lock_mode X locks gap before rec insert intention waiting
*** (2) TRANSACTION:
TRANSACTION 2947112774, ACTIVE 0 sec inserting
mysql tables in use 11, locked 11
5 lock struct(s), heap size 1184, 3 row lock(s)
MySQL thread id 19952597, OS thread handle 0x7f5e11f3b700, query id 248552705 192.168.0.7
insert into request_action (
ra_r_id,
ra_u_id,
ra_datetime,
ra_text,
ra_datetime_reply,
ra_reply,
ra_plan,
cl_id,
ra_tr_id,
ra_ss_id,
ra_h_id,
ra_uch_id,
ra_to_u_id,
ra_uct_id,
ra_shw
) values (
25182,
906,
'2019-02-21 21:09:34',
'Звонок',
'2019-02-21 21:09:34',
'',
'0',
698,
0,
0,
0,
171113,
0,
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 2320 page no 546708 n bits 104 index `PRIMARY` of table `request_action` trx id 2947112774 lock mode S locks gap before rec
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 2320 page no 546708 n bits 104 index `PRIMARY` of table `request_action` trx id 2947112774 lock_mode X locks gap before rec insert intention waiting
*** WE ROLL BACK TRANSACTION (2)
在 my.cf 中我们有以下选项:
max_connections = 10000
key_buffer_size = 1024M
join_buffer_size = 256M
read_buffer_size = 256M
sort_buffer_size = 256M
tmp_table_size = 512M
read_rnd_buffer_size = 8M
max_heap_table_size = 512M
thread_cache_size = 8192
query_cache_type = 1
query_cache_size = 15G
wait_timeout = 6000
connect_timeout = 15
interactive_timeout = 60
max_allowed_packet = 512M
bulk_insert_buffer_size = 64M
innodb_log_file_size = 512M
innodb_log_buffer_size = 2G
innodb_buffer_pool_size = 20G
你能帮我解决死锁问题吗?我该如何解决?我应该在死锁中重新运行查询吗?
最佳答案
TL;DR -- 当您尝试为每个不同的 cl_id
生成一个新的递增 id 时,您不能进行并发插入。您必须使用表锁来执行此操作,从而导致并发插入串行运行。
AUTO_INCREMENT
绕过这个死锁的原因是它获得了一个简短的表锁来生成下一个 id。从技术上讲,这会导致所有执行 INSERT 操作的并发 session 串行执行。幸运的是,表锁非常简短。默认情况下,它会在生成 id 后立即发布。您可以在此处阅读更多信息:https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html
而您生成 id 的方法导致死锁,因为它使用了两个锁定操作:
但是锁不是一起获取的,两个步骤之间有一个短暂的时间,这就是竞争条件发生的地方。我们可以使用两个表来证明这一点:
mysql> create table foo ( id serial primary key);
mysql> insert into foo (id) values (1);
mysql> create table bar ( id serial primary key);
mysql> create trigger b before insert on bar
for each row set new.id=(select max(id) from foo);
现在我们在 bar
上有一个触发器,它将读取 foo
中的一些行以获得 max(id)。
mysql> begin;
mysql> insert into bar () values ();
这应该使用从 foo
中读取的值在 bar
中创建一个新行。但交易仍在进行中。
在第二个窗口中,执行此操作:
mysql> update foo set id = 2;
...
这会挂起,等待它在 foo
上的 X 锁。它无法更新 foo
,因为它上面已经有一个 S 锁,由第一个窗口中的 session 放置。
回到第一个窗口并运行:
mysql> update foo set id = 3;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
这会创建一个循环锁等待,这就是死锁。两个事务都在等待另一个事务持有的锁。我们在第二个窗口中看到,该交易被终止:
mysql> update foo set id = 2;
...
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
“我该如何解决?我应该在死锁中重新运行查询吗?”
一种解决方法是强制并发 session 连续运行,方法是在尝试插入之前获取对 INSERT 或触发器引用的所有表的表锁。
mysql> begin;
mysql> lock tables foo write, bar write;
mysql> insert into bar () values ();
第二个窗口挂起,但这次卡在表锁上,而不是行锁上。
mysql> update foo set id = 2;
...
在第一个窗口中,完成交易。解锁表锁会隐式提交事务。
mysql> unlock tables;
第二个窗口停止等待,并成功完成更新。
mysql> update foo set id = 2;
...
Query OK, 1 row affected (3.50 sec)
Rows matched: 1 Changed: 1 Warnings: 0
请注意,它已经等待了 3.5 秒,这是我返回第一个窗口并提交事务所花费的时间。
连续插入 session 会限制应用的吞吐量,因为 session 会排队。但它避免了死锁。
关于具有复合主键和触发器自动增量的 MySQL 死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54816599/
这个问题已经有答案了: What is x after "x = x++"? (18 个回答) 已关闭 6 年前。 public static void main(String[] args)
我目前正在使用 jquery 循环插件。我有 3 个不同的幻灯片,它们彼此相邻并同时循环播放。我想做的是先关闭第一张幻灯片,然后是第二张幻灯片,然后是第三张幻灯片。无论如何,我可以通过增量或超时来做到
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: ++someVariable Vs. someVariable++ in Javascript 我知道您可以
我一直在查看 SVN 手册,但无法找到“svn log”和“svn st”的“--incremental”选项的简单用法示例或解释。 我正在编写一个开源 SVN GUI 前端,因此我需要一些有关此标志
我有这种矩阵。 非常抱歉,我没有可重现的示例。 表 1: [,1][,2][,3][,4][,5][,6][,7][,8][,9][,10] [1,] 3 NA NA NA
我在hdfs中有一个 Parquet 文件作为我的数据的初始加载。接下来的所有拼花地板只是这些数据集每天都会更改为初始负载(按时间顺序)。这是我的三角洲。 我想读取全部或部分 Parquet 文件,以
我目前有这样的功能,可以将任何输入数字四舍五入到最接近的模糊整数值: $(function(){ $('#my_value').blur(function() { $(this).va
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求提供代码的问题必须表现出对所解决问题的最低限度的了解。包括尝试的解决方案、为什么它们不起作用以及预期结果
我对 SQL 还很陌生,我想知道我是否可以使用它来自动解决我数据库中的一个复杂问题。 也就是说,我每天都在跟踪条目。因此,我们关注的列是: YYYY MM DD XXX YYYY 是年,MM 是月,D
我正在开发一个非常简单的数据库,但我不知道数据透视表是否是一个很好的解决方案。如果我使用数据透视表,我需要添加无用的表只是为了增量。 让我们从头开始。 在用户注册期间,会创建一个新表 GROUP。在G
在 MySQL 中你可以做这样的事情 SELECT @n := @n + 1 n, first_name, last_name FROM table1, (SELECT
如果我正在使用一个类,我知道如何重载运算符 += class temp { public: int i; temp(){ i = 10; } int operator+=(in
我有两个文件:file1、file2。我想从 file2 中获取 file1 中不存在的行。 我读过 post这告诉我使用 grep 的 -v 标志来执行此操作(我阅读了 grep 的手册页,但仍然不
我看了很多类似的题,功能很简单,用于API的嵌套for循环,每分钟可以调用5次。所以我将一年数据的范围设置为 75。你们能帮我解决这个问题吗?提前致谢! 第一部分正在运行,输入列表中的邮政编码。 fo
所以我想计算每日返回/增量的一些时间序列数据,其中每日增量 = value_at_time(T)/value_at_time(T-1) import pandas as pd df=pd.DataFr
请帮我解决这个问题。该表达式之后的步骤是: //Expression offSpring1[m1++] = temp1; //Steps: 1.- increment m1 2.- assign te
我正在开发一个解决方案,在该解决方案中,我通过 webapp 不同类型的实体(例如中央数据库上的用户、组、部门信息)和 ldap 进行身份验证。但是最终用户将与来自远程位置(他的办公室、节点)的数据交
我有以下 Python 数据结构: data1 = [{'name': u'String 1'}, {'name': u'String 2'}] data2 = [{'name': u'String
如果 AtomicInteger 会发生什么?达到 Integer.MAX_VALUE 并递增? 值会回到零吗? 最佳答案 由于integer overflow,它会环绕, 到 Integer.MIN
我是 C 的初学者,我正在尝试在 While 循环中进行 0.00001 增量。例如,double t = 0.00001 并且我希望循环每次以 0.00001 的增量运行,第二次是 0.00002
我是一名优秀的程序员,十分优秀!