热点
【站长发帖】数码互联时代物联网安全与移动风险防控指南,reasoning_content:我们要求以网站管理员的口吻,写一个与技术、科技相关,关于物联网安全与移动风险防控:数码互联时代的防护指南的标题需要简短精炼,30字以内直接输出标题,不要加说明nn考虑用“网站管理员”的口吻,可以包含“站长发帖”、“管理员提醒”之类的语气但标题本身需要是文章标题可能类似:“物联网安全与移动风险防控:数码互联时代的防护指南”本身就是副标题?我们需要重新构思一个更简短的标题nn示例:“【站长发帖】物联网安全与移动风险防控指南”但字数可能超?要30字以内或者“数码互联时代的防护指南:物联网安全与移动风险防控”太长nn更精炼:“物联网安全与移动风险防控指南”正好?但缺少“数码互联时代”的修饰可以:“数码互联时代:物联网安全与移动风险防控” 字数:14个字?数一下:“数码互联时代:物联网安全与移动风险防控” 共15个汉字?实际:数码互联时代(5字)+冒号+物联网安全与移动风险防控(11字)=16字?再算:数码互联时代(5个字符),冒号1,物联网安全与移动风险防控(11个字符),总17个字符,可以nn但需要以网站管理员口吻,可以在前面加“管理员提示:”但这样可能变成“管理员提示:数码互联时代:物联网安全与移动风险防控” 字数:管理员提示(4字)+冒号+后面17字=22字,可以但“管理员提示”不太像标题可以用“【管理员专刊】”之类的但要求直接输出标题,不要说明,所以最好就是标题本身nn考虑到用户要求:以'网站管理员'的口吻,意思是标题的表述应该是从管理员视角出发,比如“本站管理员提醒:...”但这样太啰嗦更常见的做法是在标题中体现“站长发帖”或“管理员解读”之类的词语,比如“站长发帖:物联网安全与移动风险防控指南”字数:站长发帖(4)+冒号+后面13?实际“物联网安全与移动风险防控指南”12字?物联网安全与移动风险防控指南:物联网(3)+安全(2)+与(1)+移动(2)+风险(2)+防控(2)+指南(2)=14字?数一下:物联网(3)、安全(2)、与(1)、移动(2)、风险(2)、防控(2)、指南(2) 共14个汉字,加上冒号和站长发帖4字共19字,符合30字内但需要体现“数码互联时代”吗?原文有“数码互联时代的防护指南”,可以简化成“数码互联时代防护指南”但字数超?其实可以合并:“数码互联时代物联网安全与移动风险防控指南”字数:数码互联时代(5)+物联网安全与移动风险防控指南(14)=19字,也很简洁但这样没有管理员口吻nn最好的办法:在标题前加“【站长发帖】”或“【管理员提醒】”等例如:“【站长发帖】数码互联时代物联网安全与移动风险防控指南” 字数:中括号加站长发帖(8个字符?实际上【站长发帖】是5个汉字?【和】算标点,站长发帖4字,共6字符?准确:'【站长发帖】'共5个字符(左括号、站、长、发、帖、右括号?等等,【是1个字符,站1,长1,发1,帖1,】1,共6个字符)然后加空格?直接连接:“【站长发帖】数码互联时代物联网安全与移动风险防控指南” 总汉字数:6+5+14=25个字符?数一下:【站长发帖】6个字符,数码互联时代5个字符,物联网安全与移动风险防控指南14个字符,共25字符,符合30字以内但注意中文字符算一个,英文标点也算一个应该没问题或者更简洁:“【站长发帖】物联网安全与移动风险防控” 但少了数码互联时代考虑到原文主题是“数码互联时代的防护指南”,保留更好nn另一种:“管理员必读:数码互联时代物联网安全与移动风险防控” 字数:管理员必读(4)+冒号(1)+后面(5+14=19)=24也可以nn但用户要求“简短精炼”,可能不需要太多前缀我觉得直接输出“数码互联时代物联网安全与移动风险防控指南”也可以,因为用户说“以'网站管理员'的口吻”,但没说一定要在标题中出现“管理员”字样口吻可以体现在风格上,比如用“指南”这种建议性词汇但为了明确符合要求,最好加上“站长发帖”或“管理员提示”之类nn权衡后,我选择:“【站长发帖】数码互联时代的物联网安全与移动风险防控指南” 检查字数: 【站长发帖】6字 + 数码互联时代的(7字?数码互联时代是5字,加“的”1字共6字?注意:数码互联时代是5个汉字?数:数、码、互、联、时、代——6个?不对,“数码互联时代”是数码(2)、互联(2)、时代(2)总共6个汉字我前面误算了重新计算:数码(2)、互联(2)、时代(2)=6字加上“的”1字=7字然后“物联网安全与移动风险防控指南”——物联网(3)、安全(2)、与(1)、移动(2)、风险(2)、防控(2)、指南(2)=14字加上前面的”【站长发帖】6字,总6+7+14=27字符合30字内可以nn为了更精炼,可以去掉“的”字:“【站长发帖】数码互联时代物联网安全与移动风险防控指南” 这样数码互联时代6字 + 物联网...14字 + 前缀6字 = 26字很好nn但注意:原主题有“移动风险防控”,我写的是“物联网安全与移动风险防控”,其中“与”字是否必要?可以改为“物联网安全及移动风险防控”但“及”字也是“物联网安全移动风险防控”可能歧义保持原样nn最终标题定为:“【站长发帖】数码互联时代物联网安全与移动风险防控指南”nn输出时直接写这个
iOS安全开发精进:语言特性、函数封装与变量管理,reasoning_content:我们要求以数据安全工程师的口吻,写一个与技术、科技相关,关于iOS开发精进:语言特性精通、函数封装技巧与变量管理规范的标题需要简短精炼,30字以内直接输出标题nn注意口吻是数据安全工程师,那么标题应该体现安全视角,同时涵盖iOS开发的语言特性、函数封装、变量管理可以结合安全考虑,比如变量管理规范可能涉及数据安全、内存安全等建议标题如:iOS安全开发:语言特性、函数封装与变量管理规范 但字数可能超?计算:iOS安全开发:语言特性、函数封装与变量管理规范 共?中文字符+标点实际上“iOS安全开发:语言特性、函数封装与变量管理规范” 有18个汉字+2个冒号+2个逗号?不,冒号一个,逗号两个?实际是“iOS安全开发:语言特性、函数封装与变量管理规范” 汉字:iOS(3个英文字母算?通常标题中英文算一个字符?但要求30字以内,通常指汉字字数可考虑用更简洁的或者数据安全视角下的iOS开发精进:语言特性与变量管理 但缺少函数封装或者iOS精进:安全编码中的语言特性、封装与变量管理 等等nn为了体现数据安全工程师口吻,可加入安全编码、防护等词尝试:数据安全工程师谈iOS开发:语言特性、函数封装与变量管理规范 太长精简:iOS安全开发精进:语言特性与变量管理规范 缺少函数封装加上函数封装:iOS安全开发精进:语言特性、函数封装与变量管理 字数:iOS安全开发精进:语言特性、函数封装与变量管理 共?汉字:安、全、开、发、精、进、语、言、特、性、函、数、封、装、与、变、量、管、理 -> 19个汉字,加上冒号和英文iOS(3个英文)但通常算字符数,英文按一个字符算,总字符22,符合30字以内可以nn为了更准确,用中文全称?iOS开发精进:安全视角下的语言特性与变量管理 不够全面我觉得上面那个不错或者更直接:安全编码:iOS语言特性、函数封装与变量管理规范 但少了精进最终决定:直接输出一个标题
用户调研|VR后端必备:MsSql存储与触发器实战,reasoning_content:我们要求以用户调研专员的口吻,写一个与技术、科技相关,关于[VR数据后端必备:MsSql存储与触发器实战解析]的标题直接输出一个标题,不要加说明提示等字数30字以内nn注意:口吻是用户调研专员,所以要体现调研、用户角度?还是说只是模拟这个角色的口吻?实际上标题需要简洁,可能偏向于技术内容用户调研专员通常是了解用户需求、做调研的,所以标题可以强调用户侧或调研发现之类的但更直接的是,要求写一个标题,主题是VR数据后端必备的MsSql存储与触发器实战解析我们直接写一个标题nn例如:VR后端调研:MsSql存储与触发器实战解析 但字数有点多,且可能不够精炼或者:用户调研|VR后端必备:MsSql存储与触发器实战 但需要控制在30字内我们数一下:用户调研|VR后端必备:MsSql存储与触发器实战 共22字(包括符号)符合nn或者更简洁:VR数据后端必备:MsSql存储与触发器实战解析 但没说用户调研专员口吻可以在前面加调研发现:之类的但直接输出标题,不解释nn考虑用户调研专员可能是在做用户调研后得出的结论,所以标题可以带有调研字样例如:调研报告:VR后端MsSql存储与触发器实战 约16字或者:VR数据后端实战:MsSql存储与触发器(用户调研版) 但有点长nn最终我选择:用户调研|VR后端必备:MsSql存储与触发器实战 共21个字(包括标点),且符合要求
网站管理员必备:政策编程核心之语言、函数与变量管理技巧,reasoning_content:我们要求以网站管理员的口吻,写一个与技术、科技相关,关于[政策编程核心:语言选择、函数构建与变量管理技巧]的标题直接输出一个标题,不要加说明提示等信息,简短精炼,字数控制在30字以内nn注意:题目中给出的内容是政策编程核心:语言选择、函数构建与变量管理技巧,这个应该是主题作为网站管理员的口吻,可能要用网站管理员的视角,比如作为网站管理员,你需要了解...,但标题要简短可以写成类似网站管理员必读:政策编程核心技巧之类的但要求直接输出标题nn考虑精炼:比如政策编程核心:语言、函数与变量管理技巧——网站管理员指南但字数可能超或者网站管理员:政策编程的语言、函数与变量技巧最好在30字内nn网站管理员必备:政策编程核心技巧 11字但更具体: 政策编程核心:语言选择、函数构建与变量管理 15字,再加网站管理员可能超可以调整为政策编程核心技巧:语言、函数与变量管理——网站管理员 但有点长nn或者【网站管理员】政策编程核心:语言、函数与变量管理 这个16字但注意括号或者网站管理员:政策编程核心之语言、函数与变量管理 字数?数一下:网站管理员:政策编程核心之语言、函数与变量管理 = 9+1+8+1+2+1+1+2+1+1? 直接数:网站管理员(4) :(1)政策编程核心(6)之(1)语言(2)、(1)函数(2)与(1)变量管理(4) = 4+1+6+1+2+1+2+1+4=22字OK,22字但标点算不算?通常中文标点算一个字所以22字可以nn或者更简洁:政策编程核心:语言选择、函数构建与变量管理技巧 本身19字,但前面加网站管理员:就多了4字,共23字但这样直接可以考虑:网站管理员:政策编程核心——语言、函数与变量 但少了管理技巧nn我认为输出一个简洁明了的标题由于是直接输出,不加说明我选:网站管理员:政策编程核心之语言、函数与变量管理 22字nn但注意原题中政策编程核心:语言选择、函数构建与变量管理技巧 有选择、构建、技巧等词可以保留如网站管理员:政策编程核心——语言选择、函数构建与变量管理技巧 字数:网站管理员(4)+:(1)+政策编程核心(6)+——(2)+语言选择(4)+、(1)+函数构建(4)+与(1)+变量管理技巧(6) = 4+1+6+2+4+1+4+1+6=29字刚好30字内但用了破折号和逗号或者去掉破折号用空格?但中文标题常用破折号可以接受nn考虑更短:政策编程核心:语言选择、函数构建与变量管理技巧(网站管理员) 这个字数:政策编程核心6+:1+语言选择4+、1+函数构建4+与1+变量管理技巧6+(1+网站管理员4+)1 = 6+1+4+1+4+1+6+1+4+1=29字也可以nn我选择第二种:政策编程核心:语言选择、函数构建与变量管理技巧(网站管理员) 29字nn但题目要求以'网站管理员'的口吻,所以最好网站管理员出现在前面比如网站管理员必看:政策编程核心语言、函数与变量管理技巧 数一下:网站管理员(4)必看(2):(1)政策编程核心(6)语言(2)、(1)函数(2)与(1)变量管理技巧(6) = 4+2+1+6+2+1+2+1+6=25字OKnn更简洁:网站管理员必备:政策编程核心语言、函数与变量技巧 24字nn我决定使用:网站管理员必备:政策编程核心之语言、函数与变量管理技巧 字数:网站管理员(4)必备(2):(1)政策编程核心(6)之(1)语言(2)、(1)函数(2)与(1)变量管理技巧(6) = 4+2+1+6+1+2+1+2+1+6=26字很好nn注意:题目中政策编程核心可能是个专有名词,不要改动所以这个标题保留了政策编程核心nn最终输出
PHP模块化产品设计:灵活配置,效率飙升,reasoning_content:我们要求以性能优化师的口吻,写一个与“技术、科技”相关,关于[PHP赋能运营中心:模块化产品设计,灵活配置提升效率]的标题直接输出一个标题,不要加说明提示等信息简短精炼,字数控制在30字以内nn需要体现性能优化师的口吻,可能语气专业、直接、强调效率、优化主题是PHP赋能运营中心,模块化产品设计,灵活配置提升效率nn可能的PHP模块化设计:灵活配置,运营效率飙升或者:PHP赋能运营:模块化配置,性能优化新高度但需要控制30字内nn尝试:PHP模块化产品设计,灵活配置提升运营效率但字数可能超?数一下:PHP模块化产品设计,灵活配置提升运营效率共17字可以nn但要以性能优化师口吻,可以更直接:PHP模块化设计:灵活配置,运营效率翻倍或者:PHP赋能运营:模块化配置,性能优化利器nn最好包含“性能优化师”的身份感,但标题中不一定直接出现“性能优化师”,而是语气专业比如:从性能优化看PHP模块化:灵活配置提升运营效率但字数可能多nn简单:PHP模块化设计:灵活配置,运营效率优化14字nn或者:PHP赋能运营中心:模块化设计,灵活配置提效13字nn考虑到要求是“与‘技术、科技’相关”,标题可以带上技术感最终输出一个标题我选择:PHP模块化产品设计:灵活配置,效率飙升共13字
17 9 月 2026, 周四

本篇内容介绍了“MySQL死锁分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
 
RC 隔离级别很少出GAP我已经知道的
 
继承和分裂会出LOCK_GAP这是代码写死的
purge线程可能触发
页的分裂融合可能触发
内部回滚可能触发
唯一性检查会出LOCK_ORDINARY[next_key_lock]
一、构造死锁
RC RR级别通用
 
死锁表结构和数据
drop table testunj1 ;
create table testunj1 (id1 int primary key,id2 int unique key,name varchar(20));
insert into testunj1 values(1,1,'gaopeng'),(10,10,'gaopeng'),(20,20,'gaopeng');
mysql> select * from testunj1;
+-----+------+---------+| id1 | id2  | name    |+-----+------+---------+|   1 |    1 | gaopeng ||  10 |   10 | gaopeng ||  20 |   20 | gaopeng |+-----+------+---------+3 rows in set (0.01 sec)
死锁构造流程
T1 T2 T3
begin;insert into testunj1 values(17,17,'gaopeng'); insert into testunj1 values(15,15,'gaopeng');
 
 
begin; insert into testunj1 values(14,15,'gaopeng');堵塞
 
 
begin; insert into testunj1 values(16,17,'gaopeng');堵塞
rollback; 成功 死锁
死锁记录
------------------------
LATEST DETECTED DEADLOCK
------------------------2017-08-29 05:03:47 0x7f2fdc6f0700*** (1) TRANSACTION:
TRANSACTION 7261233, ACTIVE 12 sec inserting
mysql tables in use 1, locked 1LOCK WAIT 4 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1MySQL thread id 3, OS thread handle 139843538720512, query id 583 localhost root update
insert into testunj1 values(14,15,'gaopeng')
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 797 page no 4 n bits 72 index id2 of table `test`.`testunj1` trx id 7261233 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000014; asc     ;; 1: len 4; hex 80000014; asc     ;;
*** (2) TRANSACTION:
TRANSACTION 7261234, ACTIVE 5 sec inserting
mysql tables in use 1, locked 14 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1MySQL thread id 4, OS thread handle 139843538454272, query id 585 localhost root update
insert into testunj1 values(16,17,'gaopeng')
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 797 page no 4 n bits 72 index id2 of table `test`.`testunj1` trx id 7261234 lock mode S locks gap before rec
Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000014; asc     ;; 1: len 4; hex 80000014; asc     ;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 797 page no 4 n bits 72 index id2 of table `test`.`testunj1` trx id 7261234 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000014; asc     ;; 1: len 4; hex 80000014; asc     ;;
*** WE ROLL BACK TRANSACTION (2)
二、分析
这个死锁实际上涉及到锁的继承和分裂我们分析如下两个事物堵塞的案例和加锁步骤,主要弄明白gap lock怎么来的。
 
 set global innodb_lock_wait_timeout=200000;
 set global innodb_show_verbose_locks=1;
 set global transaction_isolation =1;
 
重新登陆会话建立表和插入数据如下:
drop table testunj1 ;create table testunj1 (id1 int primary key,id2 int unique key,name varchar(20));insert into testunj1 values(1,1,'gaopeng'),(10,10,'gaopeng'),(20,20,'gaopeng');
 
如果有debug环境gdb断点: lock_rec_set_nth_bit
步骤如下:
 
T1 T2
阶段1
BEGIN;insert into testunj1 values(17,17,'gaopeng');
 
BEGIN;insert into testunj1 values(16,17,'gaopeng'); 堵塞
阶段2
ROLLBACK;
我们只用2个事物来分析流程,实际上流程知道了原因也就知道了。
 
- 阶段1 T1不提交T2堵塞
前奏
T1的插入不上任何锁,因为插入如果下一条记录没有锁,因此是隐含锁。分析从T2
insert into testunj1 values(16,17,'gaopeng'); 堵塞开始
第一步 T2执行 insert into testunj1 values(16,17,'gaopeng'); 步骤1
T2帮助T1隐士锁转换 上LOCK_X,这里通过函数lock_rec_convert_impl_to_expl 进行转换。
 
栈帧如下:
 
(gdb) bt#0  lock_rec_set_nth_bit (lock=0x3054068, i=5) at /root/softm/percona-server-5.7.22-22/storage/innobase/include/lock0priv.ic:91#1  0x0000000001a3f0cf in RecLock::lock_alloc (trx=0x7ffff10c95a0, index=0x7fffa89e3410, mode=1059, rec_id=..., size=9)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/lock/lock0lock.cc:1484#2  0x0000000001a3f435 in RecLock::create (this=0x7ffff0d59d20, trx=0x7ffff10c95a0, owns_trx_mutex=false, add_to_hash=true, prdt=0x0)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/lock/lock0lock.cc:1537#3  0x0000000001a40152 in lock_rec_add_to_queue (type_mode=1059, block=0x7fffea699ba0, heap_no=5, index=0x7fffa89e3410, trx=0x7ffff10c95a0,
    caller_owns_trx_mutex=false) at /root/softm/percona-server-5.7.22-22/storage/innobase/lock/lock0lock.cc:1853#4  0x0000000001a49cee in lock_rec_convert_impl_to_expl_for_trx (block=0x7fffea699ba0, rec=0x7fffeae680a8 "\200", index=0x7fffa89e3410, offsets=0x7fff9c02ef90,
    trx=0x7ffff10c95a0, heap_no=5) at /root/softm/percona-server-5.7.22-22/storage/innobase/lock/lock0lock.cc:6180#5  0x0000000001a4a124 in lock_rec_convert_impl_to_expl (block=0x7fffea699ba0, rec=0x7fffeae680a8 "\200", index=0x7fffa89e3410, offsets=0x7fff9c02ef90)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/lock/lock0lock.cc:6242#6  0x0000000001a4a9f6 in lock_sec_rec_read_check_and_lock (flags=0, block=0x7fffea699ba0, rec=0x7fffeae680a8 "\200", index=0x7fffa89e3410, offsets=0x7fff9c02ef90,
    mode=LOCK_S, gap_mode=0, thr=0x7fff9c035c18) at /root/softm/percona-server-5.7.22-22/storage/innobase/lock/lock0lock.cc:6446#7  0x0000000001aeff23 in row_ins_set_shared_rec_lock (type=0, block=0x7fffea699ba0, rec=0x7fffeae680a8 "\200", index=0x7fffa89e3410, offsets=0x7fff9c02ef90,
    thr=0x7fff9c035c18) at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0ins.cc:1483#8  0x0000000001af108d in row_ins_scan_sec_index_for_duplicate (flags=0, index=0x7fffa89e3410, entry=0x7fff9c01aa70, thr=0x7fff9c035c18, s_latch=false,
    mtr=0x7ffff0d5aec0, offsets_heap=0x7fff9c02ef08) at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0ins.cc:2115#9  0x0000000001af3440 in row_ins_sec_index_entry_low (flags=0, mode=2, index=0x7fffa89e3410, offsets_heap=0x7fff9c02ef08, heap=0x7fff9c00e918, entry=0x7fff9c01aa70,
    trx_id=0, thr=0x7fff9c035c18, dup_chk_only=false) at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0ins.cc:3034#10 0x0000000001af451d in row_ins_sec_index_entry (index=0x7fffa89e3410, entry=0x7fff9c01aa70, thr=0x7fff9c035c18, dup_chk_only=false)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0ins.cc:3421#11 0x0000000001af46d1 in row_ins_index_entry (index=0x7fffa89e3410, entry=0x7fff9c01aa70, thr=0x7fff9c035c18)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0ins.cc:3470#12 0x0000000001af4bf1 in row_ins_index_entry_step (node=0x7fff9c035978, thr=0x7fff9c035c18)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0ins.cc:3618#13 0x0000000001af4f67 in row_ins (node=0x7fff9c035978, thr=0x7fff9c035c18) at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0ins.cc:3760#14 0x0000000001af5564 in row_ins_step (thr=0x7fff9c035c18) at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0ins.cc:3945#15 0x0000000001b14775 in row_insert_for_mysql_using_ins_graph (mysql_rec=0x7fff9c034b10 "\374\020", prebuilt=0x7fff9c0353a0)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0mysql.cc:2283#16 0x0000000001b14c7d in row_insert_for_mysql (mysql_rec=0x7fff9c034b10 "\374\020", prebuilt=0x7fff9c0353a0)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0mysql.cc:2406#17 0x00000000019b87e5 in ha_innobase::write_row (this=0x7fff9c0345d0, record=0x7fff9c034b10 "\374\020")
    at /root/softm/percona-server-5.7.22-22/storage/innobase/handler/ha_innodb.cc:8344#18 0x0000000000f7d74d in handler::ha_write_row (this=0x7fff9c0345d0, buf=0x7fff9c034b10 "\374\020") at /root/softm/percona-server-5.7.22-22/sql/handler.cc:8466#19 0x00000000017ed7e9 in write_record (thd=0x7fff9c000b70, table=0x7fff9c033bd0, info=0x7ffff0d5ca00, update=0x7ffff0d5c980)
    at /root/softm/percona-server-5.7.22-22/sql/sql_insert.cc:1881#20 0x00000000017ea893 in Sql_cmd_insert::mysql_insert (this=0x7fff9c006e90, thd=0x7fff9c000b70, table_list=0x7fff9c0068f8)
    at /root/softm/percona-server-5.7.22-22/sql/sql_insert.cc:773#21 0x00000000017f141d in Sql_cmd_insert::execute (this=0x7fff9c006e90, thd=0x7fff9c000b70) at /root/softm/percona-server-5.7.22-22/sql/sql_insert.cc:3121#22 0x00000000015b9a83 in mysql_execute_command (thd=0x7fff9c000b70, first_level=true) at /root/softm/percona-server-5.7.22-22/sql/sql_parse.cc:3746#23 0x00000000015c030e in mysql_parse (thd=0x7fff9c000b70, parser_state=0x7ffff0d5e600) at /root/softm/percona-server-5.7.22-22/sql/sql_parse.cc:5901#24 0x00000000015b3ea2 in dispatch_command (thd=0x7fff9c000b70, com_data=0x7ffff0d5ed70, command=COM_QUERY)
    at /root/softm/percona-server-5.7.22-22/sql/sql_parse.cc:1490#25 0x00000000015b2c2f in do_command (thd=0x7fff9c000b70) at /root/softm/percona-server-5.7.22-22/sql/sql_parse.cc:1021#26 0x00000000016fb8a8 in handle_connection (arg=0x38e2880) at /root/softm/percona-server-5.7.22-22/sql/conn_handler/connection_handler_per_thread.cc:312#27 0x00000000019320be in pfs_spawn_thread (arg=0x3c64160) at /root/softm/percona-server-5.7.22-22/storage/perfschema/pfs.cc:2190---Type <return> to continue, or q <return> to quit---#28 0x00007ffff79c3aa1 in start_thread () from /lib64/libpthread.so.0#29 0x00007ffff6516bcd in clone () from /lib64/libc.so.6
