设为首页 加入收藏

TOP

Mysql中那些锁机制之MyISAM(一)
2015-11-21 02:07:40 来源: 作者: 【 】 浏览:3
Tags:Mysql 那些 机制 MyISAM

说到锁机制之前,先来看看Mysql的存储引擎,毕竟不同的引擎的锁机制也随着不同。

三类常见引擎:

?

MyIsam 不支持事务,不支持外键,所以访问速度快。锁机制是表锁,支持全文索引

?

InnoDB 支持事务、支持外键,所以对比MyISAM,InnoDB的处理效率差一些,并要占更多的磁盘空间保留数据和索引。锁机制是行锁,不支持全文索引

?

Memory数据是存放在内存中的,默认哈希索引,非常适合存储临时数据,服务器关闭后,数据会丢失掉。

?

如何选择存储引擎:

?

?

MyISAM:应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高。

?

InnoDB用于事务处理应用程序,支持外键,如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性。更新删除等频繁(InnoDB可以有效的降低由于删除和更新导致的锁定),对于数据准确性要求比较高的,此引擎适合。

?

Memory通常用于更新不太频繁的小表,用以快速得到访问结果。


?

Mysql中的锁

?

?

如果熟悉多线程,那么对锁肯定是有概念的,锁是计算机协调多个进程或线程对某一资源并发访问的机制。

?

Mysql中的锁分为表锁和行锁:

顾名思义,表锁就是锁住一张表,而行锁就是锁住一行。

?

表锁的特点:开销小,不会产生死锁,发生锁冲突的概率高,并且并发度低。

行锁的特点:开销大,会产生死锁,发生锁冲突的概率低,并发度高。

?

因此MyISAM和Memory引擎采用的是表锁,而InnoDB存储引擎采用的是行锁。


MyISAM的锁机制:

分为共享读锁和独占写锁。

读锁是:当某一进程对某张表进行读操作时(select),其他线程也可以读,但是不能写。简单的理解就是,我读的时候你不能写。

写锁是:当某一进程对某种表某张表的写时(insert,update,,delete),其他线程不能写也不能读。可以理解为,我写的时候,你不能读,也不能写。

?

因此MyISAM的读操作和写操作,以及写操作之间是串行的!MyISAM在执行读写操作的时候会自动给表加相应的锁(也就是说不用显示的使用lock table命令),MyISAM总是一次获得SQL语句所需要的全部锁,这也是MyISAM不会出现死锁的原因。

?

?

下面分别举关于写锁和读锁的例子:

?

写锁:

?

事务1 事务2

取得first_test表的写锁:

mysql> lock table first_test write;

Query OK, 0 rows affected (0.00 sec)

?

当前事务对查询、更新和插入操作都可以执行

mysql> select * from first_test ;

+----+------+

| id | age |

+----+------+

| 1 | 10 |

| 2 | 11 |

| 3 | 12 |

| 4 | 13 |

+----+------+

4 rows in set (0.00 sec)

mysql> insert into first_test(age) values(14);

Query OK, 1 row affected (0.11 sec)

其他事务对锁定表的查询被阻塞,需要等到锁被释放,才可以执行

mysql> select * from first_test;

等待......

mysql> unlock table;

Query OK, 0 rows affected (0.00 sec)

等待
?

mysql> select * from first_test;

+----+------+

| id | age |

+----+------+

| 1 | 10 |

| 2 | 11 |

| 3 | 12 |

| 4 | 13 |

| 5 | 14 |

+----+------+

5 rows in set (9 min 45.02 sec)

?


?

读锁例子如下:

?

事务1 事务2

获得表first_read的锁定

mysql> lock table first_test read;

Query OK, 0 rows affected (0.00 sec)

?

当前事务可以查询该表记录:

mysql> select * from first_test;

+----+------+

| id | age |

+----+------+

| 1 | 10 |

| 2 | 11 |

| 3 | 12 |

| 4 | 13 |

| 5 | 14 |

+----+------+

5 rows in set (0.00 sec)

其他事务也可以查到该表信息

mysql> select * from first_test;

+----+------+

| id | age |

+----+------+

| 1 | 10 |

| 2 | 11 |

| 3 | 12 |

| 4 | 13 |

| 5 | 14 |

+----+------+

5 rows in set (0.00 sec)

但是当前事务不能查询没有锁定的表:

mysql> select * from goods;

ERROR 1100 (HY000): Table 'goods'

was not locked with LOCK TABLES




?

其他事务可以查询或更新未锁定的表:

mysql> select * from goods;

+----+------------+------+

| id | name | num |

+----+------------+------+

| 1 | firstGoods | 11 |

| 3 | ThirdGoods | 11 |

| 4 | fourth | 11 |

+----+------------+------+

10 rows in set (0.00 sec)

而且插入更新锁定的表都会报错:

mysql> insert into first_test(age) values(15);

ERROR 1099 (HY000): Table 'first_test' was locked with

a READ lock and can't be updated

?

mysql> update first_test set age=100 where id =1;

ERROR 1099 (HY000): Table 'first_test' was locked with

a READ lock and can't be updated

当更新被锁定的表时会等待:

mysql> update first_test set age=100 where id =1;

等待......

mysql> unlock table;

Query OK, 0 rows affected (0.00 sec)

mysql> update first_test set age=100 where id =1;

Query OK, 1 row affected (38.82 sec)

Rows matched: 1 Changed: 1 Warnings: 0


?


并发插入

刚说到Mysql在插入和修改的时候都是串行的,但是MyISAM也支持查询和插入的并发操作。

?

MyISAM中有一个系统变量concurrent_insert(默认为1),用以控制并发插入(用户在表尾插入数据)行为。

concurrent_insert为0时,不允许并发插入。

concurrent_insert为1时,如果表中没有空洞(中间没有被删除的行),MyISAM允许一个进程在读表的同时,另一个进程从表尾插入记录。

concurrent_insert为2时,无论MyISAM表中有没有空洞,都可以在末尾插入记录

?

事务1 事务2

mys

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇vs+mysql+ef配置方法 下一篇MySQL InnoDB共享表空间和独立表..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: