[读书笔记]High Performance MySQL–第二章
February 1st, 2005 at 6:50 pm (用力读书)
MySQL与众不同之处在于能根据用户的环境提供给用户多种选择,例如可以在同一个数据库里使用不同类型的表。
2.1 MySQL Architecture
下面是反映MySQL架构的一个逻辑图。
figure2-1.gif
最上层是由一些服务组成,这些服务包括连接控制,认证,安全等。第二层是MySQL比较重要的一个层,在5.0版本中存储程序也在这个层。第三层就是存储引擎了,他们负责数据的存取。各种存储引擎都有优缺点,但是对查询层来说他们都是一样的。二三层之间的接口是一个API,它对存贮引擎都一视同仁。
2.2 Locking and Concurrency
锁定虽然保证了数据的完整性,但无疑带来了性能上的损失。(这里以邮件系统的mbox为例子来说明的。)
2.2.1 Read/Write Locks
锁定分为读锁定(shared locks)和写锁定(exclusive locks)。写锁定是排外的,因为出于安全的考虑在任何时间只能保证一个客户对资源进行写的动作。
2.2.2 Lock Granularity
增加共享资源并发数一种途径就是对资源锁定的细化。但这是需要付出代价的,会带来性能上的损失,因为锁定管理是需要开支的。为了总体性能的提高,这就需要妥协,所以MySQL提供了三种粒度的锁定方式。
2.2.2.1 Table locks
最基本和低开支的锁定策略就是表锁定(table lock)。在很长的一段时间内,MySQL只提供表锁定。MySQL认为大部分程序主要是由读查询组成。事实上,MySQL默认提供的引擎——MyISAM就假设90%的查询都是读的查询。
2.2.2.2 Page locks
页面锁定(page lock)影响并发的主要因素在于页面的大小。MySQL提供的BDB(Berkeley DB)表在页面锁定时使用8KB的页面。
2.2.2.3 Row locks
显然,行锁定(row lock)提供更多的并发以及消耗更多的资源。Mysql的InnoDB表使用行锁定,但是InnoDB不只是用简单的行锁定机制,它使用是一种将行锁定和Multiversioning方案联合起来的机制。
2.2.3 Multi-Version Concurrency Control
MVCC(Multi-Version Concurrency Control)——多版本并发控制目前是增加并发的最终解决办法,此种技术应用于Oracle、PostgreSQL和MySQL的InnoDB存储引擎。它的额外好处在于当进行写操作时对所需资源的锁定并不影响读操作。它的工作机制在于任何基于表的查询实际看到的其实是数据的快照。
在这个多版本系统中,每个行都有两个附加的隐含数据,它们实际上代表着行产生和删除的时间。但是数据库并不储存真实的时间,而是用版本号来代替他。当不断有查询时,这个版本号也就成为一个不断增加的数字。在MVCC下,数据库服务器的主要任务在于追踪所有运行的查询。
2.3 Transactions
事务被认为是一组SQL查询,这组查询被认为工作中最基本的一个单元。(这里用银行的例子来说明。)但是只有事务是不够的,数据库服务器还必须通过所谓的ACID测试。ACID是Atomicity、Consistency、Isolation和Durability的首字母缩写。符合这四项标准的事务被称为ACID事务。
2.3.1 Benefits and Drawbacks
毫无疑问,事务提供了额外的安全保证,但是同时也增加了许多资源的开支。就像上面提到的,这是MySQL的模块优点就会显示出来,这是你可以根据需要决定每个表是否需要ACID事务,从而节省好多资源。
2.3.2 Isolation Levels
SQL标准根据特殊用途定义了四种隔离级别。
2.3.2.1 Read uncommitted
读操作未提交也被称为脏读,是指这样一种事务它可以看到另外事务未提交的结果。脏读很危险而且在实际中应用很少。
2.3.2.2 Read committed
读操作提交是绝大多数数据库默认的隔离级别。
2.3.2.3 Repeatable read
在重复读的隔离级别下,在事务中被进行读操作的行都会被锁定,也就是说这些行不会被改变,直到事务结束。
2.3.2.4 Serializable
可序列化是隔离的最高级别,它解决了幻读的问题,它对事务进行序列化以至于他们不会冲突。
2.3.3 Deadlocks
当两个事务用不同的顺序来尝试获取一个冲突的锁定,这时死锁就会产生。为了解决这个问题,数据库实施了多种的死锁检测和超时设定。
2.3.4 Transaction Logging
事务日志可以减轻事务对资源的开销。当数据库有变化时,系统会更新内存中的数据拷贝(这样比较快)随后把改变的记录写到磁盘上事务日志里,稍后点时间进程会根据事务日志的纪录来更新数据库。
2.3.5 Transactions in MySQL
MySQL提供了两种事务安全存储引擎:Berkeley DB (BDB)和InnoDB。
2.3.5.1 AUTOCOMMIT
MySQL默认工作在自动提交模式下。除非你明确开始一个事务,否则MySQL就会把每个查询当作一个单独的事务来执行。启用或禁止自动提交可以用以下命令:
SET AUTOCOMMIT = 1/0;
启用或禁止自动提交对于非事务引擎毫无效果,例如:MyISAM或者HEAP。
2.3.5.2 Implicit commits
当打开一个事务时,一些特定的命令会使MySQL在执行这个事务前就会提交他。很显然,这些命令会导致重大的变化,例如:命名或删除一个表。下面有这样一些命令的清单:
ALTER TABLE
BEGIN
CREATE INDEX
DROP DATABASE
DROP TABLE
RENAME TABLE
TRUNCATE
LOCK TABLES
UNLOCK TABLES
2.3.5.3 Isolation levels
MySQL允许你使用命令“SET TRANSACTION ISOLATION LEVEL”来设定隔离级别。除非特别注明,隔离级别改变于下一个事务的开始。
设置session的隔离级别,可以用下面这个命令:
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED
设置全局的隔离级别,用下面这个命令
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE
MySQL认可所有4个ANSI标准隔离级别。从MySQL4.05开始,InnoDB完全支持这四个级别。
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE
默认的隔离级别可以在文件my.cnf里设置,使用下面的命令开关:
--transaction-isolation
2.3.5.4 Mixing storage engines in transactions
此项功能目前在MySQL中不能实现,让我们期待将来。
2.3.5.5 Simulating transactions