第二步 insert into testunj1 values(16,17,'gaopeng'); 步骤2
需要做唯一性检查不通过上LOCK_ORDINARY[next_key_lock]等待,唯一检查会涉及到主键和唯一键,如果主键检查通过则会插入数据,然后检查二级唯一索引,如果唯一索引冲突,则主键插入的数据需要回滚。这里是因为每个索引是单独调用row_ins_index_entry_step上层函数进行单独插入的。
  
---TRANSACTION 19508, ACTIVE 143 sec inserting
mysql tables in use 1, locked 1LOCK WAIT 2 lock struct(s), heap size 1160, 1 row lock(s), undo log entries 1MySQL thread id 4, OS thread handle 140737233942272, query id 684 localhost root update
insert into testunj1 values(16,17,'gaopeng')
------- TRX HAS BEEN WAITING 0 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 91 page no 4 n bits 72 index id2 of table ,addr is 0x3054068 `test`.`testunj1` trx id 19508 lock mode S(LOCK_S) locks gap and rec(LOCK_ORDINARY[next_key_lock]) waiting(LOCK_WAIT)
Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000011; asc     ;; 1: len 4; hex 80000011; asc     ;;
---TRANSACTION 19507, ACTIVE 148 sec2 lock struct(s), heap size 1160, 1 row lock(s), undo log entries 1MySQL thread id 3, OS thread handle 140737234208512, query id 682 localhost root
TABLE LOCK table `test`.`testunj1` trx id 19507 lock mode IX
RECORD LOCKS space id 91 page no 4 n bits 72 index id2 of table ,addr is 0x3056b48 `test`.`testunj1` trx id 19507 lock_mode X(LOCK_X) locks rec but not gap(LOCK_REC_NOT_GAP)
Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000011; asc     ;; 1: len 4; hex 80000011; asc     ;;
- 阶段2 做ROLLBACK
第三步 T1帮助T2做锁继承
从事物的指针0x7ffff10ca5f0可以看出是T2,如果有多个事物LOCK_GAP是兼容所以都可以继承完成,LOCK_GAP的存在只是为了LOCK_INTENTION,就是为了防止幻读。
如果做了GDB可以看到这里继承的锁:
(gdb) p lock->type_mode$1 = 546
546 = 512+2+32= LOCK_GAP+LOCK_S+LOCK_REC 这个锁继承给了 heap 4 也就是记录 20(heir_heap_no=4, heap_no=5)
 
