mysql数据库学习-mysql内存IO性能优化

Mysql内存性能优化

1 CPU模式优化

1.7、安装jemalloc,避免原生内存分配器带来的内存碎片问题.

cp $basedir/lib/mysql/libjemalloc.so.1 /usr/lib64/libjemalloc.so

数据库配置文件添加如下

mysqld_safe

malloc-lib=/usr/lib64/libjemalloc.so

1.8、修改cpu模式

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

2 mysql数据库8以后得hint

select /*+ set_var(optimizer_switch='index_merge=off') set_var(join_buffer_size=4M) */ c_id from customer limit 1;

3 优化innodb_buffer_pool_size

innodb_buffer_pool_size 决定 InnoDB 存储引擎表数据和索引数据的最大缓存区大小。Innod buffer pool同时为数据块和索引块提供数据缓存,这与Oracle的缓存机制很相似。在保证操作系统及其他程序有足够内存可用的情况下,innodb_buffer_pool_size的值越大,缓存命中率越高,访问InnoDB表需要的磁盘I/O就越少,性能也就越高。在一个专用的数据库服务器上,可以将 80%的物理内存分配给 InnoDB buffer pool,但一定要注意避免设置过大而导致页交换。

innodb缓存池命中率

(1 -innodb buffer pool reads /innodb buffer pool read request)*100

4 优化innodb_log_file_size

一、innodb 重做日志

当更新数据时,innodb 内部的操作流程大致是:

将数据读入 innodb buffer pool,并对相关记录加独占锁;

将 undo 信息写入 undo 表空间的回滚段中;

更改缓存页中的数据,并将更新记录写入 redo buffer中;

提交时,根据 innodb_flush_log_at_trx_commit 的设置,用不同的方式将 redo buffer 中的更新记录刷新到 innodb redo log file 中,然后释放独占锁;

最后,后台 IO 线程根据需要择机将缓存中更新过的数据刷新到磁盘文件中。

innodb_log_buffer_size决定InnoDB重做日志缓存池的大小,默认值是8MB。对于可能产生大量更新记录的大事务,增加innodb_log_buffer_size的大小,可以避免InnoDB在事务提交前就执行不必要的日志写入磁盘操作。因此,对于会在一个事务中更新、插入或删除大量记录的应用,我们可以通过增大innodb_log_buffer_size来减少日志写磁盘操作,从而提高事务处理的性能。

5 优化thread_cache_size

为加快连接数据库的速度,MySQL 会缓存一定数量的客户服务线程以备重用,通过参数thread_cache_size可控制MySQL缓存客户服务线程的数量。

可以通过计算线程cache的失效率threads_created/connections来衡量thread_cache_size的设置是否合适。该值越接近1,说明线程cache命中率越低,应考虑适当增加thread_cache_size的值。

information_schema\] 04:40:47\>show variables like '%thread_cache_size%'; +-------------------+-------+ \| Variable_name \| Value \| +-------------------+-------+ \| thread_cache_size \| 768 \| +-------------------+-------+ 1 row in set (0.00 sec) \[information_schema\] 04:38:56\>show status like '%threads_created%'; +-----------------+-------+ \| Variable_name \| Value \| +-----------------+-------+ \| Threads_created \| 338 \| +-----------------+-------+ 1 row in set (0.00 sec) \[information_schema\] 04:39:06\>show variables like '%connections%'; +----------------------+-------+ \| Variable_name \| Value \| +----------------------+-------+ \| max_connections \| 10000 \| \| max_user_connections \| 0 \| +----------------------+-------+ 2 rows in set (0.01 sec)

6 优化innodb_lock_wait_timeout的设置

参数innodb_lock_wait_timeout可以控制InnoDB事务等待行锁的时间,默认值是50ms,可以根据需要动态设置。对于需要快速反馈的交互式OLTP应用,可以将行锁等待超时时间调小,以避免事务长时间挂起;对于后台运行的批处理操作,可以将行锁等待超时时间调大,以避免发生大的回滚操作。

7 优化table_open_cache

每一个SQL执行线程至少都要打开1个表缓存,参数table_open_cache控制所有SQL执行线程可打开表缓存的数量。这个参数的值应根据最大连接数 max_connections 以及每个连接执行关联查询中所涉及表的最大个数(用N表示)来设定:

max_connections*N

information_schema\] 04:36:02\>show variables like '%table_open_cache%'; +----------------------------+--------+ \| Variable_name \| Value \| +----------------------------+--------+ \| table_open_cache \| 2048 \| +----------------------------+--------+ 3 rows in set (0.01 sec) \[information_schema\] 04:36:19\>show status like '%open_tables%'; +----------------------+-------+ \| Variable_name \| Value \| +----------------------+-------+ \| Com_show_open_tables \| 0 \| \| Open_tables \| 2048 \| +----------------------+-------+ 2 rows in set (0.00 sec) (greatdb@10.142.44.36)\[information_schema\] 04:36:24\>

