vlambda博客
学习文章列表

读书摘录--《MySQL技术内幕InnoDB存储引擎》

推荐歌单:温度 《黄霑-倩女幽魂 【木吉他指弹曲】(温度 Remix)》

温度 - 黄霑-倩女幽魂 【木吉 From 风之博客 04:03


P1 MySQL被设计为一个单进程多线程架构的数据库

P2 在MySQL数据库中,可以没有配置文件,在这种情况下,MySQL会按照编译时的默认参数设置启动实例

P3 MySQL由以下几部分组成:

  1. 链接池组件

  2. 管理服务和工具组件 

  3. SQL接口组件 

  4. 查询分析器组件 

  5. 优化器组件 

  6. 缓冲组件

  7. 插件式存储引擎

  8. 物理文件

P5 MySQL数据库区别于其他数据库的最重要的一个特点就是其插件式的表存储引擎。存储引擎是底层物理结构的实现 存储引擎是基于表的,而不是数据库

P6 从MySQL数据库5.5.8版本开始,InnoDB存储引擎是默认的存储引擎

P6 InnoDB通过使用多版本并发控制(MVCC)来获得高并发性,并且实现了SQL标准的4中隔离级别,默认为REPEATABLE级别。同时,使用一种被称为next-key locking的策略来避免幻读(phantom)现象的产生。除此之外,InnoDB 存储引擎还提供了插入缓冲(insert buffer)、二次写(double write)自适应哈希索引(adptive hash index),预读(read ahead)等高性能和高可用的功能

P7 在MySQL5.5.8版本之前MyISAM 存储引擎是默认的存储引擎

P8 Memory存储引擎将表中的数据存放于内存中。非常适合于存储临时数据的临时表,以及数据仓库中的纬度表 Memory存储引擎默认使用哈希索引。MySQL数据库使用Memory存储引擎作为临时表来存放查询的中间结果集

P9 Archive存储引擎只支持insert 和 select操作。Archive存储引擎非常适合存储归档数据,如日志信息。Archive存储引擎使用行锁来实现高并发的插入操作,但是其本身并不是事务安全的存储引擎,其设计目标主要提供高速的插入和压缩功能。

P11 可以通过show engines语句查看当前使用的MySQL数据库所支持的存储引擎

P13 常用的进程通信方式有管道、命名管道、命名字、TCP/IP 套接字、UNIX域套接字

P20 

  1. Master Thread是非常核心的后台线程,主要负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性。

  2. IO Thread在InnoDB存储引擎中大量使用了AIO(async IO)来处理IO请求。而IO Thread的工作主要负责这些IO请求的回调处理

  3. Purge Thread事务被提交后,其所使用的undo log可能不再需要,因此需要Purge Thread来回收已经使用并分配的undo页

  4. Page cleaner Thread 其作用是将之前版本中脏页的刷新操作都放入到单独的线程中来完成

P23 缓冲池的大小直接影响着数据库的整体性能,缓冲池的配置通过参数innodb_buffer_pool_size来设置

P25 数据库中的缓冲池是通过LRU(Latest Recent Used,最近最少使用)算法来进行管理的。在InnoDB存储引擎中,缓冲池中页的大小默认为16KB

P26 Innodb存储引擎 midpoint insertion strategy。在默认配置下,该位置在LRU列表长度的5/8处。在InnoDB存储引擎中,把midpoint 之后的列表成为old列表,之前的列表成为new列表

P28 执行命令 show engine innodb status显示的不是之前的状态,而是过去某个时间范围内InnoDB存储引擎的状态

P29 伙伴算法 P30 checkpoint机制

P30 LRU列表用来管理缓冲池中页的可用性,Flush列表用来管理将页刷新回磁盘,二者互补影响

P31 重做日志在下列三种情况下会将重做日志缓冲中的内容刷新到外部磁盘的重做日志文件中:

  1. Master Thread每一秒将重做日志缓冲刷新到重做日志文件

  2. 每个事务提交时会将重做日志缓冲刷新到重做日志文件

  3. 当重做日志缓冲池剩余空间小于1/2时,重做日志缓冲刷新到重做日志文件

P32 当前事务数据库系统都普遍采用了write ahead log策略,即当事务提交时,先写重做日志,再修改页

P33 对于InnoDB存储引擎而言,其实通过LSN(log sequence number)来标记版本的。

P34 sharp check point 、fuzzy check point:Master Thread checkpoint、Flush_LRU_List checkpoint、Dirty Page too much checkpoint

