一、关于一个SQL的简单的工作过程
1、工作前提描述
  1、启动MySQL,在内存中分配一个大空间innodb_buffer_pool(还有log_buffer)
  2、多用户线程连接MySQL,从内存分配用户工作空间(其中排序空间)
  3、磁盘上有数据库文件、ib_logfile、tmp目录、undo
2、SQL的简易流程
  1、DQL操作
    1、首先进行内存读
    2、如果buffer pool中没有所需数据,就进行物理读
    3、物理读数据读入buffer pool,再返回给用户工作空间
  2、DML操作(例update)
    1、内存读,然后进行物理读,读取所需修改的数据行
    2、从磁盘调入undo页到buffer pool中
    3、修改前的数据存入undo页里,产生redo
    4、修改数据行(buffer pool中数据页成脏页),产生redo
    5、生成的redo先是存于用户工作空间,择机拷入log_buffer中
    6、log线程不断的将log_buffer中的记录写入redo logfile中
    7、修改完所有数据行,提交事务,刻意再触发一下log线程
    8、待log_buffer中的相关信息都写完,响应事务提交成功
  至此,日志写入磁盘,内存脏块还在buffer pool中(后台周期写入磁盘,释放buffer pool空间)。
 
二、影响SQL执行性能的因素,及具体看方式
1、大量物理读
mysql> show global status like 'i%read%';
| Innodb_buffer_pool_reads | 647 |
| Innodb_data_read | 48402944 |
| Innodb_data_reads | 2996 |
| Innodb_pages_read | 2949 |
| Innodb_rows_read | 1002172 |
  1、Innodb_buffer_pool_reads:物理读次数
  2、Innodb_data_read:物理读数据字节量
  3、Innodb_data_reads:物理读IO请求次数
  4、Innodb_pages_read:物理读数据页数
  5、Innodb_rows_read:物理读数据行数
2、Log写性能
mysql> show engine innodb status \G
---
LOG
---
Log sequence number 144064129  //已经生成的日志量(累计值)/单位:字节
Log flushed up to 144064129  //已经写入的日志量(累计值)
Pages flushed up to 144064129  //已经写入的脏页量(累计值)
Last checkpoint at 144064120  //检查点
0 pending log flushes, 0 pending chkp writes
92 log i/o's done, 0.00 log i/o's/second
  关于redo log的写入:
  1、Innodb_os_log_written:日志刷盘的字节数,如果在commit不怎么变化的情况下,这个值出现暴增,说明系统出现大事务了(处理:kill线程,必要情况kill掉mysql进程);
  2、Innodb_log_writes:日志写的次数。
3、磁盘排序
mysql> show status like 'Sort_merge_passes';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Sort_merge_passes | 0 |
+-------------------+-------+
1 row in set (0.00 sec)

  用户所需数据,如果没有内存buffer pool中,就发生物理读;  

  如果需要过滤掉很多数据,就会影响物理读和内存读,因为返回很多的数据(物理读),在内存中需要过滤掉很多数据(内存读);  

  如果涉及到group/order by,会在用户工作空间完成排序等,如果结果集过大,用户空间过小,进行磁盘排序,Sort_merge_passes>0 ,这就很影响数据库性能了。

 
三、MySQL线程及其工作
  MySQL的工作机制是单进程多线程:IO线程=一个log线程+四个read线程+四个write线程
mysql> show engine innodb status \G
--------
FILE I/O
--------
I/O thread 0 state: waiting for i/o request (insert buffer thread)
I/O thread 1 state: waiting for i/o request (log thread)
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (read thread)
I/O thread 4 state: waiting for i/o request (read thread)
I/O thread 5 state: waiting for i/o request (read thread)
I/O thread 6 state: waiting for i/o request (write thread)
I/O thread 7 state: waiting for i/o request (write thread)
I/O thread 8 state: waiting for i/o request (write thread)
I/O thread 9 state: waiting for i/o request (write thread)
1、读操作:innodb_read_io_threads
  1、发起者:用户线程发起读请求
  2、完成者:读线程执行请求队列中的读请求操作
  3、如何调整读线程的数量
mysql> show variables like 'innodb_read_io_threads';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| innodb_read_io_threads | 4 |
+------------------------+-------+
1 row in set (0.01 sec)
    默认是开启4个读线程,静态参数,修改至配置文件中
  4、如何确定是否需要增加读线程的数量
    查看线程的状态:I/O thread 2 state: waiting for i/o request (read thread)
