Bootstrap

高性能MySql(一)

表锁(table lock)

表锁是最MySql最基本的锁策略,并且是开销最小的策略,表锁会锁定整张表,一个用户在对表进行写操作(插入、删除、更新等)前,需要先获取到写锁,这会阻塞其他用户对该表的读写操作。只有没有写锁时,其他读取的用户才能获得读锁,读锁是不互相阻塞的。

行级锁(row lock)

行级锁可以最大程度的支持并发处理。本锁是对数据表中的行进行加锁操作。

数据库事务的ACID

原子性

一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能执行其中一部分操作,这就是事务的原子性

一致性

数据库总是从一个一致性的状态转换为另外一个一致性的状态。

隔离性

通常来说,一个事务所做的修改在最终提交之前,对其他事务是不可见的。

持久性

一旦事务提交则其修改的数据会永久的保存到数据库中。此时即使系统崩溃,修改的数据也不会丢失。

 

数据库隔离级别

Read UnCommited 读未提交

在事务中的修改,即使没有提交也会被读取到。事务可以读取到没有提交的数据,这也被称为脏读。

Read Commited 提交读

这个是大多数数据库的默认隔离级别(但是MySQL不是),本隔离级别的含义是一个事务开始时,只能看到已经提交的事务所做的修改。

Repeatable Read 可重复读

MySQL的默认隔离级别,本隔离级别解决了脏读的问题,该级别保证了同一个事务中多次读取同样的记录的结果是一致的。但是理论上,该级别无法解决幻读

的问题,所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围插入了新的记录,当之前的事务再次读取记录时,就会出现幻读行,就和幻觉一样。InnoDB通过多版本并发控制(MVCC)解决了幻读的问题。

Seriable 串行化

是数据库的最高隔离级别,它通过强制事务串行执行,避免了前面说的幻读的问题。简单来说,Seriable会在读取的每一行数据都加锁,所以可能导致大量的超时和锁争用的问题。谨慎使用

 

死锁

死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。

  • 当多个事务视图以不同的顺序锁定资源时,就可能会产生死锁。

  • 多个事务同时锁定同一个资源时,也会产生死锁

例如:

如果凑巧,两个事务都执行了第一条UPDATE语句,更新了一行数据,同时也锁定了该行数据,接着每个事务都尝试执行第二条语句,却发现该行被对方锁定,然后两个事务都在等待对方释放锁,同时又持有对方需要的锁,则陷入死循环,除非有外部因素介入才能解除死锁。

 

事务日志

事务日志可以帮助提高事务效率,使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘的事务中,而不用每次都将修改的数据本身持久到硬盘。事务日志采用的是追加的方式,因此写日志的操作是磁盘上一块区域内的顺序IO,而不像随机IO需要在多个地方移动磁头,所以采用事务日志要快得多。事务日志以后,内存中被修改的数据在后台可以慢慢的刷回硬盘。

如果修改数据,数据在内存中被修改,没有写回磁盘,此时系统崩溃,在数据库系统下一次重启时会自动回复这部分的数据。

 

 

;