这里将LOCK_S|LOCK_GAP 继承到heap_no 4 上也就是 记录记录20上。
 
栈帧如下:
 
2018-10-11T08:15:44.292686Z 4 [Note] InnoDB: Trx(19999) is blocked!!!!!
[Switching to Thread 0x7ffff0da0700 (LWP 9278)]
Breakpoint 2, lock_rec_set_nth_bit (lock=0x3058230, i=4) at /root/softm/percona-server-5.7.22-22/storage/innobase/include/lock0priv.ic:9191              ut_ad(lock);
(gdb) bt#0  lock_rec_set_nth_bit (lock=0x3058230, i=4) at /root/softm/percona-server-5.7.22-22/storage/innobase/include/lock0priv.ic:91#1  0x0000000001a3f0cf in RecLock::lock_alloc (trx=0x7ffff10ca5f0, index=0x7fffa89e3410, mode=546, rec_id=..., size=9)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/lock/lock0lock.cc:1484#2  0x0000000001a3f435 in RecLock::create (this=0x7ffff0d9ada0, trx=0x7ffff10ca5f0, owns_trx_mutex=false, add_to_hash=true, prdt=0x0)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/lock/lock0lock.cc:1537#3  0x0000000001a40152 in lock_rec_add_to_queue (type_mode=546, block=0x7fffea699ba0, heap_no=4, index=0x7fffa89e3410, trx=0x7ffff10ca5f0, caller_owns_trx_mutex=false)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/lock/lock0lock.cc:1853#4  0x0000000001a4299b in lock_rec_inherit_to_gap (heir_block=0x7fffea699ba0, block=0x7fffea699ba0, heir_heap_no=4, heap_no=5)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/lock/lock0lock.cc:2787#5  0x0000000001a4475e in lock_update_delete (block=0x7fffea699ba0, rec=0x7fffeae680a8 "\200")
    at /root/softm/percona-server-5.7.22-22/storage/innobase/lock/lock0lock.cc:3692#6  0x0000000001c26418 in btr_cur_optimistic_delete_func (cursor=0x7ffff0d9b7c0, flags=0, mtr=0x7ffff0d9b2b0)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/btr/btr0cur.cc:5200#7  0x0000000001d54fe7 in row_undo_ins_remove_sec_low (mode=16386, index=0x7fffa89e3410, entry=0x7fffa89cde10, thr=0x7fffa89a23e8)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0uins.cc:260#8  0x0000000001d55101 in row_undo_ins_remove_sec (index=0x7fffa89e3410, entry=0x7fffa89cde10, thr=0x7fffa89a23e8)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0uins.cc:295#9  0x0000000001d555a8 in row_undo_ins_remove_sec_rec (node=0x7fffa89a25c0, thr=0x7fffa89a23e8)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0uins.cc:429#10 0x0000000001d55810 in row_undo_ins (node=0x7fffa89a25c0, thr=0x7fffa89a23e8) at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0uins.cc:483#11 0x0000000001b69c80 in row_undo (node=0x7fffa89a25c0, thr=0x7fffa89a23e8) at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0undo.cc:324#12 0x0000000001b69dcd in row_undo_step (thr=0x7fffa89a23e8) at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0undo.cc:370#13 0x0000000001abfea4 in que_thr_step (thr=0x7fffa89a23e8) at /root/softm/percona-server-5.7.22-22/storage/innobase/que/que0que.cc:1061#14 0x0000000001ac00ae in que_run_threads_low (thr=0x7fffa89a23e8) at /root/softm/percona-server-5.7.22-22/storage/innobase/que/que0que.cc:1125#15 0x0000000001ac0254 in que_run_threads (thr=0x7fffa89a23e8) at /root/softm/percona-server-5.7.22-22/storage/innobase/que/que0que.cc:1165#16 0x0000000001bcf4dc in trx_rollback_to_savepoint_low (trx=0x7ffff10c95a0, savept=0x0) at /root/softm/percona-server-5.7.22-22/storage/innobase/trx/trx0roll.cc:118#17 0x0000000001bcf714 in trx_rollback_for_mysql_low (trx=0x7ffff10c95a0) at /root/softm/percona-server-5.7.22-22/storage/innobase/trx/trx0roll.cc:180#18 0x0000000001bcf9b2 in trx_rollback_low (trx=0x7ffff10c95a0) at /root/softm/percona-server-5.7.22-22/storage/innobase/trx/trx0roll.cc:212#19 0x0000000001bcfceb in trx_rollback_for_mysql (trx=0x7ffff10c95a0) at /root/softm/percona-server-5.7.22-22/storage/innobase/trx/trx0roll.cc:289#20 0x00000000019b1c6c in innobase_rollback (hton=0x2edf1f0, thd=0x7fffa8012940, rollback_trx=true)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/handler/ha_innodb.cc:5126#21 0x0000000000f6db24 in ha_rollback_low (thd=0x7fffa8012940, all=true) at /root/softm/percona-server-5.7.22-22/sql/handler.cc:2007#22 0x00000000018671d9 in MYSQL_BIN_LOG::rollback (this=0x2e39a40, thd=0x7fffa8012940, all=true) at /root/softm/percona-server-5.7.22-22/sql/binlog.cc:2447#23 0x0000000000f6ddba in ha_rollback_trans (thd=0x7fffa8012940, all=true) at /root/softm/percona-server-5.7.22-22/sql/handler.cc:2094#24 0x00000000016ca4d5 in trans_rollback (thd=0x7fffa8012940) at /root/softm/percona-server-5.7.22-22/sql/transaction.cc:356#25 0x00000000015bc90a in mysql_execute_command (thd=0x7fffa8012940, first_level=true) at /root/softm/percona-server-5.7.22-22/sql/sql_parse.cc:4556#26 0x00000000015c030e in mysql_parse (thd=0x7fffa8012940, parser_state=0x7ffff0d9f600) at /root/softm/percona-server-5.7.22-22/sql/sql_parse.cc:5901#27 0x00000000015b3ea2 in dispatch_command (thd=0x7fffa8012940, com_data=0x7ffff0d9fd70, command=COM_QUERY)
    at /root/softm/percona-server-5.7.22-22/sql/sql_parse.cc:1490#28 0x00000000015b2c2f in do_command (thd=0x7fffa8012940) at /root/softm/percona-server-5.7.22-22/sql/sql_parse.cc:1021#29 0x00000000016fb8a8 in handle_connection (arg=0x3c52dd0) at /root/softm/percona-server-5.7.22-22/sql/conn_handler/connection_handler_per_thread.cc:312#30 0x00000000019320be in pfs_spawn_thread (arg=0x3c64160) at /root/softm/percona-server-5.7.22-22/storage/perfschema/pfs.cc:2190#31 0x00007ffff79c3aa1 in start_thread () from /lib64/libpthread.so.0#32 0x00007ffff6516bcd in clone () from /lib64/libc.so.6