2、写操作:innodb_write_io_threads
  1、发起者:page_cleaner线程发起
  2、完成者:写线程执行请求队列中的写请求操作
  3、如何调整写线程的数量
mysql> show variables like 'innodb_write_io_threads';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| innodb_write_io_threads | 4 |
+-------------------------+-------+
1 row in set (0.01 sec)
    默认是开启4个写线程,静态参数,修改至配置文件中
  4、如何确定是否需要增加写线程的数量
    查看线程的状态:I/O thread 6 state: waiting for i/o request (write thread)

关于innodb_purge_threads:page cleaner 线程
作用:

  1、负责对 undo 数据页的清空

  2、数据页中 delete 标志行的清除

  3、清理 innodb buffer pool,负责把内存中的脏页发起写请求,write 线程负载把脏页刷新到磁盘上。

3、日志线程
3.1、只有一个日志线程
  1、是否繁忙
    I/O thread 1 state: waiting for i/o request (log thread):闲
  2、日志写性能
mysql> show global status like 'Innodb_log_waits';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| Innodb_log_waits | 0 |
+------------------+-------+
1 row in set (0.00 sec)

    如果log buffer太小,就很容易满,导致无法写入,产生日志等待。

  3、日志写压力
    1、每秒吞吐量
mysql> show global status like 'Innodb_os_log_written';  #redo log写的字节数
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Innodb_os_log_written | 57856 |  
+-----------------------+-------+
1 row in set (0.01 sec)
    2、每秒写入次数
mysql> show global status like 'Innodb_log_writes';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Innodb_log_writes | 59 |
+-------------------+-------+
1 row in set (0.01 sec)
3.2、对于日志监控来说,三个经典参数
  1、Innodb_log_waits  #redo写入的等待次数
  2、Innodb_log_writes  #redo写入的次数
  3、Innodb_os_log_written  #写入redo logfile中的字节量
3.3、日志写入异常判断
mysql> show engine innodb status \G
Pending flushes (fsync) log: 0;
mysql> show global status like 'Innodb_os_log_pending_fsyncs';
+------------------------------+-------+
| Variable_name | Value |
+------------------------------+-------+
| Innodb_os_log_pending_fsyncs | 0 |
+------------------------------+-------+
1 row in set (0.00 sec)

  1、fsync:绕过文件系统缓存,直接将内存中的数据写入存储中,实现数据真正写入可靠的介质磁盘里。(对于redo log来说,通过fsync方式写入磁盘才是可靠的保证,因为写入文件系统缓存的提交成功响应并不是真正的将redo写入磁盘的logfile中)(sync:同步)

  2、pending:挂起(写不动),redo写入存储cache过程中,某种原因io繁忙,cache被占满,超时响应,就会被挂起;
  3、>0就说明系统IO出现问题,=0说明is OK。
 
四、log buffer调整依据
  log buffer:日志缓存,一般都很小,调整100M足够使用
mysql> show variables like "%log_buffer%";
+------------------------+----------+
| Variable_name | Value |
+------------------------+----------+
| innodb_log_buffer_size | 16777216 |
+------------------------+----------+
  5.7默认是16M,5.6默认是8M
1、文件中(log file):每次写的时候全局都写,不会挑着捡着写
  1、日志写线程每一秒redo日志缓冲刷新到重做日志文件
  2、每个事务提交时会将重做日志缓冲刷新到重做日志文件
  3、每当重做日志缓冲池剩余空间小于1/2时,重做日志缓冲刷新到重做日志文件。
2、在企业中往往设置50-100M,最多设置为2、300M,调整依据:
  1、内存空间足够大
  2、日志产生量大,系统io阻塞了,系统的io占用的是一个带宽,log_writes线程被阻塞,log buffer满了,数据库会hang住。
  3、Innodb_log_waits(状态值)
    The number of times that the log buffer was too small and a wait was required for it to be flushed before continuing.

