登录
转载

MYSQL 压力测试及参数调优

发布于 2021-05-06 阅读 353
  • 数据库
  • SQL
转载

实验环境:

mysql5.7 

CentOS Linux release 7.3.1611 (Core)

4核8G资源

目的:主要使用python代码测试一下mysql压力以及参数调优

可以开启mysql通用日志用来调试查询sql

查看是否开启通用日志

show variables like ‘%general%’; 

临时生效

开启通用日志查询: set global general_log=on;

关闭通用日志查询: set globalgeneral_log=off;

设置通用日志输出为表方式: set globallog_output=’TABLE’;

设置通用日志输出为文件方式: set globallog_output=’FILE’;

设置通用日志输出为表和文件方式:set global log_output=’FILE,TABLE’;


永久生效

my.cnf文件的配置如下:

general_log=1  #为1表示开启通用日志查询,值为0表示关闭通用日志查询

log_output=FILE,TABLE#设置通用日志的输出格式为文件和表,FILE(存储在数数据库的数据文件中的hostname.log),TABLE(存储在数据库中的mysql.general_log)

 

先描述一下 EXPLAIN 优化工具

EXPLAIN  后面跟sql语句  如图

字段解析

1. id //select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序 2. select_type //查询类型 3. table //正在访问哪个表 4. partitions //匹配的分区 5. type //访问的类型 6. possible_keys //显示可能应用在这张表中的索引,一个或多个,但不一定实际使用到 7. key //实际使用到的索引,如果为NULL,则没有使用索引 8. key_len //表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度 9. ref //显示索引的哪一列被使用了,如果可能的话,是一个常数,哪些列或常量被用于查找索引列上的值 10. rows //根据表统计信息及索引选用情况,大致估算出找到所需的记录所需读取的行数 11. filtered //查询的表行占表的百分比 12. Extra //包含不适合在其它列中显示但十分重要的额外信息

图片详解:  

 

 

数据结构:

CREATE TABLE `student_data` (   `student_id` int(11) NOT NULL AUTO_INCREMENT,   `student_name` varchar(10) DEFAULT NULL,   `student_age` tinyint(4) DEFAULT NULL,   `student_class` varchar(40) DEFAULT NULL,   `subject` varchar(40) DEFAULT NULL,   `score` tinyint(4) DEFAULT NULL,   PRIMARY KEY (`student_id`),   KEY `s_name` (`student_name`) ) ENGINE=InnoDB AUTO_INCREMENT=2063942 DEFAULT CHARSET=utf8;