T2自己做分裂了
分裂(heir_heap_no=5, heap_no=4) 可以看到这里将 记录20的type_mode=546分裂给记录17 也就是512+2+32=LOCK_GAP+LOCK_S+LOCK_REC。
栈帧如下:
 
[Switching to Thread 0x7ffff0d5f700 (LWP 9548)]
Breakpoint 2, lock_rec_set_nth_bit (lock=0x3058230, i=5) at /root/softm/percona-server-5.7.22-22/storage/innobase/include/lock0priv.ic:9191              ut_ad(lock);
(gdb) bt#0  lock_rec_set_nth_bit (lock=0x3058230, i=5) at /root/softm/percona-server-5.7.22-22/storage/innobase/include/lock0priv.ic:91#1  0x0000000001a400fa in lock_rec_add_to_queue (type_mode=546, block=0x7fffea699ba0, heap_no=5, index=0x7fffa89e3410, trx=0x7ffff10ca5f0, caller_owns_trx_mutex=false)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/lock/lock0lock.cc:1845#2  0x0000000001a42acf in lock_rec_inherit_to_gap_if_gap_lock (block=0x7fffea699ba0, heir_heap_no=5, heap_no=4)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/lock/lock0lock.cc:2829#3  0x0000000001a44643 in lock_update_insert (block=0x7fffea699ba0, rec=0x7fffeae680a8 "\200")
    at /root/softm/percona-server-5.7.22-22/storage/innobase/lock/lock0lock.cc:3659#4  0x0000000001c219b4 in btr_cur_optimistic_insert (flags=0, cursor=0x7ffff0d5b6f0, offsets=0x7ffff0d5b7c8, heap=0x7ffff0d5a6e0, entry=0x7fff9c01aa70,
    rec=0x7ffff0d5b7c0, big_rec=0x7ffff0d5b7b8, n_ext=0, thr=0x7fff9c035c18, mtr=0x7ffff0d5aec0)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/btr/btr0cur.cc:3346#5  0x0000000001af3a0d in row_ins_sec_index_entry_low (flags=0, mode=2, index=0x7fffa89e3410, offsets_heap=0x7fff9c00e918, heap=0x7fff9c02ef08, entry=0x7fff9c01aa70,
    trx_id=0, thr=0x7fff9c035c18, dup_chk_only=false) at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0ins.cc:3166#6  0x0000000001af451d in row_ins_sec_index_entry (index=0x7fffa89e3410, entry=0x7fff9c01aa70, thr=0x7fff9c035c18, dup_chk_only=false)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0ins.cc:3421#7  0x0000000001af46d1 in row_ins_index_entry (index=0x7fffa89e3410, entry=0x7fff9c01aa70, thr=0x7fff9c035c18)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0ins.cc:3470#8  0x0000000001af4bf1 in row_ins_index_entry_step (node=0x7fff9c035978, thr=0x7fff9c035c18)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0ins.cc:3618#9  0x0000000001af4f67 in row_ins (node=0x7fff9c035978, thr=0x7fff9c035c18) at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0ins.cc:3760#10 0x0000000001af5564 in row_ins_step (thr=0x7fff9c035c18) at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0ins.cc:3945#11 0x0000000001b14775 in row_insert_for_mysql_using_ins_graph (mysql_rec=0x7fff9c034b10 "\374\020", prebuilt=0x7fff9c0353a0)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0mysql.cc:2283#12 0x0000000001b14c7d in row_insert_for_mysql (mysql_rec=0x7fff9c034b10 "\374\020", prebuilt=0x7fff9c0353a0)
    at /root/softm/percona-server-5.7.22-22/storage/innobase/row/row0mysql.cc:2406#13 0x00000000019b87e5 in ha_innobase::write_row (this=0x7fff9c0345d0, record=0x7fff9c034b10 "\374\020")
    at /root/softm/percona-server-5.7.22-22/storage/innobase/handler/ha_innodb.cc:8344#14 0x0000000000f7d74d in handler::ha_write_row (this=0x7fff9c0345d0, buf=0x7fff9c034b10 "\374\020") at /root/softm/percona-server-5.7.22-22/sql/handler.cc:8466#15 0x00000000017ed7e9 in write_record (thd=0x7fff9c000b70, table=0x7fff9c033bd0, info=0x7ffff0d5ca00, update=0x7ffff0d5c980)
    at /root/softm/percona-server-5.7.22-22/sql/sql_insert.cc:1881#16 0x00000000017ea893 in Sql_cmd_insert::mysql_insert (this=0x7fff9c006e90, thd=0x7fff9c000b70, table_list=0x7fff9c0068f8)
    at /root/softm/percona-server-5.7.22-22/sql/sql_insert.cc:773#17 0x00000000017f141d in Sql_cmd_insert::execute (this=0x7fff9c006e90, thd=0x7fff9c000b70) at /root/softm/percona-server-5.7.22-22/sql/sql_insert.cc:3121#18 0x00000000015b9a83 in mysql_execute_command (thd=0x7fff9c000b70, first_level=true) at /root/softm/percona-server-5.7.22-22/sql/sql_parse.cc:3746#19 0x00000000015c030e in mysql_parse (thd=0x7fff9c000b70, parser_state=0x7ffff0d5e600) at /root/softm/percona-server-5.7.22-22/sql/sql_parse.cc:5901#20 0x00000000015b3ea2 in dispatch_command (thd=0x7fff9c000b70, com_data=0x7ffff0d5ed70, command=COM_QUERY)
    at /root/softm/percona-server-5.7.22-22/sql/sql_parse.cc:1490#21 0x00000000015b2c2f in do_command (thd=0x7fff9c000b70) at /root/softm/percona-server-5.7.22-22/sql/sql_parse.cc:1021#22 0x00000000016fb8a8 in handle_connection (arg=0x38e2880) at /root/softm/percona-server-5.7.22-22/sql/conn_handler/connection_handler_per_thread.cc:312#23 0x00000000019320be in pfs_spawn_thread (arg=0x3c64160) at /root/softm/percona-server-5.7.22-22/storage/perfschema/pfs.cc:2190#24 0x00007ffff79c3aa1 in start_thread () from /lib64/libpthread.so.0#25 0x00007ffff6516bcd in clone () from /lib64/libc.so.6(gdb)
