Day815.数据库参数设置优化 -Java 性能调优实战

news2024/11/25 14:46:48

数据库参数设置优化

Hi,我是阿昌,今天学习记录的是关于数据库参数设置优化

MySQL 是一个灵活性比较强的数据库系统,提供了很多可配置参数,便于根据应用和服务器硬件来做定制化数据库服务。

数据库主要是用来存取数据的,而存取数据涉及到了磁盘 I/O 的读写操作,所以数据库系统主要的性能瓶颈就是 I/O 读写的瓶颈了。

MySQL 数据库为了减少磁盘 I/O 的读写操作,应用了大量内存管理来优化数据库操作,包括内存优化查询、排序以及写入操作。

把内存设置得越大越好,数据刷新到磁盘越快越好,不就对了吗?

其实不然,内存设置过大,同样会带来新的问题。

例如,InnoDB 中的数据和索引缓存,如果设置过大,就会引发 SWAP 页交换

还有数据写入到磁盘也不是越快越好,期望的是在高并发时,数据能均匀地写入到磁盘中,从而避免 I/O 性能瓶颈

SWAP 页交换:SWAP 分区在系统的物理内存不够用的时候,就会把物理内存中的一部分空间释放出来,以供当前运行的程序使用。被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间的数据被临时保存到 SWAP 分区中,等到那些程序要运行时,再从 SWAP 分区中恢复保存的数据到内存中。

所以,这些参数的设置跟的应用服务特性以及服务器硬件有很大的关系。

MySQL 是一个高定制化的数据库,可以根据需求来调整参数,定制性能最优的数据库。


一、MySQL 体系结构

一般可以将 MySQL 的结构分为四层

  • 最上层为客户端连接器,主要包括了数据库连接、授权认证、安全管理等,该层引用了线程池,为接入的连接请求提高线程处理效率。
  • 第二层是 Server 层,主要实现 SQL 的一些基础功能,包括 SQL 解析、优化、执行以及缓存等,其中与这一讲主要相关的就是缓存。
  • 第三层包括了各种存储引擎,主要负责数据的存取,这一层涉及到的 Buffer 缓存,也和这一讲密切相关。
  • 最下面一层是数据存储层,主要负责将数据存储在文件系统中,并完成与存储引擎的交互。

在这里插入图片描述

1、查询语句

一个应用服务需要通过第一层的连接和授权认证,再将 SQL 请求发送至 SQL 接口。

SQL 接口接收到请求之后,会先检查查询 SQL 是否命中 Cache 缓存中的数据,如果命中,则直接返回缓存中的结果;

否则,需要进入解析器

解析器主要对 SQL 进行语法以及词法分析,之后,便会进入到优化器中,优化器会生成多种执行计划方案,并选择最优方案执行。

确定了最优执行计划方案之后,执行器会检查连接用户是否有该表的执行权限,有则查看 Buffer 中是否存在该缓存,存在则获取锁,查询表数据;

否则重新打开表文件,通过接口调用相应的存储引擎处理,这时存储引擎就会进入到存储文件系统中获取相应的数据,并返回结果集。

2、更新语句

数据库更新 SQL 的执行流程其实跟查询 SQL 差不多,只不过执行更新操作的时候多了记录日志的步骤。

在执行更新操作时 MySQL 会将操作的日志记录到 binlog(归档日志)中,这个步骤所有的存储引擎都有。

InnoDB 除了要记录 binlog 之外,还需要多记录一个 redo log(重做日志)。

redo log 主要是为了解决 crash-safe 问题而引入的。

当数据库在存储数据时发生异常重启,需要保证存储的数据要么存储成功,要么存储失败,也就是不会出现数据丢失的情况,这就是 crash-safe 了。

在执行更新操作时,首先会查询相关的数据,之后通过执行器执行更新操作,并将执行结果写入到内存中,同时记录更新操作到 redo log 的缓存中,此时 redo log 中的记录状态为 prepare,并通知执行器更新完成,随时可以提交事务。

执行器收到通知后会执行 binlog 的写入操作,此时的 binlog 是记录在缓存中的,写入成功后会调用引擎的提交事务接口,更新记录状态为 commit。

之后,内存中的 redo log 以及 binlog 都会刷新到磁盘文件中。


二、内存调优

基于以上两个 SQL 执行过程,可以发现,在执行查询 SQL 语句时,会涉及到两个缓存。

