美文网首页
mysql整体介绍

mysql整体介绍

作者: kar_joe | 来源:发表于2020-01-24 18:20 被阅读0次

    整体架构

    逻辑架构

    image.png

    大体来说,MySQL 可以分为 Server 层和存储引擎层两部分。
    Server 层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
    而存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。

    存储架构

    image.png

    未在图中表示的有,join_buffer、sort_buffer(server层)、临时表
    设计总体原则:
    查询:尽量读内存,实在没办法才读磁盘,尽可能避免磁盘随机读
    写:写内存+顺序写磁盘+随机读磁盘,尽量避免随机读磁盘(普通索引插入),完全避免随机写磁盘

    一条更新语句如何执行

    mysql> update T set c=c+1 where ID=2;

    执行步骤

    image.png
    1. 执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。
    2. 执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到新的一行数据,再调用引擎接口写入这行新数据。
    3. 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。
    4. 执行器生成这个操作的 binlog,并把 binlog 写入磁盘。
    5. 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。
      整个过程,没有修改磁盘数据文件,所以内存与磁盘文件数据不一致,即内存数据页为脏页

    redolog与binlog

    1. redolog
      采用WAL技术,写入时顺序写,避免随机写磁盘;解决crash-safe问题(磁盘数据+redo log)


      image.png

      日常操作写buffer,提交(prepare)时根据配置不同决定是否落地,或者依赖后台线程每秒落地
      InnoDB 提供了innodb_flush_log_at_trx_commit 参数,它有三种可能取值:

      • 设置为 0 的时候,表示每次事务提交时都只是把 redo log 留在 redo log buffer 中 ;
      • 设置为 1 的时候,表示每次事务提交时都将 redo log 直接持久化到磁盘;
      • 设置为 2 的时候,表示每次事务提交时都只是把 redo log 写到 page cache。
        持久化与事务提交无关系,buffer里面的数据可能持久化,但事务提交的时候才变成prepare状态,等待二阶段提交
    2. binlog
      主要用于备份恢复,主备同步
      正常的语句执行,事务提交之前,写binlog cache;事务提交才根据配置执行write或fsync。
      write 和 fsync 的时机,是由参数 sync_binlog 控制的:

    • sync_binlog=0 的时候,表示每次提交事务都只 write,不 fsync;
    • sync_binlog=1 的时候,表示每次提交事务都会执行 fsync; - - sync_binlog=N(N>1) 的时候,表示每次提交事务都 write,但累积 N 个事务后才 fsync。
    1. 比较
    • redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
    • redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
    • redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
    1. 两阶段提交
    • redolog 置为prepare
    • 写binlog
    • redolog 置为commit
      当在第二步之前崩溃,重启恢复:后发现没有commit,回滚;备份恢复:没有binlog 。状态一致
      当在第三步之前崩溃,重启恢复:虽没有commit,但满足prepare和binlog完整,所以重启后会自动commit。备份:有binlog。 状态一致

    刷脏页

    当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为“脏页”。内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”。
    平时执行很快的更新操作,其实就是在写内存和日志,而 MySQL 偶尔“抖”一下的那个瞬间,可能就是在刷脏页(flush)。


    image.png

    刷脏页的场景:

    1. redo log写满了---------------阻塞所有更新操作
    2. 内存满了,根据LRU算法淘汰的是脏页---------一个大查询导致很多脏页淘汰,会慢很多
    3. 空闲的时候
    4. 数据库关闭的时候

    内存页维护LRU算法

    版本1:


    image.png

    版本2:


    image.png

    相关文章

      网友评论

          本文标题:mysql整体介绍

          本文链接:https://www.haomeiwen.com/subject/hyncthtx.html