P45 InooDB特性:插入缓冲(insert buffer)、两次写(Double wriite)、自适应哈希索引(adaptive hash index)、异步IO(Async IO)、刷新临接页(Flush Neighbor Page)

P55 在生产环境中,B+树的高度一般为3-4层,故需要3-4次的查询(Adaptive Hash Index,AHI),InnoDB存储引擎会监控对表上个索引页的查询。如果观察到简历哈希索引可以带来速度提升,则建立哈希索引,称之为自适应哈希索引

P56 核心索引只能用来搜索等值的查询

P65 日志文件记录了影响MySQL数据库的各种类型活动。MySQL数据库常见的日志文件有:错误日志 二进制文件 慢查询日志

P67 慢查询日志可帮助DBA定位可能存在问题的SQL语句,从而进行SQL语句层面的优化。

在默认情况下,MySQL数据库并不启动慢查询日志,用户需要手工将这个参数设为on

P68 使用MySQL数据库提供的 mysqldumpslow 命令,对慢查询日志文件进行分析

P69 slow_log 慢查询日志表

P73 二进制日志记录了对MySQL数据库执行更改的所有操作。

P87 重做日志文件的大小设置对于InnoDB存储引擎的性能有着非常大的影响

P137 约束和索引的概念还是有所不同的,约束更是一个逻辑的概念,用来保证数据的完整性,而索引是一个数据结构,既有逻辑上的概念,在数据库中还代表着物理存储的方式

P140 最多可以为一个表建立6个触发器,即分别为insert、update、delete的before和after各定义一个

P150 物化视图

P184 InnoDB存储引擎支持的哈希索引是自适应的,InnoDB存储引擎会根据表的使用情况自动为表生产哈希索引,不能人为干预是否在一张表中生成哈希索引

P190 B+树使用填充因子(fill factor)来控制树的删除变化,50%是填充因子可设的最小值

P191 B+索引在数据库中有一个特点是高扇出性,因此在数据库中,B+树的高度一般都在2-4层,这也就是说查询某一键值的行记录是最多只需要2到4次IO



P206 因此我建议在一个非高峰时间,对应用程序下的几张核心表做ANALYZE TABLE操作,这能使优化器和索引更好地为你工作

P231 需要注意的是,哈希索引只能用来搜索等值的查询

P231 全文检索(full-text search)是将存储于数据库中的整本书或整篇文章中的任意内容查找出来的技术

      全文检索通常使用倒排索引(inverted index)来实现。它在辅助表(auxiliary table)中存储了单词与单词自身在一个或多个文档中所在位置之间的映射

P233 在InnoDB存储引擎的全文索引中,还有另外一个重要的概念 FTS index cache(全文检索索引缓存),其用来提高全文检索的性能。FTS Index Cache是一个红黑树结构。其根据(word,ilist)进行排序

P239 stopword 列表,其表示该列表中的word不要对其进行索引分词操作

当前InnoDB存储引擎的全文检索还存在以下的限制:

  1. 每张表只能有一个全文检索的索引

  2. 由多列组合而成的全文紧缩的索引列必须使用相同的字符集与排序规则

  3. 不支持设有单词界定符的语言,如中文、日语、韩语等

P240 MySQL数据库通过MATCH --- AGIAINST 语法支持全文检索的查询

例如:select * from fts_a where match(body) against ('Porridge' IN NATURAL LANGUAGE MODE);

P247 MySQL数据库还支持全文检索的扩展查询。这种查询通常在查询的关键词太短,用户需要implied knowledge(隐含知识)时进行。Query Expansion

P249 人们认为行级锁总会增加开销。实际上,只有当实现本身会增加开销时,行级锁才会增加开销

P250 InnoDB存储引擎的实现和oracle数据库非常类似,提供一致性的非锁定读---行级锁支持

    lock 与 latch都可以被称为“锁”。但两者有着截然不同的含义

    latch一般称为闩锁(轻量级的锁),因为其要求锁定的时间必须非常短。若持续的时间长,则应用的性能会非常差。在InnoDB存储引擎中,latch又可以分为mutex(互斥量)和rwlock(读写锁)。其目的是用来保证并发线程操作临界资源的正确性,并且通常没有死锁检测的机制。

    lock的对象是事务,用来锁定的是数据库中的对象,如表、页、行,并且一般lock的对象仅在事务commit 或 roll back 后进行释放(不同事务隔离级别释放的时间可能不同。)此外,lock,正如在大多数数据库中一样,是有死锁机制的。

P252 InnoDB存储引擎实现了如下两种标准的行级锁:

共享锁(S lock),允许事务读一行数据

排他锁(X lock),允许事务删除或更新一行数据