第一个缓存是刚进来时的 Query Cache,它缓存的是 SQL 语句和对应的结果集。

这里的缓存是以查询 SQL 的 Hash 值为 key,返回结果集为 value 的键值对,判断一条 SQL 是否命中缓存,是通过匹配查询 SQL 的 Hash 值来实现的。

很明显,Query Cache 可以优化查询 SQL 语句,减少大量工作,特别是减少了 I/O 读取操作。

可以通过以下几个主要的设置参数来优化查询操作:

在这里插入图片描述

可以通过设置合适的 query_cache_min_res_unit 来减少碎片,这个参数最合适的大小和应用程序查询结果的平均大小直接相关,可以通过以下公式计算所得:

(query_cache_size - Qcache_free_memory)/ Qcache_queries_in_cache

Qcache_free_memory 和 Qcache_queries_in_cache 的值可以通过以下命令查询:

show status like 'Qcache%'

Query Cache 虽然可以优化查询操作,但也仅限于不常修改的数据,如果一张表数据经常进行新增、更新和删除操作,则会造成 Query Cache 的失效率非常高,从而导致频繁地清除 Cache 中的数据,给系统增加额外的性能开销。

这也会导致缓存命中率非常低,我们可以通过以上查询状态的命令查看 Qcache_hits,该值表示缓存命中率。

如果缓存命中率特别低的话,还可以通过 query_cache_size = 0 或者 query_cache_type来关闭查询缓存。

经过了 Query Cache 缓存之后,还会使用到存储引擎中的 Buffer 缓存。

不同的存储引擎,使用的 Buffer 也是不一样的。

1、MyISAM 存储引擎参数设置调优

MyISAM 存储引擎使用 key buffer 缓存索引块,MyISAM 表的数据块则没有缓存,它是直接存储在磁盘文件中的。

可以通过 key_buffer_size 设置 key buffer 缓存的大小,而它的大小并不是越大越好。

正如我前面所讲的,key buffer 缓存设置过大,实际应用却不大的话,就容易造成内存浪费,而且系统也容易发生 SWAP 页交换,一般我是建议将服务器内存中可用内存的 1/4 分配给 key buffer。

如果要更准确地评估 key buffer 的设置是否合理,我们还可以通过缓存使用率公式来计算:

1-((key_blocks_unused*key_cache_block_size)/key_buffer_size)

key_blocks_unused 表示未使用的缓存簇(blocks)数
key_cache_block_size 表示 key_buffer_size 被分割的区域大小
key_blocks_unused*key_cache_block_size 则表示剩余的可用缓存空间(一般来说,缓存使用率在 80% 作用比较合适)。

2、InnoDB 存储引擎参数设置调优

InnoDB Buffer Pool(简称 IBP)是 InnoDB 存储引擎的一个缓冲池,与 MyISAM 存储引擎使用 key buffer 缓存不同,它不仅存储了表索引块,还存储了表数据。

查询数据时,IBP 允许快速返回频繁访问的数据,而无需访问磁盘文件。

InnoDB 表空间缓存越多,MySQL 访问物理磁盘的频率就越低,这表示查询响应时间更快,系统的整体性能也有所提高。

一般可以通过多个设置参数来调整 IBP,优化 InnoDB 表性能。

innodb_buffer_pool_size

IBP 默认的内存大小是 128M,可以通过参数 innodb_buffer_pool_size 来设置 IBP 的大小,IBP 设置得越大,InnoDB 表性能就越好。

将 IBP 大小设置得过大也不好,可能会导致系统发生 SWAP 页交换。

所以需要在 IBP 大小和其它系统服务所需内存大小之间取得平衡。

MySQL 推荐配置 IBP 的大小为服务器物理内存的 80%。

也可以通过计算 InnoDB 缓冲池的命中率来调整 IBP 大小:

(1-innodb_buffer_pool_reads/innodb_buffer_pool_read_request)*100

但如果将 IBP 的大小设置为物理内存的 80% 以后,发现命中率还是很低,此时就应该考虑扩充内存来增加 IBP 的大小。

innodb_buffer_pool_instances

InnoDB 中的 IBP 缓冲池被划分为了多个实例,对于具有数千兆字节的缓冲池的系统来说,将缓冲池划分为单独的实例可以减少不同线程读取和写入缓存页面时的争用,从而提高系统的并发性。