MySQL IO线程及相关参数调优的更多相关文章

  1. mysql日常运维与参数调优

    日常运维 DBA运维工作 日常 导数据,数据修改,表结构变更 加权限,问题处理 其它 数据库选型部署,设计,监控,备份,优化等 日常运维工作: 导数据及注意事项 数据修改及注意事项 表结构变更及注意事 ...

  2. ngnix——FastCGI 相关参数调优

    当 LNMP 组合工作时,首先是用户通过浏览器输入域名请求 Nginx Web 服务,如果请求的是静态资源,则由 Nginx 解析返回给用户:如果是动态请求(如 PHP),那么 Nginx 就会把它通 ...

  3. LNMT(Linux+Nginx+MySQL+Tomcat)常见性能参数调优

  4. 【Spark调优】Shuffle原理理解与参数调优

    [生产实践经验] 生产实践中的切身体会是:影响Spark性能的大BOSS就是shuffle,抓住并解决shuffle这个主要原因,事半功倍. [Shuffle原理学习笔记] 1.未经优化的HashSh ...

  5. 看MySQL的参数调优及数据库锁实践有这一篇足够了

    史上最强MySQL参数调优及数据库锁实践 1. 应用优化 1.2 减少对MySQL的访问 1.2.1 避免对数据进行重复检索 1.2.2 增加cache层 1.3 负载均衡 1.3.1 利用MySQL ...

  6. Mysql Innodb 引擎优化-内存、日志、IO、其他相关参数

    介绍: InnoDB给MySQL提供了具有提交,回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎.InnoDB锁定在行级并且也在SELECT语句提供一个Oracle风格一致的非锁定读.这些特色增加 ...

  7. (转)linux IO 内核参数调优 之 参数调节和场景分析

    1. pdflush刷新脏数据条件 (linux IO 内核参数调优 之 原理和参数介绍)上一章节讲述了IO内核调优介个重要参数参数. 总结可知cached中的脏数据满足如下几个条件中一个或者多个的时 ...

  8. inux IO 内核参数调优 之 参数调节和场景分析

    http://backend.blog.163.com/blog/static/2022941262013112081215609/ http://blog.csdn.net/icycode/arti ...

  9. MySQL 优化之 Linux系统层面调优

    MySQL 一般运行于Linux系统中.对于MySQL的调优一般分为Linux操作系统层面的调优和MySQL层面的调优(当然还有架构层面.业务层面.应用程序层面的调优).操作系统主要是管理和分配硬件资 ...

随机推荐

  1. 2017·iOS学习资料

    我的两个想法更新了,欢迎新老司机出来槽点一下 star →[iOS·UIKit & Foundation框架-Annotations & Category注解工具类

  2. VR全景:实体店与互联网的完美结合

    VR元年已过,VR项目.VR创业潮转为理性,VR行业分为两个方向:硬件和内容.硬件又分为VR头显和辅助设备,内容又分为VR全景和VR虚拟内容,如游戏.娱乐.根据行业划分为VR+购物,VR+教育,VR+ ...

  3. 网络编程应用:基于UDP协议【实现聊天程序】--练习

    要求: 使用UDP协议实现一个聊天程序 代码: 发送端: package UDP聊天程序; import java.io.IOException; import java.net.DatagramPa ...

  4. 模板C++ 03图论算法 1最短路之单源最短路(SPFA)

    3.1最短路之单源最短路(SPFA) 松弛:常听人说松弛,一直不懂,后来明白其实就是更新某点到源点最短距离. 邻接表:表示与一个点联通的所有路. 如果从一个点沿着某条路径出发,又回到了自己,而且所经过 ...

  5. 《物联网框架ServerSuperIO教程》-19.设备驱动和OPC Client支持mysql、oracle、sqlite、sqlserver的持久化。v3.6.4版本发布

    19.设备驱动和OPC Client支持mysql.oracle.sqlite.sqlserver的持久化 19.1     概述 ServerSuperIO支持设备驱动和OPC Client采集的数 ...

  6. 两个同级div等高布局

    显示效果: css代码如下 .wrap{ overflow:hidden; } .left{ width:30%; background:#09C; } .right{ width:70%; back ...

  7. Node.js安装和配置

    今天有时间开始要研究Node.js了,项目的需要,先把环境正好,初次接触,把安装和配置过程记录下来,以备不时之需.言归正传. 1.打开NodeJS的官网,下载和自己系统相配的NodeJS的安装程序,包 ...

  8. 如何在require中使用VUE

    现在网上抄的沸沸扬扬的VUE看来是个很NB的东西啊,看了一下,确实相对于angular1来说简化了不少东西,性能方面也比angular1要好很多,所以现在用的人越来越多了,于是作为前端,学习一下新东西 ...

  9. Netty方法误解ChannelHandlerContext.writeAndFlush(Object msg)

    乍一看这个方法,以为什么消息都能输出,因为参数是Object类型的,但实际上,netty内部只支持两种类型,如图

  10. 循环执行sql语句

    DECLARE --声明变量 SQL_ALLTABLES LONG; SQL_INSERT LONG; TYPE THE_CURSOR_TYPE IS REF CURSOR; --定义引用游标的数据类 ...