zoukankan      html  css  js  c++  java
  • (1.1)学习笔记之mysql体系结构(内存、进程、线程)

    关键词:mysql体系结构

    参考:https://www.cnblogs.com/zhoubaojian/articles/7866292.html

    一、mysql体系架构概述

      

    1.mysql体系结构概述

      (1)mysql是单进程、多线程的架构,oracle是多进程的架构(windows也是单进程,通过windows虚拟机)。

        单进程、多线程:上下文切换代价比较小,CPU消耗比较少。

        多进程:并发比较好,上下文切换代价比较大。

      (2)mysql存储引擎是可插拔的;什么是存储引擎?存储引擎就是对数据库进行CRUD等相关操作的。存储引擎的对象就是表。

      (3)体系结构自上而下大概分为4部分

        【1】应用程序连接器:为各类应用程序提供连接方式

        【2】连接池:缓存各个应用程序的连接信息,以便不需要每次都去数据库初始化。

        【3】SQL层:

            企业管理服务于工具(management service & untilities):用于管理Mysql,用于协助使用mysql;包括备份、恢复、复制、权限等等

            SQL接口(SQL Interface):用于提供结构来接收外部传输的SQL操作;包括ddl、dml、sp、view、triggers、etc等等

            剖析器(parser):用于分析事物,分析语法是否正确

            优化器(optimizer):用于优化SQL,进行选择-投影-连接行程结果。

            缓存器与缓冲池(buffer & cache):用于缓存磁盘IO数据,缓存CPU与内存协调数据。

        【4】存储层

            存储引擎(可热拔插):决定数据存储的方式和形式

            磁盘存储:直接落地到磁盘的各类文件与数据。

               

    2.mysql实例与数据库的概念

      (1)mysql 1个实例对应多个1个数据库(整体概念,说的是数据文件而不是create database这个);磁盘上的文件叫数据库,内存和进程叫实例。

      (2)oracle 可以1个数据库(整体概念)对应多个实例(即RAC);

      (3)数据库实例来操作数据库数据库。

    3.mysql  InnoDB体系概念

      

      (1)mysql存储引擎就可以看做是数据库

      (2)内存加进程可以看做是实例

      红线框起来的叫实例,蓝色框起来的叫数据库,其关系为1比1;

     mysql5.6 InnoDB 内存系列(Buffer Pool、additional memory pool、redo log buffer pool)

     

      对应这个参数;下面来详解一下;

    (3)buffer pool:

       

      (3.1)index page/data page缓冲

      就是块数据以及脏数据缓存。

        在磁盘中叫块(block),在内存中叫Page,其实是一个概念,Mysql 默认是16K一个块/页。(帧)

      本模块主要放聚集索引组织的数据以及脏数据,注意这里也包含聚集索引的叶子节点,也称之为以聚集索引的方式缓存表数据。

      (3.2)data dictionary缓冲

      数据字典,物理上数据信息存放在mysql根目录下的iblog目录下的ibdata1/ibdata2。

      本模块主要是在DDL操作时做内存数据字典缓冲。

      (3.3)lock info缓冲

      mysql中,行锁信息会放在lock info缓冲里,行锁信息从这里找。

      但大事务、大数据量,行锁达到一定程度会自动升级为表锁。

      (3.4)undo page缓冲

      物理上数据信息存放在mysql根目录下的iblog目录下的ibdata1/ibdata2。

      每次做操作的时候,会把修改、增加、删除的前镜像放入Undo page,以便事务回滚

      (3.5)insert buffer page缓冲(change buffer)

      缓存普通索引/非聚集、非唯一索引。(就是所有缓存)

        在非聚集索引中,如果2个值相差很大,如(1,123456),(2,654321)在磁盘上的存放位置就会相隔较远,我们的hdd磁盘的随机读写比较差,很影响效率。

        这个缓冲解决了这个问题,使用space_id和Page_no +索引值,存放到该缓冲。使用完之后,然后merge合并,插入到磁盘中,减少磁盘IO提高效率。

      (3.6)adaptive hash index缓冲

      查找算法:

        (1)链表遍历 O(N)

        (2)二分查找 Log(N)

        (3)B-TREE查找 Log(N)

        (4)hash查找Log(1)

      这一块就是用来缓冲Hash索引。

    (4)additional memory pool

      附加内存池,随着buffer pool的大小而需要对应增减。单位是byte,默认是8M

    (5)redo log buffer

      其实就是日志缓存池,【1】一般commit就会提交到磁盘日志文件上去  【2】通过设置每1秒刷新  【3】log write(redo log buffer满一半,即1/2))

      物理上存放如下;

      

      

    (6)binlog buffer

      主要用来缓存各种数据变更操作所产生的二进制信息。二进制日志会先写入binlog buffer ,然后再写入到磁盘log file。

       与redo log buffer的区别;

      【1】从类别来说:  Binlog buffer包含innodb与myisam引擎,而redo log buffer只在Innodb里面;

      【2】从记录方式:  二进制日志:记录日志的具体操作内容,是逻辑日志    重做日志:记录每个页的更改的物理情况;

      【3】从时间上说:  二进制日志:只在事务完成后进行写入,只写磁盘一次,无论这时事务有多大  重做日志:在事务进行中,就不断有重做日志条目(redo entry)写入重做日志文件;

    (7)double write Buffer(是innodb表空间ibdata中一块连续的128page=2M的存储空间,它的作用是处理产生Partial write时候的data recovery)

      以一个insert 为例。步骤如下

      【1】从磁盘读取page到index page(也就是把数据都缓存到内存),这个过程是同步的。

      【2】在内存中插入数据,然后再准备写回磁盘,这个过程是异步的。

            问:插入在内存中该页为16K,脏页刷新写入磁盘写到一半的时候也就是8K的时候突然出问题了,后续写入失败了。这个时候咋办?

       答:这个时候实际数据页坏了,redo恢复不了。因为每个页头部和尾部都有个checksum校验和,当你写到一半的时候,页是有问题的(因为头部和尾部的checksum校验和不一致),mysql会把页设置为损坏状态。redo去重做的时候,发现该页是损坏的(checksum头尾不一致)。redo无法恢复,因为redo里面没有保留数据页完整的镜像,只是保留了这个page里面修改的某条记录。所以当page不完整的时候,redo没办法去修改。

      所以为了解决这个问题,mysql里面有了double write。double write怎么做到的呢,步骤如下;

      【3】脏数据插入磁盘过程:首先会把脏数据放入double write里面

      【4】double write会把数据写入到 sys tablespace中的double write segment(即表空间中的专属双写段中),其实就是写到了上面说过多次的ibdata1/ibdata2中(这个步骤其实已经把数据持久化到磁盘上了)。如果从double write内存中写入到double write segment过程中出了问题,那么先丢弃掉double write segment中的本次已写数据。然后double write会重新写入一遍,直到数据写入到double write segment中去为止。

      【5】然后再从double write segment 中写入到user tablespace中的正式数据文件中去。如果这个过程中发生写坏了的情况,那么double write segment中已经存在持久化的完整的数据页信息,会重新写一份到正式数据文件中去。

    那么内存到这里就基本学习完了。下面继续学习线程。

    mysql InnoDB 线程系列

    1.查看

     查看mysql进程与线程

    ps -ef |grep 3306

    #效果如下
     
    #看图中 进程号为3530,那么我们要查看进程中的所有线程命令如下

    pstack 3530
    #如下图,我这里一共28个线程

     2.深入讲解所有线程

    (1)user threads :用户连接线程

    (2)full text seach optimize thread:全文搜索线程

    (3)rollback clean thread:回滚线程

    (4)recv write thread:恢复线程

    (5)redo log thread:刷日志线程,当内存中的redo log buffer有事务commit的时候,会刷日志数据到磁盘。或者当redo log buffer超过其buffer阈值 1/2的时候,也会刷日志数据到磁盘。每1s也会刷。

    (6)write thread:配合double write去写,异步写入,我这里设置的是10个。

      

    (7)read thread:读线程,这里为预读。我这里线程数为4

      

    (8)purge thread:清除线程,当undo buffer比较大的时候,专门用这个线程来清除undo buffer里面的数据;让undo可以重用。如下图:我设置的每次purge 300个页,线程为1;默认是10S刷新一次(在undo buffer没有使用的情况下),而且,undo buffer一定是要比脏数据提前存到磁盘的。。。

      这样就不会反复写入,把undo 文件撑得很大。

      

    (9)page cleaner thread:刷脏块/index page线程(使用LRU算法)

      内存分为三大Page:

      【1】free page; 【2】clean page; 【3】dirty page;

    (10)master thread:刷insert buffer page。使用merge来合并insert buffer page里面的数据,然后一次性的去写入到磁盘;

    (11)buffer dump thread:保留/启用预热数据

    我们启用一下这个线程,然后看看其作用。

      

    关闭Mysql之后,热数据(内存数据)会放到这里来

      

    然后这个文件里面存的热块内容是:space_id和page_no

      

    以前没这个参数的时候,我们都是通过select count(*) from table 来预热某个表。

    (12)monitor thread:监听线程;

    (13)dictionary stats thread:字典状态datas dictionary线程;

    (14)lock timeout thread:锁超时线程;

    (15)error monltor thread:错误显示线程;

      

      

      

        

     

  • 相关阅读:
    Cocos2d-x 学习笔记(11.1) MoveBy MoveTo
    Cocos2d-x 学习笔记(10) ActionInstant
    Cocos2d-x 学习笔记(9) Action 运行原理
    Cocos2d-x 学习笔记(8) ActionManager
    Cocos2d-x 学习笔记(7) 内存管理 Sprite SpriteFrame Texture2D
    Cocos2d-x 学习笔记(6) Sprite SpriteFrameCache Texture2D TextureCache
    常见串口术语区分
    串口调试
    Linux
    缓冲区
  • 原文地址:https://www.cnblogs.com/gered/p/9613750.html
Copyright © 2011-2022 走看看