(答辩完成,接下来一段时间会抓紧学习,月底回国。)
拿两三篇总结MySQL的知识点,补上之前的坑。这里第一篇主要讲粗略讲一下MySQL体系结构和存储引擎,通过对MySQL大体的认识,连带补充一些关于InnoDB的特性。
1.1 什么是数据库,MySQL和SQL
首先讲数据库,
数据库(DB)是文件的集合,是依照某种数据模型组织起来并存放于二级存储器中的数据集合。通俗讲,数据库就是存放数据的仓库。
数据库管理系统(DBMS)就是用来管理数据库的,在用户与操作系统之间,由相互关联的数据集合以及一组用于访问这些数据的程序组成。
数据库系统(DBS)是一个通称,包括数据库、数据库管理系统、数据库管理人员等的统称,是最大的范畴。详细点说,DBS是实现有组织的、动态的存储大量关联数据、方便多用户访问的计算机硬件、软件(包括操作系统、应用程序、DBMS)、数据资源、人员(数据库管理员、使用者等)组成的系统。
现在讲什么是MySQL和SQL
MySQL 是最流行的关系型数据库管理系统(RDBMS),在 WEB 应用方面 MySQL 是最好的 RDBMS应用软件之一,而SQL是用来操作数据库里数据的语言(工具)。
SQL,指结构化查询语言,全称是 Structured Query Language。其中SQL与NoSQL的区别见这篇文章。
回到SQL和MySQl,来源知乎的一个例子比较形象:例如有一碗米饭(碗就是mysql,里面放的米是数据),你要吃碗里的米饭,拿什么吃?拿筷子(sql)。用筷子(sql)操作碗里(mysql)的米饭(数据)
我们规定一个数据库实例是位于用户和操作系统之间的一层数据管理软件的程序,用户对数据库的任何操作都是在数据库实例下进行的。
1.2 MySQL的认识与体系架构
现在我们知道了MySQl是一种RDBMS,是位于用户和操作系统之间的一层数据管理软件。那用户对数据库的任何操作都是在一个MySQL下的一个数据库实例下进行的。不过由于我们一般会淡化DB,DBMS和DBS之间的关系,只有在较真的情况下才会区别,所以以下篇幅中,会把MySQL数据库管理系统简化称为MySQL数据库。
在linux中通过以下命令启动MySQL实例,并通过命令ps观察MySQL启动后的进程情况。(挖坑)
我们发现MySQL是一个单进程多线程架构的数据库,由后台线程以及一个共享内存区组成。官网中的体系结构如图
我们发现,MySQL由很多部分组成,其中很多是所有数据库都需要完成的,比如SQL分析器和优化器,然而MySQL的重要特点之一是插件式的存储引擎架构,存储引擎是物理架构的实现,基于表操作,每个存储引擎开发者可以按照自己的意愿来开发,具体存储引擎的部分会在下面部分讲。
从体系架构得到的MySQL总体的三个问题及解答:
MySQL支持全文索引吗?---> MySQL的MyISAM, Sphinx,新版InnoDB存储引擎都支持全文索引
MySQL速度快是因为它不支持事务吗?---》MyISAM不支持事务,所以对于ETL这种操作,会有优势;InnoDB支持事务,在OLTP环境中效率变高。
数据量大于1000万时MySQL性能急剧下降怎么办?---》优化SQL和索引->加缓存redis->主从复制,读写分离,防止扫描全区->垂直拆分,变成分布式系统->水平拆分,分数据量过大的表
通过这三个问题,解决问题是一方面,还有了解存储引擎在MySQl的重要性。
1.3 连接MySQL数据库的常用方式:
TCP/IP套接字(跨平台)
命名管道和共享内存(Windows,进程通信在同一服务器)
Unix域套接字(Unix,不是网络协议,所以只有在客户端和数据库实例在一台机器上可用)
MySQL存储引擎有很多,一般用到的是MyISAM和InnoDB。
2.1 InnoDB存储引擎:
支持事务
行锁设计
支持外键
支持非锁定读(默认读不会产生锁)
实现MVCC多版本并发控制获得高并发性,实现SQL的四种隔离级别,默认为可重复读。使用next-keylocking的策略来避免幻读。
提供插入缓冲,二次写,自适应哈希索引,预读等功能。
聚集索引:对于表中数据的存储,InnoDB存储引擎采用了聚集索引的方式,因此每张表的存储都是按主键的顺序存放,如果没有显式指定主键,就会为每一行生成一个6字节的RowID,并以此为主键。
InnoDB支持崩溃后的安全恢复。
(补充:MVCC 的机制:通过时间戳,递增事务实现事务一致性,使每个连接到数据库的读者,在某个瞬间看到的是数据库的一个快照,写者写操作造成的变化在写操作完成之前(或者数据库事务提交之前)对于其他的读者来说是不可见的。
当一个 MVCC 数据库需要更一个一条数据记录的时候,它不会直接用新数据覆盖旧数据,而是将旧数据标记为过时(obsolete)并在别处增加新版本的数据。这样就会有存储多个版本的数据,但是只有一个是最新的。)
2.2 MyISAM存储引擎:
不支持事务
表锁设计
支持全文索引,InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快。
非聚集索引,缓冲池中只缓存索引文件,而不缓存数据文件。存储引擎表由存放数据文件的MYD和存放索引文件的MYI组成。
读效率高
InnoDB存储引擎
3.1 OLAP和OLTP的区别与联系
数据库与传统文件系统最大的区别在于DB支持事务。
当今的数据处理大致可以分成两大类:联机事务处理OLTP(on-line transaction processing)、联机分析处理OLAP(On-Line Analytical Processing)。
OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,例如银行交易。
OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。
3.2 InnoDB体系架构:
1. 后台线程需要访问的多个内部数据结构,主线程负责缓存异步刷新到磁盘,保持数据一致性
2. 内存缓存磁盘上的数据,方便读取(LRU策略)
3. redo日志缓冲
3.3 checkpoint技术
在以往数据库容错场景中,事务提交时,先做日志,再修改页,当发生宕机导致数据丢失时,通过重做日志来完成数据恢复。可是缓冲越来越大,日志越来越大的时候就会发生很多问题。
redo log记录了数据操作在物理层面的修改,mysql中使用了大量缓存,缓存存在于内存中,修改操作时会直接修改内存,而不是立刻修改磁盘,当内存和磁盘的数据不一致时,称内存中的数据为脏页(dirty page)。为了保证数据的安全性,事务进行中时会不断的产生redo log,在事务提交时进行一次flush操作,保存到磁盘中, redo log是按照顺序写入的,磁盘的顺序读写的速度远大于随机读写。当数据库或主机失效重启时,会根据redo log进行数据的恢复,如果redo log中有事务提交,则进行事务提交修改数据。这样实现了事务的原子性、一致性和持久性。
现在InnoDB加入checkpoint目的是:
1. 缩短数据库恢复时间
2. 缓冲池不够用时,将脏页刷新到磁盘
3. redo日志不可用时,刷新脏页
数据库不需要重做所有的日志,因为checkpoint之前的页都已经刷新回磁盘,故数据库只需要checkpoint后重做日志进行恢复。