该参数项仅在将 innodb_buffer_pool_size 设置为 1GB 或更大时才会生效。

在 windows 32 位操作系统中,如果 innodb_buffer_pool_size 的大小超过 1.3GB,innodb_buffer_pool_instances 默认大小就为 innodb_buffer_pool_size/128MB;否则,默认为 1。

在其它操作系统中,如果 innodb_buffer_pool_size 大小超过 1GB,innodb_buffer_pool_instances 值就默认为 8;

否则,默认为 1。为了获取最佳效率,建议指定 innodb_buffer_pool_instances 的大小,并保证每个缓冲池实例至少有 1GB 内存。

通常,建议 innodb_buffer_pool_instances 的大小不超过 innodb_read_io_threads + innodb_write_io_threads 之和,建议实例和线程数量比例为 1:1。

innodb_read_io_threads / innodb_write_io_threads

在默认情况下,MySQL 后台线程包括了主线程、IO 线程、锁线程以及监控线程等,其中读写线程属于 IO 线程,主要负责数据库的读取和写入操作,这些线程分别读取和写入 innodb_buffer_pool_instances 创建的各个内存页面。

MySQL 支持配置多个读写线程,即通过 innodb_read_io_threads 和 innodb_write_io_threads 设置读写线程数量。读写线程数量值默认为 4,也就是总共有 8 个线程同时在后台运行。

innodb_read_io_threads 和 innodb_write_io_threads 设置的读写线程数量,与 innodb_buffer_pool_instances 的大小有关,两者的协同优化是提高系统性能的一个关键因素。

在一些内存以及 CPU 内核超大型的数据库服务器上,可以在保证足够大的 IBP 内存的前提下,通过以下公式,协同增加缓存实例数量以及读写线程。

( innodb_read_io_threads + innodb_write_io_threads ) = innodb_buffe_pool_instances

如果仅仅是将读写线程根据缓存实例数量对半来分,即读线程和写线程各为实例大小的一半,肯定是不合理的。

例如应用服务读取数据库的数据多于写入数据库的数据,那么增加写入线程反而没有优化效果。

一般可以通过 MySQL 服务器保存的全局统计信息,来确定系统的读取和写入比率。

可以通过以下查询来确定读写比率:

SHOW GLOBAL STATUS LIKE 'Com_select';//读取数量
SHOW GLOBAL STATUS WHERE Variable_name IN ('Com_insert', 'Com_update', 'Com_replace', 'Com_delete');//写入数量

如果读大于写,应该考虑将读线程的数量设置得大一些,写线程数量小一些;否则,反之。

innodb_log_file_size

除了以上 InnoDB 缓存等因素之外,InnoDB 的日志缓存大小、日志文件大小以及日志文件持久化到磁盘的策略都影响着 InnnoDB 的性能。

InnoDB 中有一个 redo log 文件,InnoDB 用它来存储服务器处理的每个写请求的重做活动。执行的每个写入查询都会在日志文件中获得重做条目,以便在发生崩溃时可以恢复更改。

当日志文件大小已经超过我们参数设置的日志文件大小时,InnoDB 会自动切换到另外一个日志文件,由于重做日志是一个循环使用的环,在切换时,就需要将新的日志文件脏页的缓存数据刷新到磁盘中(触发检查点)。

理论上来说,innodb_log_file_size 设置得越大,缓冲池中需要的检查点刷新活动就越少,从而节省磁盘 I/O。

那是不是将这个日志文件设置得越大越好呢?

如果日志文件设置得太大,恢复时间就会变长,这样不便于 DBA 管理。

在大多数情况下,将日志文件大小设置为 1GB 就足够了。

innodb_log_buffer_size

这个参数决定了 InnoDB 重做日志缓冲池的大小,默认值为 8MB。

如果高并发中存在大量的事务,该值设置得太小,就会增加写入磁盘的 I/O 操作。

可以通过增大该参数来减少写入磁盘操作,从而提高并发时的事务性能。

innodb_flush_log_at_trx_commit

这个参数可以控制重做日志从缓存写入文件刷新到磁盘中的策略,默认值为 1。

