fio模拟mysql写入速度_优化innochecksum实战,四倍加速榨干NVMe SSD磁盘带宽

innodhecksum[1]是MySQL自带的offline工具bin,可检查innodb数据文件是否损坏。使用方式如下。

shell> bin/innochecksum [options] file_name

MySQL的系统表空间(ibdata)、用户表空间(*.ibd)、redo log(ib_logfile)等文件,结构类似,都由page构成,UNIV_PAGE_SIZE默认16KB,定义如下。了解更多可参考文章[2]或者innodb-java-reader工具[3]。

#define UNIV_PAGE_SIZE (2 * 8192)

如下图所示,page前后是38字节的header和8字节的trailer。checksum校验算法会利用index4-26以及index38-16376这两部分计算。详细实现参考ut0crc32.cc[4]。图片一部分参考链接[5]

page的checksum算法有三种,参考官方文档[6]。

innodb

crc32

none

从MySQL 5.7.7版本之后crc32是默认的checksum算法。

crc32的校验算法有两种实现,如果CPU支持SIMD SSE4_2指令集,则硬件加速,直接inline汇编代码;如果不支持,fallback到软件算法实现。

innochecksum执行的逻辑很简单。

while (!feof(fil_in)) {

bytes = read_file //read 16KB

is_page_corrupted //using crc32/innodb/none algorithm

}

优化innochecksum前,先看看基准性能如何。环境如下。CPU: Intel Xeon CPU E5-2682 v4 @ 2.50GHz(开启超线程,逻辑核数64)

内存: 256G

NVMe SSD硬盘:PCIe 3.0 x4, NVMe, Intel® SSD DC P3600 Series, 1.6TB

背面图如下,可以看到排列整齐的MLC NAND闪存颗粒[8]。

规格如下。官方资料,顺序写1600 MB/s,顺序读2600 MB/s。

测试数据文件是TPC-H的LINEITEM,大小有72G左右。(dbgen -s 70生成后导入MySQL,文件较大,为了更好的观测)。

直接上图,MySQL自带的bin执行innochecksum -C crc32 file_name,带宽只有642 MB/s,远低于这块盘的顺序读吞吐限。

优化后的最优版本可以达到2503 MB/s,非常接近官方最高吞吐。

下面第一部分 测试NVMe SSD读写极限吞吐,第二部分 阐述优化实现方案。

1. 测试NVMe SSD读写极限吞吐

fio[9]测试读写吞吐,ioengine选择libaio。

fio写:

./fio --filename=test -iodepth=16 -ioengine=libaio -direct=1 -rw=write -bs=1m -size=512g -numjobs=8 -runtime=50 -group_reporting -name=test-write

write: bw=1543.2MB/s, iops=1543

fio读:

./fio --filename=test -iodepth=16 -ioengine=libaio -direct=1 -rw=read -bs=2m -size=512g -numjobs=8 -runtime=50 -group_reporting -name=test-read

read : bw=2382.8MB/s, iops=2382

测试结果基本符合官方的数据,但都差一些,所以手写代码再压测下,部分代码参考文章[10]。源码链接如下。https://github.com/neoremind/io_benchmark​github.com

测试buffer io write-back写,代码如下。

#include

#include

#include

#i

#!/bin/bash CPWD=$(cd $(dirname $0);pwd) cd $CPWD rm -f ssd_symbol_set hdd_symbol_set nvme_symbol_set filter_ssd_hdd_nvme_set() { rm -f ssd_symbol_set hdd_symbol_set nvme_symbol_set os_disk_symbol=$(echo $(lsblk |grep -B1 -E "part|boot" |grep -E "^sd[a-z]+|^nvme" |awk '{print $1}') |sed 's/ /|/') non_os_disk_set=$(lsscsi -g |-E "ATA|TOSHIBA" |awk '{print $(NF-1)}' |grep -Ev $os_disk_symbol) if [[ -n $non_os_disk_set ]];then for i in $(echo "$non_os_disk_set") do rotationRate=$(smartctl -i $i |awk -F":" '/Rotation Rate/{print $2}') if [[ $rotationRate =~ "Solid State Device" ]];then echo $i |awk -F"/" '{print $3}' >> ssd_symbol_set elif [[ $rotationRate =~ "rpm" ]];then echo $i |awk -F"/" '{print $3}' >> hdd_symbol_set fi done fi nvme_info_set=$(nvme list |grep -E "nvme[0-9]+n1") if [[ -n $nvme_info_set ]];then echo "$nvme_info_set" |awk '{print $1}' |awk -F"/" '{print $3}' > nvme_symbol_set fi } hdd_parallel_fio_test() { # multi hdd fio test if [ -s hdd_symbol_set ];then for dev in $(cat hdd_symbol_set) do nohup &>/dev/null bash hdd_raw_fio_test.sh $dev & done wait mkdir -p $CPWD/hdd_fio_log mv hdd_sd*_*.log $CPWD/hdd_fio_log fi } ssd_parallel_fio_test() { # multi sata ssd fio test if [ -s ssd_symbol_set ];then for dev in $(cat ssd_symbol_set) do nohup &>/dev/null bash ssd_raw_fio_test.sh $dev & done wait mkdir -p $CPWD/ssd_fio_log mv ssd_sd*_*.log $CPWD/ssd_fio_log fi } nvme_parallel_fio_test() { # multi nvme ssd fio test if [ -s nvme_symbol_set ];then for dev in $(cat nvme_symbol_set) do nohup &>/dev/null bash ssd_raw_fio_test.sh $dev & done wait mkdir -p $CPWD/nvme_fio_log mv ssd_nvme*_*.log $CPWD/nvme_fio_log fi } filter_ssd_hdd_nvme_set #hdd_parallel_fio_test #ssd_parallel_fio_test nvme_parallel_fio_test
06-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值