李锋镝的博客

  • 首页
  • 时间轴
  • 说说
  • 左邻右舍
  • 博友圈
  • 关于我
    • 关于我
    • 网站地图
    • 网站统计
    • 另一个网站
    • 我的导航站
    • 赞助
  • 留言
  • 走心评论
  • 系列文章
  • Now
  • 每日心情
  • 论坛
  • 🚇开往
Destiny
自是人生长恨水长东
  1. 首页
  2. 转载
  3. 技术
  4. 正文

优化了MYSQL大量写入问题,老板奖励了1000块给我

2021年2月19日 约 2,096 字7 分钟 45点热度 0人点赞 3条评论
本文最后更新于 2021年2月19日,距今已 2000 天,其中的信息可能已经发生变化,请注意甄别。

问题。然而在大量写入数据场景该如何优化呢?

今天这里主要给大家介绍,在有大量写入的场景,进行优化的方案。

总的来说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操作。

当然还有更多的硬件或者软件优化方法,这里就不一一列举了。

 

原文链接:https://huaweicloud.blog.csdn.net/article/details/112171692

除非注明,否则均为李锋镝的博客原创文章,转载必须以链接形式标明本文链接

本文链接:https://www.lifengdi.com/transport/2494

推荐阅读

  • MySQL分页排序时数据重复问题(MySQL优先队列)
  • 彻底搞懂mysql日志系统binlog,redolog,undolog
  • MySQL中的这个池子,强的一批!
  • 还不懂Redis?看完这个故事就明白了!
  • MySQL语句执行顺序
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: MySQL
最后更新:2021年2月19日

岁月同一天 8 月 12 日

回望过去的今天,你在写什么

  • 6 年前 2020年8月12日
    jstat命令使用(JDK1.8)

    概述 jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下: jstat [-命令选项] [vm…

相关文章
  • MySQL深度分页2022年2月11日
  • MySQL数据库查看执行计划以及名词解释2019年9月12日
  • 千万级大表新增字段实战指南:告别锁表与业务中断2026年1月15日
  • MySQL 的自增 ID 用完了,怎么办?2021年3月30日
  • 彻底搞懂mysql日志系统binlog,redolog,undolog2021年5月19日

李锋镝

既然选择了远方,便只顾风雨兼程。

打赏 点赞
< 上一篇
下一篇 >
1234567891112131415161718192021222324252627282930313233343536373839404142434446474849505152535455575859606162636465666769727476777879808182858687909293949596979899
取消回复
…

文章评论

  • 王光卫博客Lv 1

    也来优化试试看

    macOSFirefox 85.0 中国-德阳市
    2021年2月19日
    00 回复
    • 城南旧事Lv 1

      @王光卫博客 咱流量没那么大,还不至于

      macOSFirefox 85.0 中国-郑州市
      2021年2月22日
      00 回复
      • 王光卫博客Lv 1

        @城南旧事 :douyin.19: 我网站只要有人评论留言,就会出现超负荷,研究了半天也不敢就优化mysql

        macOSChrome 113.0.0.0 中国-成都市
        2023年5月18日
        00 回复
  • 不将沉重累坠的银元装在怀中,来自讨无谓的苦吃。

    听点儿音乐吧 朋友~
    文章目录
    最新 热点 随机
    最新 热点 随机
    Kratos+ v1.1.16版本更新说明 WorkBuddy介绍 Kratos+ v1.1.14版本更新说明 Spring Boot 指定外部配置文件的方式 Spring Boot 配置加载优先级总结 Claude Fable 5(claude-fable-5)深度详解
    给主题增加了Now、每日心情、年度回顾、岁月同一天、随机漫步等功能AI时代,个人技术博客的出路在哪里?增加了两套复古皮肤-牛皮纸、千禧网页这个域名注册整整十年了,十年时间,真快啊Kratos+ v1.1.14版本更新说明WordPress实现用户评论等级排行榜插件
    使用shell脚本统一修改maven项目的版本 图数据库选型:Neo4j、Janus、HugeGraph 今晚,回家过年! ElasticSearch入门-基本概念介绍以及安装 SpringBoot 实现 RSA+AES 自动接口解密 Kafka常见面试题(一)
    最近评论
    李锋镝 发布于 2 天前(08月10日) 等我搞一个数据转换的插件~
    李锋镝 发布于 2 天前(08月10日) 精美可担不起~😂
    李锋镝 发布于 2 天前(08月10日) PHP是世界上最伟大的语言=。=
    Hary 发布于 3 天前(08月09日) 我都想用了,但是是ty,转换有点麻烦
    老张博客 发布于 4 天前(08月08日) 做的越来越精美了,好看。
    标签聚合
    Spring JAVA K8s SQL Claude Redis JVM 设计模式 分布式 MySQL IDEA 架构 ElasticSearch 日常 SpringBoot AI编程 AI 数据库 WordPress 多线程
    友情链接
    • Serendipity
    • 老张博客
    • 韩小韩博客
    • Mr.Sun的博客
    • 九仞之行
    • 志文工作室
    • 风渡言
    • 知向前端
    • 拾趣博客导航
    • Honesty
    • 瓦匠个人小站
    • 旧时繁华
    • 彬红茶日记
    • 懋和道人
    • 临窗旋墨
    • 搬砖日记
    • 林羽凡
    • 哥斯拉
    • 韩情脉脉
    • 皮皮社

    COPYRIGHT © 2026 lifengdi.com. ALL RIGHTS RESERVED.

    正在博友圈履约中

    域名年龄

    Theme Kratos+ By Dylan Li

    津ICP备2024022503号-3

    京公网安备11011502039375号