MySQL存储引擎:
一个数据库系统可以切换不同的存储引擎,随意选择写磁盘或操作磁盘的方式,采用插件式的存储引擎体系结构,不同的存储引擎提供不同的存储机制,索引技巧等功能;
个人理解存储引擎解决了怎样存储数据,存储数据到磁盘还是内存;存储引擎执行SQL语句,按照查询计划去查询内存数据,更新磁盘数据,查询磁盘数据,等等,执行诸如此类的一系列操作 常用的存储引擎有InnoDB,MyISAM,Memory等,现在的MySQL一般都是使用InnoDB存储引擎。
binlog日志:
日志是mysql数据库的重要组成部分,记录着数据库运行期间各种状态信息,mysql日志主要包括错误日志,查询日志,慢查询日志,事务日志,二进制日志几大类需要重点关注的是二进制日志(binlog) 和 事务日志(redo log, undo log)
binlog用于记录数据库执行的写入操作信息(不包括查询),以二进制的形式保存在磁盘。binlog是mysql的逻辑日志,使用任何存储引擎的mysql数据库都会记录binlog日志;
binlog是通过追加的方式进行写入的,可以通过max_binlog_size参数设置每个binlog文件的大小,当文件大小达到给定值之后,会生成新的文件来保存日志
binlog使用场景:
在实际应用中,binlog的主要使用场景有两个,分别是主从复制和数据恢复
1.主从复制:在Master端开启binlog,然后将binlog发送到各个Slave端,Slave端重放binlog从而达到主从数据一致
2.数据恢复:通过使用mysqlbinlog工具来恢复数据
binlog的刷盘时机:
通过设置 sync_binlog 参数控制binlog的刷盘时机
逻辑日志和物理日志:
逻辑日志:可以简单理解为记录的就是sql语句 ===> CameraLingo:update(0,’Kermera’=>’camera’)
物理日志:mysql数据最终是保存在数据页中的,物理日志记录的就是数据页变更 ===> “Page 42:image at 367,2; before:’ke’;after:’ca’”
顺序读写比随机读写速度更快,磁盘上随机读写操作是非常耗时的,每次修改一行数据就改磁盘文件,MySQL 的执行效率会非常低下。
innodb_flush_log_at_trx_commit 和 sync_binlog 配置组合:
innodb_flush_log_at_trx_commit:
当设置为0时,该模式速度最快,但不太安全,mysqld进程的崩溃会导致上一秒所有事务数据的丢失
当设置为1时,该模式最安全但也是最慢的一种方式。在mysqld服务崩溃或者服务器主机宕机的情况下,日志缓存区只有可能丢失最多一个语句或者一个事务
当设置为2时,该模式速度较快,较取值为0情况下更安全,只有在操作系统崩溃或者系统断电的情况下,上一秒所有事务数据才可能丢失
sync_binlog=0 或者 N:默认说是0,但是我的是1;
为0时,存储引擎不进行binlog的刷新到磁盘操作,由操作系统控制缓存刷新
为1时,那么此时会强制在提交事务的时候,把binlog直接写入到磁盘文件里去
当设置为0或者大于1时,事务被提交,而尚未同步到磁盘。因此,在电源故障或者系统崩溃时有可能丢失日志
innodb_flush_log_at_trx_commit和sync_binlog都为1时是最安全的,但是双1会导致频繁的IO操作,因为该模式也是最慢的一种
CheckPoint机制:
随着MySQL的运行,Buffer pool中的数据页会被修改成脏数据页,当你开启事务进行一系列的操作时MySQL会为你不停的记录一堆日志,拿redolog来说,redolog也需要先往内存里写,然后再以块的形式刷新回磁盘的。
无论怎样都存在这样一个中间过程:内存中存在脏数据页和脏日志未来得及刷新回磁盘,CheckPoint机制就是将这些脏数据刷新回磁盘的机制,即只要发生ChechPoint,就要将脏数据刷新回磁盘,反过来,当MySQL重启时会去找CheckPoint,并且根据CheckPoint的特性,MySQL可以明确的知道CheckPiont之前的脏数据已经落过盘了,重启时没必要继续重做。
总结:
1.所谓的崩溃恢复,其实就是MySQL重启时只需要对CheckPoint之后的数据进行恢复,所以CheckPoint会缩短MySQL重启的时间
2.因为CheckPoint会不断的更新,并且MySQL重启时只需要对CheckPoint之后的日志回放一遍
3.因此每次进行CheckPoint时Buffer Pool中的脏数据页,redo log中的脏日志都会落盘。所以CheckPoint实际上起到了为这两者进行瘦身的作用
CheckPoint种类及触发条件: fuzzy,模糊
Sharp CheckPoint:当MySQL关闭时或者切换要写的redolog时,会一次性将所有的脏日志全部刷新到磁盘,这种模式下会对MySQL的性能带来较大影响
Fuzzy CheckPoint:这种模式下的CheckPoint每次仅将部分日志刷新到磁盘。
触发条件1:Master Thread Checkpoint 由master线程控制,每秒或每10秒刷入一定比例的脏页到磁盘。
触发条件2:FLUSH_LRU_LIST Checkpoint 从MySQL5.6开始可通过 innodb_page_cleaners 变量指定专门负责脏页刷盘的page cleaner线程的个数,
该线程的目的是为了保证lru列表有可用的空闲页。
触发条件3:async/sync flush Checkpoint 同步刷盘还是异步刷盘。例如还有非常多的脏页没刷到磁盘,这时候会选择同步刷到磁盘,但这很少出现;如果脏页 不是很多,可以选择异步刷到磁盘,如果脏页很少,可以暂时不刷脏页到磁盘
触发条件4:dirty page too much Checkpoint 脏页太多时强制触发检查点,目的是为了保证缓存有足够的空闲空间。too much的比例由变量
innodb_max_dirty_pages_pct 控制,MySQL 5.6默认的值为75,即当脏页占缓冲池的百分之75后,就强制刷一部分脏页到磁盘。
LSN:log sequence number
序列号,表空间中的数据页、内存中的缓存页、内存中的redo log、磁盘中的redo log、checkpoint它们五者都有记录LSN
LSN作用:
比如MySQL重启时会对比数据页的LSN和redo log的LSN的大小,如果前者比后者小,说明数据页缺失一部分数据,如果满足其他数据恢复的条件,MySQL就会将LSN之后的这些redo进行一次回放,完成数据的恢复。
CheckPoint和LSN是两个维度的概念,CheckPoint是为了保持数据的一致性,触发CheckPoint的条件,会将当前内存所处的LSN序列号位置的数据全部落盘,然后Mysql宕机重启那就比较redolog的LSN和磁盘数据页的LSN位置,如果redolog的LSN > 磁盘数据页的LSN,说明磁盘数据页缺失,就把redolog的LSN位置后的数据回放到磁盘数据页。也就是说,一个是落盘用的,一个是记录位置的
InnoDB会把存储的数据划分为若干个页
WAL机制(Write Ahead Log):先将数据写入缓存,然后再写入日志文件,比如redo log日志,先将数据写入redo缓存池里,然后事务开始时再逐步将数据写入redolog文件中,事务结束后必须将该数据写入redolog文件中。
预读机制是利用局部访问原理,加快数据的读取,触发MySQL预读的场景里提到“区”这个概念,什么意思? 可以理解为一个数据区域,包含很多个数据页。这一块区域的热点数据
MySQL使用的是基于冷热数据区域的LRU链表,一个链表分成了冷热两个数据区域。LRU算法:最近最少使用算法,选择最近最久未使用的给予淘汰
如果前一秒读取一个缓存页A 10次,这一秒读取另一个缓存页B 1次,那么缓存页B会排到缓存页A前面嘛?最近读的这个缓存页进入LRU链表头部,B是最近访问的,那么它就在前面。为了达到最大的性能优化,MySQL服务器其实还存在一个机制,前1/4的热数据区域被访问是不会移动链表位置的,只有后3/4的数据被访问了,才会链接位置的移动。热数据区满了,就会将热数据区域尾部缓存页移动到冷数据区域头部。
问题:如果全表扫描的时候37%的冷数据区域一次性放不下从磁盘加载来的数据页会发生什么?
处理会变慢,扫描一部分,淘汰一部分,再加载一部分页进来
Free链表,Flush链表,LRU链表,他们是将不同状态的数据维护起来的,三个链表是操作的是同一块内存区域的Buffer Pool
Free链表:标记哪些缓存页是空闲的,可以存放从磁盘读取的数据页
Flush链表:标记哪些缓存页被修改,成为脏页,增删改。
LRU链表:标记哪些是冷数据,哪些是热数据,lru链表存储了所有的缓存页,增删改查的缓存页都可能会有,当需要淘汰缓存页时,会去lru链表尾部淘汰缓存页,根据flush链表判断是否是脏页刷入磁盘,并且从flush链表中删除,如果是查询页直接释放掉,然后将空闲的缓存页对应的数据块地址加入到free链表中。
知识点:LRU链表刷盘的时候会检查缓存页是否在flush链表中,如果发现存在,lru链表中对应的缓存页刷完盘,flush链表中同一描述数据也会被清理掉。