在未执行 flush tables命令的情况下,如果MySQL状态变量 opened_tables的值较大,就说明table_open_cache设置得太小,应适当增大

增大table_open_cache的值,会增加MySQL对文件描述符的使用量,因此,也要注意评估open-files-limit的设置是否够用。

8 合理设置log file size 控制检查点

当日志文件写满后INNODB会自动切换到另一个logfile,其他的logfile要产生检查点,产生大量IO操作,刷脏页(16KB)

show status like '%innodb_os_log_written%';

select sleep(60);

show status like '%innodb_os_log_written%';

复制代码
在业务高峰运行期间如果 Innodb_log_waits 值为0或接近0, innodb_log_buffer_size 可能太大,可以减少。

set @old_value := 0;

set @new_value := 0;

select VARIABLE_VALUE into @old_value from information_schema.GLOBAL_STATUS where VARIABLE_NAME = 'Innodb_log_waits';

select SLEEP(时间);

select VARIABLE_VALUE into @new_value from information_schema.GLOBAL_STATUS where VARIABLE_NAME = 'Innodb_log_waits';

select @old_value;

select @new_value;

日志设置大小至少为 30* 两次值差量/1024/1024.

9 数据盘禁用atime

/etc/fstab

atime是Linux/Unix系统下的一个文件属性,每当读取文件时,OS都会将读操作发生的时间回写到磁盘上。对于读写频繁的数据库文件来说,记录文件的访问时间一般没有任何用处,反而会增加磁盘系统的负担,影响I/O的性能。因此,可以通过设置文件系统的mount属性,阻止操作系统写atime信息,以减轻磁盘I/O的负担。在Linux下的具体做法如下。

(1)修改文件系统配置文件/etc/fstab,指定noatime选项:

/dev/vg_orasoft/lv_orasoft_u01 u01 ext4 defaults,noatime 0 0

(2)重新mount文件系统:

#mount -oremount /u01

完成上述操作,以后读/u01下文件就不会再写磁盘了。

7 优化back_log

back_log参数控制MySQL监听TCP端口时设置的积压请求栈大小,5.6.6版本以前的默认值是 50,5.6.6版本以后的默认值是 50+(max_connections / 5),但最大不能超过 900。
如果需要数据库在较短时间内处理大量连接请求,可以考虑适当增大back_log的值。

8 子查询调整连接优化

explain update irdb.r_tra_port a set a.line_branch_type = 52101 where obj_id in

(select ORIG_POINT_ID id from irdb.r_topolink where orig_ne_type in (504,501) union select DEST_POINT_ID id from irdb.r_topolink where orig_ne_type in (504,501));

一条update语句优化。

explain

update irdb.r_tra_port b JOIN

(select ORIG_POINT_ID id from irdb.r_topolink where orig_ne_type in (504,501)

union

select DEST_POINT_ID id from irdb.r_topolink where orig_ne_type in (504,501)

) a

on b.obj_id =a.id set b.line_branch_type = 52101

相关推荐
坤坤不爱吃鱼几秒前
【MySQL\Oracle\PostgreSQL】迁移到openGauss数据出现的问题解决方案
mysql·postgresql·oracle
胡斌附体1 分钟前
mobaxterm终端sqlplus乱码问题解决
数据库·乱码·sqlplus·字符集设置
生如夏花℡8 分钟前
HarmonyOS学习记录3
学习·ubuntu·harmonyos
moon66sun11 分钟前
开源项目XYZ.ESB:数据库到数据库(DB->DB)集成
数据库·esb
之歆11 分钟前
Python-封装和解构-set及操作-字典及操作-解析式生成器-内建函数迭代器-学习笔记
笔记·python·学习
幽络源小助理17 分钟前
SpringBoot基于JavaWeb的城乡居民基本医疗信息管理系统
java·spring boot·学习
欧阳有财20 分钟前
[java八股文][Mysql面试篇]日志
java·mysql·面试
TDengine (老段)29 分钟前
使用 StatsD 向 TDengine 写入
java·大数据·数据库·时序数据库·iot·tdengine·涛思数据
DarkAthena35 分钟前
【GaussDB】深度解析:创建存储过程卡死且无法Kill会话的疑难排查
数据库·gaussdb
叁沐40 分钟前
MySQL 03 事务隔离:为什么你改了我还看不见?
mysql