当设置该参数为 0 时,InnoDB 每秒种就会触发一次缓存日志写入到文件中并刷新到磁盘的操作,这有可能在数据库崩溃后,丢失 1s 的数据。当设置该参数为 1 时,则表示每次事务的 redo log 都会直接持久化到磁盘中,这样可以保证 MySQL 异常重启之后数据不会丢失。

当设置该参数为 2 时,每次事务的 redo log 都会直接写入到文件中,再将文件刷新到磁盘。在一些对数据安全性要求比较高的场景中,显然该值需要设置为 1;

在一些可以容忍数据库崩溃时丢失 1s 数据的场景中,可以将该值设置为 0 或 2,这样可以明显地减少日志同步到磁盘的 I/O 操作。


三、总结

MySQL 并发的相关参数设置,总结如下:

在这里插入图片描述

InnoDB 的 IBP 的内存大小是有限的, InnoDB 是如何将热点数据留在内存中,淘汰非热点数据的吗?

通过在内存中维护一个链表,并使用LRU(最近最少使用)算法淘汰非热点数据

MySQL基于LRU算法来实现淘汰非热点数据,但与熟悉的LRU算法不同的是,MySQL新增了一个midpoint insertion startegy策略,就是默认情况下,读取到的新页并不是直接放入的LRU列表的首部,而是LRU列表长度的5/8处,目的是为了避免由于一些不常查询SQL偶尔一次查询就把之前热点数据淘汰的情况。

mysql的缓冲池(buffer_pool)使用改进版的lru算法来缓存数据,如果使用传统的lru算法,会存在预读失效和缓冲池污染的问题,为了解决预读失效问题,mysql将lru分为新生代和老生代,为了解决缓冲池污染的问题,引入老生代停留时间窗口,只有大于设置的值,才能加入新生代头部

InnoDB 的缓存淘汰策略是分代的,分为老年代和新生代,大致是7:3,新数据总是先加入到新生代,如果在一定时间内有被再次查询,才会进入到老年代。老年代和新生代内部都是LRU算法来淘汰缓存页的。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/46987.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

视频编解码 — DCT变换和量化

目录 视频编码流程 DCT变换 Hadamard变换 量化 H264中的DCT变换和量化 H264各模式的DCT变换和量化过程 1、亮度16x16帧内预测块 2,其它模式亮度块 3,色度块 小结 视频编码流程 DCT变换 离散余弦变换 它能将空域信号转换到频率上表示&#xff0…

建造者模式

文章目录定义优点使用场景代码实现定义 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 4个角色: Product产品类:通常是实现了模板方法模式,也就是有模板方法和基本方法Builder抽象建造者&#xf…

PyQt5可视化编程-事件、信号和对话框

一、概述: 所有的应用都是事件驱动的。事件大部分都是由用户的行为产生的,当然也有其他的事件产生方式,比如网络的连接,窗口管理器或者定时器等。调用应用的exec_()方法时,应用会进入主循环,主循环会监听和分发事件。…

算法题:整数除法

一.题目描述以及来源 给定两个整数 a 和 b ,求它们的除法的商 a/b ,要求不得使用乘号 *、除号 / 以及求余符号 % 。 注意: 整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345…

MP157-2-TF-A移植:

MP157-2-TF-A移植:1. TF-A移植:1.1 新建开发板的设备树1.2 修改设备树电源管理1.3修改TF卡和EMMC设备树1.4 修改USBOTG设备树2 编译测试2.1 Makefile.sdk 修改内容:2.2 编译命令:正点原子第九章内容:自己记的笔记&…

SpringBoot(One·上)

SpringBoot一、简介概述Spring Boot特性SpringBoot四大核心二、SpringBoot项目分析1、创建第一个案例结构目录和pom文件2、Springboot集成mvcSpringboot核心配置文件application.propertiesSpringboot核心配置文件application.yml或者application.yamlapplication.ymlapplicati…

Allegro削铜皮详细操作指导

Allegro削铜皮详细操作指导 Allegro可以编辑任意形状的铜皮,下面介绍几种削铜皮的方式 任意形状,shape-manual Void/cavity-Polygon 鼠标左键点击铜皮,铜皮会被亮起来 画出需要的形状 完成后如下图 方形shape-manual Void/cavity-Rectangular 同样的选择铜皮,画出需要…

通过 js 给元素添加动画样式animation属性 ,以及 perspective 属性探究

