关键词: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:错误显示线程;

  

  

  

    

 

(1.1)学习笔记之mysql体系结构(内存、进程、线程)的更多相关文章

  1. (1.3)学习笔记之mysql体系结构(C/S整体架构、内存结构、物理存储结构、逻辑结构)

    目录 1.学习笔记之mysql体系结构(C/S架构) 2.mysql整体架构 3.存储引擎 4.sql语句处理--SQL层(内存层) 5.服务器内存结构 6.mysql如何使用磁盘空间 7.mysql ...

  2. (1.2)学习笔记之mysql体系结构(数据库文件)

    InnoDB存储引擎体系结构图 1.InnoDB数据库的结构 (1)redo log:这里的redo log不是数据的redo log,InnoDB本也是一个数据库,身具有的redo log,所以这里 ...

  3. JVM学习笔记(四)------内存调优【转】

    转自:http://blog.csdn.net/cutesource/article/details/5907418 版权声明:本文为博主原创文章,未经博主允许不得转载. 首先需要注意的是在对JVM内 ...

  4. JVM学习笔记(四)------内存调优

    首先需要注意的是在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提 ...

  5. SQLMAP学习笔记2 Mysql数据库注入

    SQLMAP学习笔记2 Mysql数据库注入 注入流程 (如果网站需要登录,就要用到cookie信息,通过F12开发者工具获取cookie信息) sqlmap -u "URL" - ...

  6. ref:学习笔记 UpdateXml() MYSQL显错注入

    ref:https://www.cnblogs.com/MiWhite/p/6228491.html 学习笔记 UpdateXml() MYSQL显错注入 在学习之前,需要先了解 UpdateXml( ...

  7. JUC学习笔记——共享模型之内存

    JUC学习笔记--共享模型之内存 在本系列内容中我们会对JUC做一个系统的学习,本片将会介绍JUC的内存部分 我们会分为以下几部分进行介绍: Java内存模型 可见性 模式之两阶段终止 模式之Balk ...

  8. JS 学习笔记--9---变量-作用域-内存相关

    JS 中变量和其它语言中变量最大的区别就是,JS 是松散型语言,决定了它只是在某一个特定时间保存某一特定的值的一个名字而已.由于在定义变量的时候不需要显示规定必须保存某种类型的值,故变量的值以及保存的 ...

  9. MySQL笔记(1)---MySQL体系结构和存储引擎

    1.前言 本系列记录MYSQL数据库的一些结构和实现特点,方便查询. 2.基本概念 数据库:物理操作系统文件或者其他形式文件类型的集合.MySQL中数据库文件可以是frm.MYD.MYI.ibd结尾的 ...

随机推荐

  1. think PHP提取字符串中的数字,并到数据库中使用in查询所关联表的字段值

    /* * 提取数字并去数据库取得相应的分类名 * $strs 需要处理的字符串 * $table 数据表名 * $condition 条件字段 * $field 获取的字段 */ public fun ...

  2. 基于第二次数独游戏,添加GUI界面

    高级软件工程第三次作业:基于第二次数独游戏,添加GUI界面.GUI界面代码如下: package firstGui; import java.awt.*; import java.awt.event. ...

  3. git 资料

    git学习资料整理(知乎搜集的) https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 ...

  4. Scrapy框架: 通用爬虫之XMLFeedSpider

    步骤01: 创建项目 scrapy startproject xmlfeedspider 步骤02: 使用XMLFeedSpider模版创建爬虫 scrapy genspider -t xmlfeed ...

  5. 注册服务到服务中心(Consul)

    注册服务到服务中心(Consul) 添加POM文件中的依赖 在POM文件添加如下依赖: <dependency> <groupId>org.springframework.bo ...

  6. Codeforces 500C New Year Book Reading

    C. New Year Book Reading time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  7. UML 简介

    虚线箭头指向依赖: 实线箭头指向关联: 虚线三角指向接口: 实线三角指向父类: 空心菱形能分离而独立存在,是聚合: 实心菱形精密关联不可分,是组合:

  8. JS事件委托(事件代理,dom2级事件)

    一.前言 说实话,真问我什么是事件委托,我肯定gg,还好查了一下,原来就是我之前练习过的DOM2级事件的应用. 二.什么是事件委托? 事件委托就是当事件触发时,把要做的事委托给父元素(或父元素的父元素 ...

  9. sql 根据身份证判断年龄是否小于18岁

    SELECT *, Age= datediff(yy,cast(case when substring(PersonalId,,) ') /*若第7位不是'1'或'2'则表示是15位身份证编码规则*/ ...

  10. MD相关语法

    原文链接:https://www.jianshu.com/p/96ecaa2cc989 标题 一个#表示一级标题,最多6个表示6级标题 h1 h2 h3 h4 h5 h6 列表 无序列表,用 * + ...