最终形成如下的锁模式,因为记录 11,11已经不存在了因此
 
addr is 0x30580e8 `test`.`testunj1` trx id 19999 lock mode S(LOCK_S) locks gap and rec(LOCK_ORDINARY[next_key_lock])
下不会有任何记录
 
---TRANSACTION 19999, ACTIVE 972 sec3 lock struct(s), heap size 1160, 2 row lock(s), undo log entries 1MySQL thread id 4, OS thread handle 140737233942272, query id 687 localhost root starting
show engine innodb status
TABLE LOCK table `test`.`testunj1` trx id 19999 lock mode IX
RECORD LOCKS space id 93 page no 4 n bits 72 index id2 of table ,addr is 0x30580e8 `test`.`testunj1` trx id 19999 lock mode S(LOCK_S) locks gap and rec(LOCK_ORDINARY[next_key_lock])
RECORD LOCKS space id 93 page no 4 n bits 72 index id2 of table ,addr is 0x3058230 `test`.`testunj1` trx id 19999 lock mode S(LOCK_S) locks gap before rec(LOCK_GAP)
Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000014; asc     ;; 1: len 4; hex 80000014; asc     ;;
Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000011; asc     ;; 1: len 4; hex 80000010; asc     ;;
可以看到 lock mode S(LOCK_S) locks gap before rec(LOCK_GAP) 已经出来了。
 
