优化了MYSQL大量写入问题,老板奖励了1000块给我
摘要:大家提到Mysql的性能优化都是注重于优化sql以及索引来提升查询性能,大多数产品或者网站面临的更多的高并发数据读取问题。然而在大量写入数据场景该如何优化呢?
今天这里主要给大家介绍,在有大量写入的场景,进行优化的方案。
总的来说MYSQL数据库写入性能主要受限于数据库自身的配置,以及操作系统的性能,磁盘IO的性能。主要的优化手段包括以下几点:
1、调整数据库参数
(1) innodb_flush_log_at_trx_commit
默认为1,这是数据库的事务提交设置参数,可选值如下:
0: 日志缓冲每秒一次地被写到日志文件,并且对日志文件做到磁盘操作的刷新,但是在一个事务提交不做任何操作。
1:在每个事务提交时,日志缓冲被写到日志文件,对日志文件做到磁盘操作的刷新。
2:在每个提交,日志缓冲被写到文件,但不对日志文件做到磁盘操作的刷新。对日志文件每秒刷新一次。
有人会说如果改为不是1的值会不会不安全呢? 安全性比较如下:
在 mysql 的手册中,为了确保事务的持久性和一致性,都是建议将这个参数设置为 1 。出厂默认值是 1,也是最安全的设置。
当innodb_flush_log_at_trx_commit和sync_binlog 都为 1 时是最安全的,在mysqld 服务崩溃或者服务器主机crash的情况下,binary log 只有可能丢失最多一个语句 或者一个事务。
但是这种情况下,会导致频繁的io操作,因此该模式也是最慢的一种方式。
- 当innodb_flush_log_at_trx_commit设置为0,mysqld进程的崩溃会导致上一秒钟所有事务数据的丢失。
- 当innodb_flush_log_at_trx_commit设置为2,只有在操作系统崩溃或者系统掉电的情况下,上一秒钟所有事务数据才可能丢失。
针对同一个表通过c#代码按照系统业务流程进行批量插入,性能比较如下所示:
- (a.相同条件下:innodb_flush_log_at_trx_commit=0,插入50W行数据所花时间25.08秒;
- (b.相同条件下:innodb_flush_log_at_trx_commit=1,插入50W行数据所花时间17分21.91秒;
- (c.相同条件下:innodb_flush_log_at_trx_commit=2,插入50W行数据所花时间1分0.35秒。
结论:设置为0的情况下,数据写入是最快的,能迅速提升数据库的写入性能, 但有可能丢失上1秒的数据。
(2) temp_table_size,heap_table_size
这两个参数主要影响临时表temporary table 以及内存数据库引擎memory engine表的写入,设置太小,甚至会出现table is full的报错信息.
要根据实际业务情况设置大于需要写入的数据量占用空间大小才行。
(3) max_allowed_packet=256M,net_buffer_length=16M,set autocommit=0
备份和恢复时如果设置好这三个参数,可以让你的备份恢复速度飞起来哦!
(4) innodb_data_file_path=ibdata1:1G;ibdata2:64M:autoextend
很显然表空间后面的autoextend就是让表空间自动扩展,不够默认情况下只有10M,而在大批量数据写入的场景,不妨把这个参数调大;
让表空间增长时一次尽可能分配更多的表空间,避免在大批量写入时频繁的进行文件扩容
(5) innodb_log_file_size,innodb_log_files_in_group,innodb_log_buffer_size
设置事务日志的大小,日志组数,以及日志缓存。默认值很小,innodb_log_file_size默认值才几十M,innodb_log_files_in_group默认为2。
然而在innodb中,数据通常都是先写缓存,再写事务日志,再写入数据文件。设置太小,在大批量数据写入的场景,必然会导致频繁的触发数据库的检查点,去把 日志中的数据写入磁盘数据文件。频繁的刷新buffer以及切换日志,就会导致大批量写入数据性能的降低。
当然,也不宜设置过大。过大会导致数据库异常宕机时,数据库重启时会去读取日志中未写入数据文件的脏数据,进行redo,恢复数据库,太大就会导致恢复的时间变的更长。当恢复时间远远超出用户的预期接受的恢复时间,必然会引起用户的抱怨。
这方面的设置倒可以参考华为云的数据库默认设置,在华为云2核4G的环境,貌似默认配置的buffer:16M,log_file_size:1G----差不多按照mysql官方建议达到总内存的25%了;而日志组files_in_group则设置为4组。

2核4G这么低的硬件配置,由于参数设置的合理性,已经能抗住每秒数千次,每分钟8万多次的读写请求了。
而假如在写入数据量远大于读的场景,或者说方便随便改动参数的场景,可以针对大批量的数据导入,再做调整,把log_file_size调整的更大,可以达到innodb_buffer_pool_size的25%~100%。
(6) innodb_buffer_pool_size设置MySQL Innodb的可用缓存大小。理论上最大可以设置为服务器总内存的80%.
设置越大的值,当然比设置小的值的写入性能更好。比如上面的参数innodb_log_file_size就是参考innodb_buffer_pool_size的大小来设置的。
(7) innodb_thread_concurrency=16
故名思意,控制并发线程数,理论上线程数越多当然会写入越快。当然也不能设置过大官方建议是CPU核数的两倍左右最合适。
(8) write_buffer_size
控制单个会话单次写入的缓存大小,默认值4K左右,一般可以不用调整。然而在频繁大批量写入场景,可以尝试调整为2M,你会发现写入速度会有一定的提升。
(9) innodb_buffer_pool_instance
默认为1,主要设置内存缓冲池的个数,简单一点来说,是控制并发读写innodb_buffer_pool的个数。
在大批量写入的场景,同样可以调大该参数,也会带来显著的性能提升。
(10) bin_log
二进制日志,通常会记录数据库的所有增删改操作。然而在大量导数据,比如数据库还原的时候不妨临时关闭bin_log,关掉对二进制日志的写入,让数据只写入数据文件,迅速完成数据恢复,完了再开启吧。
2、减少磁盘IO,提高磁盘读写效率
包括如下方法:
(1):数据库系统架构优化
a:做主从复制;
比如部署一个双主从,双主从模式部署是为了相互备份,能保证数据安全,不同的业务系统连接不同的数据库服务器,结合ngnix或者keepalive自动切换的功能实现负载均衡以及故障时自动切换。
通过这种架构优化,分散业务系统的并发读写IO从一台服务器到多台服务器,同样能提高单台数据库的写入速度。
b:做读写分离
和1中要考虑的问题一样,可以减轻单台服务器的磁盘IO,还可以把在服务器上的备份操作移到备服务器,减轻主服务器的IO压力,从而提升写入性能。
(2):硬件优化
a: 在资源有限的情况下,安装部署的时候,操作系统中应有多个磁盘,把应用程序,数据库文件,日志文件等分散到不同的磁盘存储,减轻每个磁盘的IO,从而提升单个磁盘的写入性能。
b:采用固态硬盘SSD
如果资源足够可以采用SSD存储,SSD具有高速写入的特性,同样也能显著提升所有的磁盘IO操作。
当然还有更多的硬件或者软件优化方法,这里就不一一列举了。
本文分享自华为云社区《MYSQL大批量写入之性能优化》,原文作者: 浮尘 。
优化了MYSQL大量写入问题,老板奖励了1000块给我的更多相关文章
- Mysql数据库写入数据速度优化
Mysql数据库写入数据速度优化 1)innodb_flush_log_at_trx_commit 默认值为1:设置为0,可以提高写入速度. 值为0:提升写入速度,但是安全方面较差,mysql服务器 ...
- MySQL磁盘写入策略以及数据安全性的相关参数
转载自:http://blog.itpub.net/22664653/viewspace-1063134/ innodb_flush_log_at_trx_commit和sync_binlog ...
- 性能优化之MySQL调优篇
MySQL对于很多Linux从业者而言,是一个非常棘手的问题,多数情况都是因为对数据库出现问题的情况和处理思路不清晰.在进行MySQL的优化之前必须要了解的就是MySQL的查询过程,很多的查询优化工作 ...
- 【优化】MySQL千万级大表优化解决方案
问题概述 使用阿里云rds for MySQL数据库(就是MySQL5.6版本),有个用户上网记录表6个月的数据量近2000万,保留最近一年的数据量达到4000万,查询速度极慢,日常卡死.严重影响业务 ...
- mysql批量写入
MySQL批量写入语法是: INSERT INTO table (field1,field2,field3) VALUES (“a”,”b”,”c”), (“a1”,”b1”,”c1”),(“a2”, ...
- MySQL 批量写入数据报错:mysql_query:Lost connection to MySQL server during query
场景: 批量往mysql replace写入数据时,报错. 解决方法: 1.增大mysql 数据库配置中 max_allowed_packet 的值 max_allowed_packet = 1G ( ...
- saltstack自动化运维系列④之saltstack的命令返回结果mysql数据库写入
saltstack自动化运维系列④之saltstack的命令返回结果mysql数据库写入salt的返回值写入mysql数据库:可参考:https://docs.saltstack.com/en/lat ...
- 数据库优化之mysql【转】
1. 优化流程图 mysql优化(主要增加数据库的select查询,让查询速度更快) 2. 优化mysql的方面 主要从以下四个方面去优化mysql ①存储层:如何选择一个数据库引擎,选择合适的字段列 ...
- 转】[MySQL优化]为MySQL数据文件ibdata1瘦身
原博文出自于: http://blog.fens.me/category/%E6%95%B0%E6%8D%AE%E5%BA%93/page/2/ 感谢! [MySQL优化]为MySQL数据文件ibda ...
- .NET 5/.NET Core使用EF Core 5连接MySQL数据库写入/读取数据示例教程
本文首发于<.NET 5/.NET Core使用EF Core 5(Entity Framework Core)连接MySQL数据库写入/读取数据示例教程> 前言 在.NET Core/. ...
随机推荐
- nginx中一个请求匹配到多个location时的优先级问题,马失前蹄了
背景 为什么讲这么小的一个问题呢?因为今天在进行系统上线的时候遇到了这个问题. 这次的上线动作还是比较大的,由于组织架构拆分,某个接入层服务需要在两个部门各自独立部署,以避免频繁的跨部门沟通,提升该接 ...
- IEEE754浮点数与字节数互转工具
前段时间做的一个小工具,分享一下. 提供浮点数和字节的相互转换. 下载
- centos服务器搭建https
一.环境 OS:CentOS Linux release 8.2.2004 (Core) 硬件:某外网云服务器虚拟机 二.安装命令 1.安装nginx yum install nginx 2.安装签发 ...
- MicroSIP-3.21.3+pjproject-2.13.1+ opus-1.3.1+VS2019
本文记录了我通过VS2019编译MicroSIP-3.21.3开源项目的过程. Microsip:MicroSIP source code pjproject:Download PJSIP - Ope ...
- 22. 从零用Rust编写正反向代理,一个数据包的神奇HTTP历险记!
wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,内网穿透,后续将实现websocket代理等,会将实现 ...
- JavaScript 简介与引用
作者:WangMin 格言:努力做好自己喜欢的每一件事 我们通常写好的HTML网页是处于一个静态的效果,在用户体验这一方面就不是很好,给人一种死板的感觉.这里我们就可以用到JavaScript来为网页 ...
- git 忽略已提交(commit)的文件/文件夹
git 忽略已提交的文件或文件夹 最好是在工程一开始就编辑好 .gitignore 文件, 在第一次提交的时候仔细检查避免添加那些无用的文件 因为 .gitignore 只能对未提交过的文件起效, 也 ...
- 01_实验一_操作系统的启动start
实验一 操作系统的启动 从源代码到可运行的操作系统(前置知识) API 与 SDK 以 C 语言编写的操作系统为背景进行介绍,EOS 是由 C 语言编写的 操作系统和应用程序之间一个重要的纽带就是应用 ...
- Educational Codeforces Round 104 (Rated for Div. 2) A~E题解
写在前边 链接:Educational Codeforces Round 104 (Rated for Div. 2) A. Arena 链接:A题链接 题目大意: 给定一个长度为\(n\)的数组,表 ...
- 关于点赞业务对MySQL和Redis和MongoDB的思考
点赞 在我个人理解中,点赞业务比较频繁,很多人业务可能都会有这个,比如:博客,视频,文章,动态,评论等,但是不应该是核心业务,不应该大量地请求MySQL数据库,给数据库造成大量的资源消耗,MySQ ...