- 任何时候Why都比What重要;
- 不要相信任何的“神话”,学会自己思考;
- 不要墨守成规,大部分人都知道的事情可能是错误的;
- 不要相信网上的传言,去测试,根据自己的实践做出决定;
- 花时间充分地思考,敢于提出质疑。
1.MYSQL被设计为一个单进程多线程架构的数据库,MYSQL数据库实例在系统上的表现就是一个进程。
2.Oracle中如果没有参数文件,在启动实例时会提示找不到该参数文件,数据库启动失败。而在 MYSQL数据库中,可以没有配置文件,在这种情况下, MYSQL会按照编译时的默认参数设置启动实例。
3.从概念上来说,数据库是文件的集合,是依照某种数据模型组织起来并存放于二级存储器中的数据集合;数据库实例是程序,是位于用户与操作系统之间的一层数据管理软件,用户对数据库数据的任何操作,包括数据库定义、数据查询、数据维护、数据库运行控制等都是在数据库实例下进行的,应用程序只有通过数据库实例才能和数据库打交道。
4.MYSQL由以下几部分组成:
- 连接池组件
- 管理服务和工具组件
- SQL接口组件
- 查询分析器组件
- 优化器组件
- 缓冲(Cache)组件
- 插件式存储引擎
- 物理文件
5.MYSQL数据库区别于其他数据库的最重要的一个特点就是其插件式的表存储引擎。
6.存储引擎是基于表的,而不是数据库。
7.裸设备(raw device),也叫裸分区(原始分区),是一种没有经过格式化,不被Unix通过文件系统来读取的特殊字符设备文件。由应用程序负责对它进行读写操作。不经过文件系统的缓冲。它是不被操作系统直接管理的设备。
8.如果没有显式地在表定义时指定主键, Innodb存储引擎会为每一行生成一个6字节的ROWID,并以此作为主键。
9.MyISAM存储引擎的另一个与众不同的地方是它的缓冲池只缓存(cache)索引文件,而不缓冲数据文件,这点和大多数的数据库都非常不同。
10.MYISAM存储引擎表由MYD和MYI组成,MYD用来存放数据文件,MYI用来存放索引文件。
11.可以通过使用myisampack工具来进一步压缩数据文件,因为myisampack工具使用赫夫曼(Huffman)编码静态算法来压缩数据,因此使用myisampack工具压缩后的表是只读的,当然用户也可以通过myisampack来解压数据文件。
12.NDB存储引擎是一个集群存储引擎,其结构是share nothing的集群架构,因此能提供更高的可用性。NDB的特点是数据全部放在内存中(从MYSQL5.1版本开始,可以将非索引数据放在磁盘上),因此主键查找(primary key lookups)的速度极快,并且通过添加NDB数据存储节点(Data Node)可以线性地提高数据库性能,是高可用、高性能的集群系统。
13.关于NDB存储引擎,有一个问题值得注意,那就是NDB存储引擎的连接操作(JOIN)是在MYSQL数据库层完成的,而不是在存储引擎层完成的。
14.Memory存储引擎默认使用哈希索引,而不是我们熟悉的B+树索引。
15.此外有一点容易被忽视, MYSQL数据库使用 Memory存储引擎作为临时表来存放查询的中间结果集( intermediate result)。如果中间结果集大于 Memory存储引擎表的容量设置,又或者中间结果含有TEXT或BLOB列类型字段,则 MYSQL数据库会把其转换到 MYISAM存储引擎表而存放到磁盘中。之前提到 MYISAM不缓存数据文件,因此这时产生的临时表的性能对于查询会有损失。
16.Maria存储引擎是新开发的引擎,设计目标主要是用来取代原有MyISAM存储引擎,从而成为MYSQL的默认存储引擎。因此,它可以看做是MyISAM的后续版本。Maria存储引擎的特点是:支持缓存数据和索引文件,应用了行锁设计,提供了MVCC功能,支持事务和非事务安全的选项,以及更好的BLOB字符类型的处理性能。
17.可以通过SHOW ENGINES语句查看当前使用的 MYSQL数据库所支持的存储引擎,也可以通过查找information_schema架构下的ENGINES表。
18.MYSQL提供了一个非常好的用来演示MYSQL各项功能的示例数据库。
19.连接MySQL操作是个连接进程和MySQL数据库实例进行通信,本质上是进程通信。
20.常用的进程通信方式有管道、命名管道、命名字、TCP/IP套接字、UNIX域套接字。
21.TCP/IP套接字方式是MySQL数据库在任何平台下都提供的连接方式。
22.在通过TCP/IP连接到MySQL实例时, MySQL数据库会先检查一张权限视图,用来判断发起请求的客户端IP是否允许连接到MySQL实例。该视图在mysql架构下,表名为user。
23.BDB是第一个支持事务的 MySQL存储引擎。
24.Innodb存储引擎有多个内存块,可以认为这些内存块组成了一个大的内存池。
25.后台线程的主要作用是负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据。此外将已修改的数据文件刷新到磁盘文件,同时保证在数据库发生异常的情况下Innodb能恢复到正常运行状态。
26.InnoDB存储引擎是多线程的模型,因此其后台有多个不同的后台线程,负责处理不同的任务。
- Master Thread是一个非常核心的后台线程,主要负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性,包括脏页的刷新、合并插人缓冲(INSERT BUFFER)、UNDO页的回收等。
- 在Innodb存储引擎中大量使用了AIO( Async IO)来处理写IO请求,这样可以极大提高数据库的性能。而IO Thread的工作主要是负责这些IO请求的回调(call back)处理。分别是write、read、insert buffer和log IO thread。
- 事务被提交后,其所使用的undolog可能不再需要,因此需要Purge Thread来回收已经使用并分配的undo页。
- Page Cleaner Thread是在 Innodb1.2x版本中引入的。其作用是将之前版本中脏页的刷新操作都放入到单独的线程中来完成。
27.在数据库中进行读取页的操作,首先将从磁盘读到的页存放在缓冲池中,这个过程称为将页“FIX”在缓冲池中。下一次再读相同的页时,若在缓冲池中,称该页在缓冲池中被命中,直接读取该页。
28.对于数据库中页的修改操作,则首先修改在缓冲池中的页,然后再以一定的频率刷新到磁盘上。Checkpoint
29.具体来看,缓冲池中缓存的数据页类型有:索引页、数据页、undo页、插入缓冲(insert buffer)、自适应哈希索引(adaptive hash index)、Innodb存储的锁信息(lock info)、数据字典信息(data dictionary)等。
30.从InnoDB 1.0.x版本开始,允许有多个缓冲池实例。每个页根据哈希值平均分配到不同缓冲池实例中。
31.从MySQL56版本开始,还可以通过information_schema架构下的表INNODB_BUFFER_POOL_STATS来观察缓冲的状态。
32.在InnoDB存储引擎中,缓冲池中页的大小默认为16KB,同样使用LRU算法对缓冲池进行管理。LRU列表中还加入了midpoint位置。新读取到的页放入到LRU列表的midpoint位置。这个算法称为midpoint insertion strategy。在默认配置下,该位置在LRU列表长度的5/8处。
33.在Innodb存储引擎中,把midpoint之后的列表称为old列表,之前的列表称为new列表。可以简单地理解为new列表中的页都是最为活跃的热点数据。
34.InnoDB存储引擎引入了另一个参数来进一步管理LRU列表这个参数是innodb_old_blocks_time,用于表示页读取到mid位置后需要等待多久才会被加人到LRU列表的热端。
35.Buffer pool hit rate,表示缓冲池的命中率,通常该值不应该小于95%。若发生Buffer pool hit rate的值小于95%这种情况,用户需要观察是否是由于全表扫描引起的LRU列表被污染的问题。
36.InnoDB存储引擎从1.0.x版本开始支持压缩页的功能,即将原本16KB的页压缩为1KB、2KB、4KB和8KB。对于非16KB的页,是通过unzip_LRU列表进行管理的。
37.首先,在unzip_LRU列表中对不同压缩页大小的页进行分别管理。其次,通过伙伴算法进行内存的分配。
38.在LRU列表中的页被修改后,称该页为脏页(dirty page),即缓冲池中的页和磁盘上的页的数据产生了不一致。这时数据库会通过CHECKPOINT机制将脏页刷新回磁盘,而Flush列表中的页即为脏页列表。需要注意的是,脏页既存在于LRU列表中,也存在于Flush列表中。LRU列表用来管理缓冲池中页的可用性, Flush列表用来管理将页刷新回磁盘,二者互不影响。
39.InnoDB存储引擎的内存区域除了有缓冲池外,还有重做日志缓冲(redo log buffer)。 Innodb存储引擎首先将重做日志信息先放入到这个缓冲区,然后按一定频率将其刷新到重做日志文件。
40.下列三种情况下会将重做日志缓冲中的内容刷新到外部磁盘的重做日志文件中。
- Master Thread每一秒将重做日志缓冲刷新到重做日志文件;
- 每个事务提交时会将重做日志缓冲刷新到重做日志文件;
- 当重做日志缓冲池剩余空间小于1/2时,重做日志缓冲刷新到重做日志文件。
41.在InnoDB存储引擎中,对内存的管理是通过一种称为内存堆(heap)的方式进行的。在对一些数据结构本身的内存进行分配时,需要从额外的内存池中进行申请,当该区域的内存不够时,会从缓冲池中进行申请。
42.为了避免发生数据丢失的问题,当前事务数据库系统普遍都采用了Write Ahead Log策略,即当事务提交时,先写重做日志,再修改页。当由于发生宕机而导致数据丢失时,通过重做日志来完成数据的恢复。这也是事务ACID中D(Durability持久性)的要求。
- 即使某个事务还没有提交, INNODB存储引擎仍然每秒会将重做日志缓冲中的内容刷新到重做日志文件。这一点是必须要知道的,因为这可以很好地解释为什么再大的事务提交(commit)的时间也是很短的。