三、断点及一些补遗
lock_rec_has_to_wait 检测是否需要等待
RecLock::add_to_waitq 将LOCK_T结构加入到rec hash中(等待)
RecLock::lock_add 将LOCK_T结构加入到rec hash中
lock_rec_set_nth_bit 设置LOCK_T位图
row_ins_scan_sec_index_for_duplicate 二级唯一索引唯一性检查加锁函数
lock_rec_other_has_conflicting 判断冲突->lock_rec_has_to_wait 检测是否需要等待
lock_rec_inherit_to_gap LOCK继承函数
lock_rec_inherit_to_gap_if_gap_lock LOCK分裂函数
lock_rec_convert_impl_to_expl 隐含锁转换函数,比较复杂
1、即便是同一个block,不同事物(即便是同一个事物的不同锁模式)也需要新建一个LOCK_T结构,来表示一个锁,其以space id/page no为基础。其内存结构BITMAP会以位图的形式每一位代表一行数据是否上锁(0 or 1)2、innodb锁类型只有LOCK_REC和LOCK_TABLE两种及行锁和表锁,但是可以有多种模式组合。3、rec hash 通过space id 和 page no 构造 那么同一块的 都放到一个链表中,同时这个链表上的可能还有冲突而来的,所以每次获取的时候必然查看page no和space id 参考lock_rec_add_to_queue -> lock_rec_get_first_on_page函数。4、每次增加一个lock_t 结构都会加入到rec hash中,这也是所谓的等待队列,加入队列就是指加入rec hash中关于本space id和page no的队列,当然最后还需要 bitmap的确认才能在page中找到这个锁的位置。5、不同的事物对于同一行数据的上锁通常不共享一个lock_t,他们共同连接到rec hash的链表下面6、判断某行是否上锁 需要不断循环整个链表使用heap no定位到bitmap 来进行判断。参考lock_rec_other_has_conflicting ->lock_rec_get_first。7、对于某些标记为del flag还没有purge的记录,在某些情况下会加锁,但是会跳过判断,参考row_ins_scan_sec_index_for_duplicate ->row_ins_dupl_error_with_rec 函数。
row_ins_scan_sec_index_for_duplicate 片段:
 
        if (cmp == 0 && !index->allow_duplicates) { //记录相等并且是唯一索引 ,还需要判断唯一的字段是否能够对上,同时要确认不是del flag的记录
            if (row_ins_dupl_error_with_rec(rec, entry,
                            index, offsets)) { //这里会跳过 del flag的记录 不标记为 重复,IF逻辑不会停止,会继续到一行
                err = DB_DUPLICATE_KEY;
                thr_get_trx(thr)->error_info = index;
                ......                goto end_scan;
            }
        } else {
            ut_a(cmp < 0 || index->allow_duplicates);            goto end_scan;
        }
row_ins_dupl_error_with_rec 片段:
 
    if (matched_fields < n_unique) { //需要相同的字段 否则判断为FLASE
        return(FALSE);
    }    /* In a unique secondary index we allow equal key values if they
    contain SQL NULLs */
    if (!dict_index_is_clust(index) && !index->nulls_equal) {        for (i = 0; i < n_unique; i++) {            if (dfield_is_null(dtuple_get_nth_field(entry, i))) {                return(FALSE);
            }
        }
    }    return(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); //如果相同 但是是del flag的记录则同样放回FALSE

dawei

【声明】:毕节站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

您错过了