日期:2014-05-16  浏览次数:21002 次

mysql锁释放时机(二)

?????? 上篇,跟踪了select在事务和非事务下的调用路径,本次跟踪insert下的执行路径。

?????? insert into test1(aa) values('hello world');

?????? 断点显示的堆栈

#0? lock_release_off_kernel (trx=0xb512ac68) at lock/lock0lock.c:3853
#1? 0xb5dca803 in trx_commit_off_kernel (trx=0xb512ac68) at trx/trx0trx.c:853
#2? 0xb5dcad19 in trx_commit_for_mysql (trx=0xb512ac68) at trx/trx0trx.c:1582
#3? 0xb5dd2838 in innobase_commit_low (trx=0x0) at handler/ha_innodb.cc:1878
#4? 0xb5dd5f42 in innobase_commit (hton=0x8f6c2e8, thd=0x982fec0, all=false)
??? at handler/ha_innodb.cc:2021
#5? 0x082e840a in ha_commit_one_phase (thd=0x982fec0, all=false)
??? at handler.cc:1231
#6? 0x082e897d in ha_commit_trans (thd=0x982fec0, all=false) at handler.cc:1199
#7? 0x0839277d in trans_commit_stmt (thd=0x982fec0) at transaction.cc:239
#8? 0x081ec38f in dispatch_command (command=COM_QUERY, thd=0x982fec0,
??? packet=<value optimized out>, packet_length=43) at sql_parse.cc:1429
#9? 0x081ecaec in do_command (thd=0x982fec0) at sql_parse.cc:731
#10 0x081dc327 in handle_one_connection (arg=0x982fec0) at sql_connect.cc:1146
#11 0x4dfe92db in start_thread (arg=0xb26f4790) at pthread_create.c:296
#12 0x006cf14e in clone () from /lib/libc.so.6

注意红色地方,trans_commit_stmt 为每个语句执行之后都会执行的。

?????? 在事务模式下

?????? start transaction;

?????? insert into test1(aa) values('hello world2'); --也是commit之后才出现断点

?????? commit;

?????? 断点显示之后的堆栈为:

#0? lock_release_off_kernel (trx=0xb512ac68) at lock/lock0lock.c:3853
#1? 0xb5dca803 in trx_commit_off_kernel (trx=0xb512ac68) at trx/trx0trx.c:853
#2? 0xb5dcad19 in trx_commit_for_mysql (trx=0xb512ac68) at trx/trx0trx.c:1582
#3? 0xb5dd2838 in innobase_commit_low (trx=0x0) at handler/ha_innodb.cc:1878
#4? 0xb5dd5f42 in innobase_commit (hton=0x8f6c2e8, thd=0x982fec0, all=true)
??? at handler/ha_innodb.cc:2021
#5? 0x082e840a in ha_commit_one_phase (thd=0x982fec0, all=true)
??? at handler.cc:1231
#6? 0x082e897d in ha_commit_trans (thd=0x982fec0, all=true) at handler.cc:1199
#7? 0x083925fc in trans_commit (thd=0x982fec0) at transaction.cc:136
#8? 0x081e7972 in mysql_execute_command (thd=0x982fec0) at sql_parse.cc:4130
#9? 0x081ea940 in mysql_parse (thd=0x982fec0, inBuf=0x96fb048 "commit",
??? length=6, found_semicolon=0xb26f3f14) at sql_parse.cc:5937
#10 0x081eb82c in dispatch_command (command=COM_QUERY, thd=0x982fec0,
??? packet=0x9826231 "commit", packet_length=6) at sql_parse.cc:1049
#11 0x081ecaec in do_command (thd=0x982fec0) at sql_parse.cc:731
#12 0x081dc327 in handle_one_connection (arg=0x982fec0) at sql_connect.cc:1146
#13 0x4dfe92db in start_thread (arg=0xb26f4790) at pthread_create.c:296
#14 0x006cf14e in clone () from /lib/libc.so.6

???二者提交事务的方式是不同的。

?? 对mysql的一些困惑,为什么在非事务方式下面,select和insert,二者的锁释放的时机也不一样?

一个在JOIN::exec下面的join_free下面直接释放,而insert则在trans_commit_stmt里面释放。统一在trans_commit_stmt释放锁不好吗?出现的调用路径过多,也不好理解,维护起来麻烦,难道又是所谓的为了效率牺牲可读性?