- 论坛徽章:
- 0
|
本帖最后由 justin033 于 2010-02-25 10:41 编辑
最近在研究innodb index的实现形式!
如下测试:
测试1:插入的字段记录没gap的并发情况
session一,id=2:
- root@localhost[test] 10:04:35>create table tbl_no_index(i int) engine=innodb;
- Query OK, 0 rows affected (0.05 sec)
- root@localhost[test] 10:05:19>insert into tbl_no_index values(1),(2),(3),(4);
- Query OK, 4 rows affected (0.00 sec)
- Records: 4 Duplicates: 0 Warnings: 0
- root@localhost[test] 10:07:07>set autocommit=off;
- Query OK, 0 rows affected (0.00 sec)
- root@localhost[test] 10:07:19>select * from tbl_no_index where i=1;
- +------+
- | i |
- +------+
- | 1 |
- +------+
- 1 row in set (0.00 sec)
- root@localhost[test] 10:07:23>select * from tbl_no_index where i=1[color=Red] for update;[/color]
- +------+
- | i |
- +------+
- | 1 |
- +------+
- 1 row in set (0.00 sec)
- root@localhost[test] 10:07:26>status
- --------------
- mysql Ver 14.14 Distrib 5.1.39, for Win32 (ia32)
- Connection id: 2
- SSL: Not in use
- Using delimiter: ;
- Server version: [color=Red]5.1.39-community-log MySQL Community Server (GPL)[/color]
- Protocol version: 10
- Connection: localhost via TCP/IP
- Client characterset: gbk
- Server characterset: gbk
- TCP port: 3306
- Uptime: 11 min 24 sec
复制代码 session 二,id=3:
- C:\>mysql -uroot -p
- Enter password: *
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 3
- Server version: 5.1.39-community-log MySQL Community Server (GPL)
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- root@localhost[(none)] 10:05:52>show processlist\G
- *************************** 1. row ***************************
- Id: 2
- User: root
- Host: localhost:1948
- db: test
- Command: Sleep
- Time: 13
- State:
- Info: NULL
- *************************** 2. row ***************************
- Id: 3
- User: root
- Host: localhost:1962
- db: NULL
- Command: Query
- Time: 0
- State: NULL
- Info: show processlist
- 2 rows in set (0.03 sec)
- root@localhost[(none)] 10:05:58>use test;
- Database changed
- root@localhost[test] 10:21:48>set @@autocommit=0;
- Query OK, 0 rows affected (0.00 sec)
- root@localhost[test] 10:22:06>select * from tbl_no_index where i=4 for update;
- [color=Red]ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction[/color]
- root@localhost[test] 10:23:00>
复制代码 按道理说,innodb是用index lock/record lock,只会锁定要查询的记录。为什么会把session二,id=3给锁定了,就像加了table lock。而在show engine innodb status下也是显示record lock的,如下:
- ------------
- TRANSACTIONS
- ------------
- Trx id counter 0 3854
- Purge done for trx's n:o < 0 3336 undo n:o < 0 0
- History list length 7
- LIST OF TRANSACTIONS FOR EACH SESSION:
- ---TRANSACTION 0 0, not started, OS thread id 1760
- MySQL thread id 4, query id 52 localhost 127.0.0.1 root
- show engine innodb status
- ---TRANSACTION 0 3853, ACTIVE 28 sec, OS thread id 3428 starting index read
- mysql tables in use 1, locked 1
- LOCK WAIT 2 lock struct(s), heap size 320, 1 row lock(s)
- MySQL thread id 3, query id 51 localhost 127.0.0.1 root Sending data
- select * from tbl_no_index where i=4 for update
- ------- TRX HAS BEEN WAITING 28 SEC FOR THIS LOCK TO BE GRANTED:
- [color=Red]RECORD LOCKS space id 0 page no 197 n bits 72 index `GEN_CLUST_INDEX` of table `test`.`tbl_no_index` trx id 0 3853 lock_mode X waiting[/color]
- Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
- 0: len 6; hex 000000000400; asc ;; 1: len 6; hex 000000000f01; asc ;; 2: len 7; hex 800000002d0110; asc - ;; 3: len 4; hex 80000001; asc ;;
- ------------------
- ---TRANSACTION 0 3849, ACTIVE 914 sec, OS thread id 2868
- 2 lock struct(s), heap size 320, 5 row lock(s)
- MySQL thread id 2, query id 45 localhost 127.0.0.1 root
- Trx read view will not see trx with id >= 0 3850, sees < 0 3850
复制代码 如下测试:
测试2:插入的字段记录有gap的并发情况
session一:
- root@localhost[test] 10:32:21>set autocommit=off;
- Query OK, 0 rows affected (0.00 sec)
- root@localhost[test] 11:29:19>select * from tbl_no_index;
- +------+
- | i |
- +------+
- | 1 |
- | 2 |
- | 7 |
- | 11 |
- | 12 |
- +------+
- 5 rows in set (0.00 sec)
- root@localhost[test] 11:29:33>select * from tbl_no_index where i=2 [color=Red]for update[/color];
- +------+
- | i |
- +------+
- | 2 |
- +------+
- 1 row in set (0.00 sec)
复制代码 session二:
- root@localhost[test] 11:29:51>set autocommit=0;
- Query OK, 0 rows affected (0.02 sec)
- root@localhost[test] 11:29:55>[color=Red]insert into tbl_no_index values(5);[/color]
- Query OK, 1 row affected (0.00 sec)
- root@localhost[test] 11:30:03>select * from tbl_no_index;
- +------+
- | i |
- +------+
- | 1 |
- | 2 |
- | 3 |
- | 5 |
- | 7 |
- | 11 |
- | 12 |
- +------+
- 7 rows in set (0.00 sec)
复制代码 从上面的测试来看,gap lock是record lock行锁的,也是文档上说的!但为什么测试一,感觉是加了table lock的锁。。。我还没找合理的解释了,也问了一些朋友了。目前还没理解清楚,帮忙哈,谢谢! |
|