CREATE TABLE `student_info` (   `student_id` int(11) DEFAULT NULL,   `grade` int(11) DEFAULT NULL,   `addr` varchar(100) DEFAULT NULL,   `phone` varchar(11) DEFAULT NULL,   `patriarch_phone` varchar(11) DEFAULT NULL,   `teacher_id` int(11) DEFAULT NULL,   KEY `sid` (`student_id`),   KEY `tid` (`teacher_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `teacher_by_class` (   `teacher_id` tinyint(4) DEFAULT NULL,   `class_id` tinyint(4) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `teacheres` (   `teacher_id` int(11) NOT NULL AUTO_INCREMENT,   `teacher_name` varchar(40) DEFAULT NULL,   `teacher_subject_id` varchar(40) DEFAULT NULL,   `teacher_phone` varchar(11) DEFAULT NULL,   `if_head_teacher` enum('1','0') DEFAULT '0',   PRIMARY KEY (`teacher_id`) ) ENGINE=InnoDB AUTO_INCREMENT=200001 DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `class_name_zh`; CREATE TABLE `class_name_zh` (   `class_id` tinyint(4) DEFAULT NULL,   `class_name_zh` varchar(40) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `class_name_zh` VALUES ('1', '一班'); INSERT INTO `class_name_zh` VALUES ('2', '二班'); INSERT INTO `class_name_zh` VALUES ('3', '三班'); INSERT INTO `class_name_zh` VALUES ('4', '四班');

 

 

压测工具

执行一次测试,分别50和100个并发,执行10w次总查询

mysqlslap -a --concurrency=50,100 --number-of-queries 100000 -uroot -p123

我这里使用50并发发送请求会导致CPU占满,而内存使用20%

当出现连接异常或者CPU,内存资源占满时应该调整参数  

 使用python代码连接压测

import pymysql
import sys
import random
import threading


class MysqlCustom():
    def __init__(self,db_name):
        self.db = pymysql.connect(host="127.0.0.1", user="test",passwd="test123", db=db_name)
        self.cursor = self.db.cursor()

    def select(self,sql):
        try:
            self.db.ping(reconnect=True)
            self.cursor.execute(sql)
            result = self.cursor.fetchall()
            if sys.version_info[0] == 2:
                result = map(list, result)
            else:
                result = list(map(list, result))
            print(result)
        except Exception as e:
            print(str(e))
    def insert(self,cus_sql):
        row=0
        try:
            self.db.ping(reconnect=True)
            self.cursor.execute(cus_sql)
            row = self.cursor.rowcount
            self.db.commit()
        except Exception as e:
            row = "插入数据错误" +str(e)
        return row
    def close(self):
        self.cursor.close()
        self.db.close()


def tasks():
    db_obj = MysqlCustom("Stress")
    for i in range(1000):
        i = random.randrange(20,80)
        j = random.randrange(30,99)
        class_id = random.choice([1,2,3,4])
        db_obj.select('''select * from student_data where score BETWEEN %s and %s  and student_class = %s limit 5'''%(i,j,class_id))
    db_obj.close()

if __name__ == "__main__":
    thread_list = []
    for i in range(4):
        p = threading.Thread(target=tasks)
        thread_list.append(p)
    for thread in thread_list:
        thread.setDaemon(True)
        thread.start()
    for thread in thread_list:
        thread.join()



默认使用4个线程去测试,未添加索引score时,每个查询都会使用1s左右,会把cpu占满,此时qps为20左右,添加索引后,每个查询都是0.01s,无占用cpu

初步判断 当有慢查询时,即使并发不高的情况,也会导致cpu爆满

mysql参数配置

2-4G  内存  建议

[mysqld] binlog_cache_size = 64K thread_stack = 256K join_buffer_size = 2048K read_rnd_buffer_size = 512K read_buffer_size = 768K sort_buffer_size = 768K thread_cache_size = 96 table_open_cache = 192 query_cache_type = 1 max_connections = 200 innodb_log_buffer_size = 32M innodb_buffer_pool_size = 384M max_heap_table_size = 384M tmp_table_size = 384M query_cache_size = 128M

4-8G  内存  建议

[mysqld] binlog_cache_size = 128K thread_stack = 256K join_buffer_size = 2048K read_rnd_buffer_size = 768K read_buffer_size = 1024K sort_buffer_size = 1024K thread_cache_size = 128 table_open_cache = 384 query_cache_type = 1 max_connections = 300 innodb_log_buffer_size = 32M innodb_buffer_pool_size = 512M max_heap_table_size = 512M tmp_table_size = 512M query_cache_size = 192M

8-16G  内存  建议

[mysqld] binlog_cache_size = 192K thread_stack = 384K join_buffer_size = 4096K read_rnd_buffer_size = 1024K read_buffer_size = 2048K sort_buffer_size = 2048K thread_cache_size = 192 table_open_cache = 1024 query_cache_type = 1 max_connections = 400 innodb_log_buffer_size = 32M innodb_buffer_pool_size = 1024M max_heap_table_size = 1024M tmp_table_size = 1024M query_cache_size = 256M

16-32G 内存建议

[mysqld] binlog_cache_size = 256K thread_stack = 512K join_buffer_size = 8192K read_rnd_buffer_size = 2048K read_buffer_size = 4096K sort_buffer_size = 4096K thread_cache_size = 256 table_open_cache = 2048 query_cache_type = 1 max_connections = 500 innodb_log_buffer_size = 32M innodb_buffer_pool_size = 4096M max_heap_table_size = 2048M tmp_table_size = 2048M query_cache_size = 384M

 

 

评论区

励志做一条安静的咸鱼,从此走上人生巅峰。

0

0

0

举报