学习关键语句: js添加动画效果 js控制元素animation属性 写在前面 在制作组件的过程中呢 , 突然觉得这个动画啊应该由用户来决定到底是个啥样 , 但是怎么让用户操作这一步呢 ? 总不能让用户自己去写 css keyframe 吧 , 所以便有了这篇文章 , 同时 , 这篇文章的下半部分我们会…

Python+Selenium:Google patent数据爬取

准备工作,已搭建Python环境,安装Selenium pip install selenium -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com 步骤1: 根据Chrome版本下载ChromeDriver 下载链接地址: ChromeDriver - WebDriver for Chrome - Downloads 如在帮助——>关于Ch…

车道线检测-lanedet

源码:https://github.com/Turoad/lanedet 这是一个常见的检测网络整合版本,目前包括的检测网络有: 模型论文介绍 SCNN,RESA论文介绍,UFLD介绍,laneNet|其它相关模型,LaneATT介绍 数据集介绍…

机器学习之归一化

机器学习之归一化1.目的1.1损失函数求解问题1.2 归一化目的2. 归一化2.1 最大值最小值归一化2.2 标准化1.目的 1.1损失函数求解问题 线性回归Loss函数梯度公式 参数含义θ\thetaθ函数参数α\alphaα学习率xjix^i_{j}xji​x:数据集,i:样本,j:特征 【数…

OPengl学习(二)——opengl环境搭建

文章目录0、 概念/准备1、VSOpengl快速添加手动编译2、QT中使用opengl1.pro配置文件2.引入头文件 继承QGLWidget3.实现三个主要函数3、引用0、 概念/准备 opengl官网地址 1、OpenGL 函数库相关的 API 有核心库(gl),实用库(glu&a…

自动化状态监测和工业4.0解决方案-Softing uaGate SI

某公司为其注塑和反应/挤出系统采用了uaGate SI网关技术并实行了开放且独立于平台的OPC UA标准,以用于设备状态自动化监控,这有助于提高产量并避免机器停机。 自动化状态监测提高了产量并且可避免机器停机。为了将其设备控制系统与IT系统相连接起来&…

最小生成树(Prim算法与Kruskal算法)

一、什么是最小生成树 一个连通图的生成树是一个极小的连通子图,它含有图中全部的n个顶点,但只有足以构成一棵树的n-1条边。我们把构造连通网的最小代价生成树称为最小生成树。 例如下图中①、②、③都是左侧图的生成树,但③是构…

k8s的亲和调度

k8s的亲和调度 出于高效通信等需求,偶尔需要把一些Pod对象组织在相近的位置(同一节点、机架、区域或地区等),例如应用程序的Pod及其后端提供数据服务的Pod等,我们可以认为这是一类具有亲和关系的Pod对象。 理想的实现方式是允许调度器把第一个…

[附源码]计算机毕业设计springboot高校流浪动物领养网站

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

2022.11.28总结

今天写了条件查询 虽然思路上还说是比较顺,但是还是写了一晚上,因为老是在细节上出现bug,改了好久,踩了好几个坑。 首先大概是因为组件不是确定的,我把ref属性绑定在router-view上,导致我获取不到条件选择…

c++类型转换

目录 1.隐式类型转换和强制类型转换 2.隐式类型转换带来的危险 3.c提供的标准类型转换关键字 4.总结 1.隐式类型转换和强制类型转换 c语言的类型转换可以分为隐式类型转换和强制类型转换。 #include<iostream>using namespace std;int main() {double a 3.14;int …

医疗保健行业的福音是对话式AI吗?

导读对话式AI可以对医疗保健行业产生重大影响&#xff0c;且在许多领域已经产生了影响。如果使用得当&#xff0c;对话式AI可以提高操作效率和临床结果&#xff0c;并减轻医护人员的工作量。 对话式AI技术开启了数字患者护理的新时代。 患者可以随时访问其需要的数据&#xff…

Ubuntu 18.04 + CUDA 11.3.0 + CUDNN 8.2.1 + Anaconda + Pytorch 1.10

Xshell远程连接进行Ubuntu的Pytorch配置写在最前面参考Xshell常用命令Ubantu检查系统的各项配置查看ubuntu系统的版本信息和gcc版本查看Linux的内核版本和系统是多少位的验证机器是否具有n卡各种配置&#xff08;建议不要省略&#xff09;安装vim增加pip镜像源禁用nouveau开启S…