zoukankan      html  css  js  c++  java
  • 了解一下Mysql的刷脏以及如何合理刷脏

     mysql数据库跑着跑着突然有那么几秒或者十几秒所有的sql都不响应,就好像是所有的表被锁住一样,但是实际上都没有加锁。但会发现数据库卡几秒,磁盘IO很高,在疯狂地读写盘,其实此时mysql正在刷脏页。

    什么是脏页?
    Innodb在更新数据时,只更新了内存的数据页,但并没有更新磁盘。看下图
    把数据页从磁盘读到内存,然后在内存里把行记录数据页修改,但mysql真实的数据并没有写回磁盘,就比如修改PPT,但没有ctrl+s,没保存,那么相当于内容在内存里,没有写回磁盘,但为什么能持久化,是因为redo log,redo log能在崩溃的时候重放内存中的数据页。假如内存没写回磁盘,内存中的数据和磁盘里的数据不一样,那么这种数据不一致的情况成为脏页。


    什么是刷脏?
    将内存中的数据页保存到磁盘,假如你修改过了ppt,按ctrl+s保存,那么就等于刷脏。mysql,刷脏的同时会删除相关的redo log。
    为什么要刷脏?

    1. 内存中的脏页太多,内存不足
    2. redo log文件写满了,不能接收数据日志更新了,写不进去所以卡住
    3. 系统空闲的时候提前刷脏,预防上述情况
    4. mysql正常关闭前,保存数据,非kill

    如何预防被迫刷脏?
    正确告知Innodb服务器的磁盘性能。因为Innodb刷脏的速度跟磁盘性能有关的,如果磁盘很垃圾,告诉innodb磁盘很垃圾,innodb会慢慢的刷,因为刷快了磁盘受不了,导致性能更差

    合理配置脏页比例上线,就好比设置内存可以设置多少脏页

    控制刷脏策略

    服务器IO配置

    配置项:innodb_io_capacity,设置跟io性能相关的配置项,用来告知服务器的硬盘性能,决定刷脏速度。
    了解一下IOPS:常见硬盘IOPS

    • 台式机笔记本相关的7200转rpm SATA 的IOPS一般在70-100多,性能好的在100多,也就是每秒多少次IO;
    • 服务器一般是10000 rpm FC的125的IOPS;
    • SSD 固态硬盘SATA,大概在3000-40000的IOPS;

    刷脏过慢的话 ,会浪费你的磁盘性能,所以要合理设置。

    在配置之前先测试一下服务器的性能,测试命令如下(服务器假如没有fio,可以yum安装)

    fio -filename=iotest_file -direct=1 -iodepth 1 -thread -rw=randrw -ioengine=psync -bs=16k -size=500M -numjobs=10 -runtime=10 -group_reporting -name=mytest

    [root@S859680 ~]# fio -filename=iotest_file -direct=1 -iodepth 1 -thread -rw=randrw -ioengine=psync -bs=16k -size=500M -numjobs=10 -runtime=10 -group_reporting -name=mytest
    mytest: (g=0): rw=randrw, bs=(R) 16.0KiB-16.0KiB, (W) 16.0KiB-16.0KiB, (T) 16.0KiB-16.0KiB, ioengine=psync, iodepth=1
    ...
    fio-3.7
    Starting 10 threads
    mytest: Laying out IO file (1 file / 500MiB)
    Jobs: 10 (f=10): [m(10)][100.0%][r=50.6MiB/s,w=50.6MiB/s][r=3239,w=3239 IOPS][eta 00m:00s]
    mytest: (groupid=0, jobs=10): err= 0: pid=17915: Mon Oct 25 15:06:45 2021
    read: IOPS=2489, BW=38.9MiB/s (40.8MB/s)(389MiB/10003msec) //读的位置
    clat (usec): min=127, max=439291, avg=1988.97, stdev=4806.49
    lat (usec): min=128, max=439292, avg=1990.94, stdev=4806.58
    clat percentiles (usec):
    | 1.00th=[ 165], 5.00th=[ 192], 10.00th=[ 215], 20.00th=[ 262],
    | 30.00th=[ 310], 40.00th=[ 367], 50.00th=[ 529], 60.00th=[ 2024],
    | 70.00th=[ 2835], 80.00th=[ 3654], 90.00th=[ 4752], 95.00th=[ 5735],
    | 99.00th=[ 8225], 99.50th=[ 10290], 99.90th=[ 28705], 99.95th=[ 64226],
    | 99.99th=[208667]
    bw ( KiB/s): min= 95, max= 6336, per=10.00%, avg=3982.64, stdev=1188.00, samples=199
    iops : min= 5, max= 396, avg=248.87, stdev=74.28, samples=199 //注意这里,这里是要设置到参数里的,平均大概250
    write: IOPS=2508, BW=39.2MiB/s (41.1MB/s)(392MiB/10003msec) //写的位置
    clat (usec): min=116, max=232175, avg=1972.94, stdev=5096.18
    lat (usec): min=118, max=232177, avg=1975.68, stdev=5096.29
    clat percentiles (usec):
    | 1.00th=[ 155], 5.00th=[ 178], 10.00th=[ 196], 20.00th=[ 241],
    | 30.00th=[ 289], 40.00th=[ 338], 50.00th=[ 441], 60.00th=[ 1975],
    | 70.00th=[ 2769], 80.00th=[ 3621], 90.00th=[ 4752], 95.00th=[ 5669],
    | 99.00th=[ 8029], 99.50th=[ 10421], 99.90th=[ 29230], 99.95th=[ 70779],
    | 99.99th=[221250]
    bw ( KiB/s): min= 32, max= 6784, per=9.99%, avg=4011.59, stdev=1223.41, samples=199
    iops : min= 2, max= 424, avg=250.68, stdev=76.50, samples=199 //注意这里,这里是要设置到参数里的,平均大概250,
    lat (usec) : 250=19.76%, 500=30.61%, 750=2.38%, 1000=0.73%
    lat (msec) : 2=6.52%, 4=23.75%, 10=15.71%, 20=0.40%, 50=0.06%
    lat (msec) : 100=0.03%, 250=0.04%, 500=0.01%
    cpu : usr=0.88%, sys=4.68%, ctx=91997, majf=0, minf=13
    IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
    submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
    complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
    issued rwts: total=24904,25095,0,0 short=0,0,0,0 dropped=0,0,0,0
    latency : target=0, window=0, percentile=100.00%, depth=1

    Run status group 0 (all jobs):
    READ: bw=38.9MiB/s (40.8MB/s), 38.9MiB/s-38.9MiB/s (40.8MB/s-40.8MB/s), io=389MiB (408MB), run=10003-10003msec
    WRITE: bw=39.2MiB/s (41.1MB/s), 39.2MiB/s-39.2MiB/s (41.1MB/s-41.1MB/s), io=392MiB (411MB), run=10003-10003msec

    Disk stats (read/write):
    vda: ios=25084/25090, merge=1/10, ticks=16025/6698, in_queue=21191, util=85.33%


    综合来看读写平均大概250,那么设置250就好了

    配置合理的脏页比例上限

    配置项:innodb_max_dirty_pages_pct
    也就是说,磁盘里的页的数量和内存中脏页的数量比值,不能太高也不能太低。就好比我磁盘里有100个PPT,内存中打开了50个,假如设置了50%,内存中打开了50个PPT,假如你再打开一个,它会强制你把前面一些PPT保存并关掉,要不然脏页比例太多,如果突然有一个大请求,就没法搞了。当脏页比例接近此值的时候,会加速刷脏页,假如默认值是75,如果接近75%那么会把之前的脏页给保存到硬盘就可以达到提前刷脏的目的,不会在高峰期突然来的时候搞得很狼狈

    控制”顺便刷脏“策略
    配置项:innodb_flush_neighbors(SSD要关掉,不然会影响SSD的随机刷脏策略)
    传统的机械磁盘连续写型能最好,尽量刷连续的页
    SSD建议设置为0(8.0默认是0)

  • 相关阅读:
    Java IO输入输出流 FileWriter 字符流
    Java IO输入输出流File 字节流
    Java List集合和Map集合的综合应用
    表单提交中的重复问题(表单令牌验证)
    php中const与define的区别
    阿里云中获取文件及目录列表的方法
    巧用php中的array_filter()函数去掉多维空值
    文件大小格式化函数
    UTC 通用格式时间 转换为 时间戳,并格式化为2017-01-01 12:00:00
    关于匿名函数的使用,购物车中计算销售税的应用
  • 原文地址:https://www.cnblogs.com/wt645631686/p/9745254.html
Copyright © 2011-2022 走看看