意向锁(Intension lock)

P259 非锁定读机制极大地提高了数据库的并发性

在事务隔离级别 READ COMMITED 和 REPEATABLE READ (InnoDB 存储引擎的默认事务隔离级别),InnoDB存储引擎使用非锁定一致性读

P262 InnoDB存储引擎对于select语句支持两种一致性的锁定读操作:

select --- for updateselect --- lock in share mode

select --- for update 对读取的行记录加一个X锁,其他事务不能对已锁定的行加上任何锁。

select--- lock in share mode 对读取的记录加一个S 锁,其他事务可以向被锁定的行加S锁,但是如果加X锁,则会被阻塞。

P262 自增长锁

P272 InnoDB存储引擎默认的事务级别为READ REPEATABLE,Microsoft SQL Server数据库为READ COMMITED,Oracle数据库同样也是READ COMMITED

P274 在InnoDB存储引擎中,通过使用next-key lock 算法来避免不可重复读问题

P278 当前数据库还都普遍采用了 wait-for-graph (等待图)的方式来进行死锁检测。较之超时的解决方案,这是一种更为主动的死锁检测方式

    解决死锁问题最简单的一种方法是超时。

    wait-for graph的死锁检测通常采用了深度优先的算法实现

P294 在InnoDB存储引擎中,由两部分组成,即redo_log和undo_log。redo log用来保证事务的持久性,undo来用来帮助事务回滚及MVCC的功能。

P305 redo存放在重做日志文件中,与redo不同,undo存放在数据库内部的一个特殊段(segment),这个段称为undo段(undo segment)。undo段位于共享表空间内

P324 但在存储过程中,MySQL数据库的分析器会自动将BEGIN识别为BEGIN---END,因此在存储过程中只能使用START TRANSACTION语句来开启事务

P331 InnoDB存储引擎在REPEATABLE READ事务隔离级别下,使用NEXT-Key lock锁的算法,因此避免幻读的产生

P331 可通过命令 SET GLOBAL/SESSION TRANSACTION ISOLATION LEVEL或修改mysql配置文件的方式来修改事务的隔离级别

P332 SERIALIABLE的事务隔离级别主要用于InnoDB存储引擎的分布式事务

P335 InnoDB存储引擎提供了对XA事务的支持,并通过XA事务来支持分布式事务的实现

在使用分布式事务时,InnoDB存储引擎的事务隔离级别必须设置为SERIALIABLE

P335 XA事务允许不同数据库之间的分布式事务,如一台服务器是MySQL数据库的,另一台是oracle数据库的,又可能还有一台服务器是SQL Server数据库的,只要参与在全局事务中的每个节点都支持XA事务

P336 XA事务由一个或多个资源管理器(Resource Mangager)。一个事务管理器(Transaction Manager)以及一个应用程序(Application Program)组成

资源管理器:提供访问事务资源的方法。通常一个数据库就是一个资源管理器

事务管理器:协调参与全局事务中的各个事务。需要和参与全局事务的所有资源管理器进行通信。

应用程序:定义事务的边界,指定全局事务中的操作。

分布式事务使用两阶段提交(two-phase commit)的方式

P337 当前java的 JTA(java transaction API)可以很好地支持MySQL的分布式事务

P383 数据库的应用类型。一般而言,可分为两大类:OLTP(Online Transaction Processiong,z在线事务处理)和OLAP(Online Analytical Processing,在线分析处理)。OLAP多用在数据仓库或数据集市中,一般需要指执行复杂的SQL语句来进行查询:OLTP用在日常的事务处理应用中,如银行交易,在线商品交易、Blog、网络游戏等应用。相对于OLAP,数据库的容量较小

P384 可以说OLAP是CPU密集型的操作,而OLTP是IO密集型的操作。

如果CPU是多核的,可以通过修改参数innodb_read_io_threads 和 innodb_write_io_threads来增大IO的线程,这样也能更充分有效地利用CPU的多核性能

P385 所以,应该在开发应用前预估“活跃”数据库的大小是多少,并以此确定数据库服务器内存的大小

P389 此外,还可以使用Inno SQL开发的L2 Cache解决方案,该解决方案可以充分利用固态硬盘的超高速随机读取性能,在内存缓冲池和传统存储层之间建立一层基于闪存固态硬盘的二级缓冲池,以此来扩充缓冲池的容量,提高数据库的性能

P389 RAID(Redundant Array of Independt Disks,独立磁盘冗余数组)

P394 RAID 片配置 Mega CLI 工具

P399 两款更为优秀和常用的基准测试工具:sysbench 和 mysql-tpcc