博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MySQL编程 优化篇(七) 优化MySQL Server
阅读量:3905 次
发布时间:2019-05-23

本文共 2543 字,大约阅读时间需要 8 分钟。

目录


MySQL体系结构概览

MySQL实例由一组后台线程、一些内存块和若干服务线程组成。

在默认情况下,MySQL有7组后台线程,分别是1个主线程,4组IO线程,1个锁线程,1个错误监控线程。MySQL 5.5之后又新增了一个 purge线程。

后台线程的主要功能略。

内存管理及优化

优化原则

在调整MySQL内存分配时,要注意以下几点。

  • 将尽量多的内存分配给MySQL做缓存,但要给操作系统和其他程序的运行预留足够的内存,否则如果产生SWAP页交换,将严重影响系统性能。

  • MyISAM的数据文件读取依赖于操作系统自身的IO缓存,因此,如果有MyISAM表,就要预留更多的内存给操作系统做IO缓存。

  • 排序区、连接区等缓存是分配给每个数据库会话(session)专用的,其默认值的设置要根据最大连接数合理分配,如果设置太大,不但浪费内存资源,而且在并发连接较高时会导致物理内存耗尽。

InnoDB优化策略

InnoDB用一块内存做IO缓存池,该缓冲池不仅用来缓存InnoDB索引块,而且也用来缓存InnoDB的数据块。

在内部,InnoDB缓存池逻辑上由 free list、flush list和LRU list组成。顾名思义,free list是空闲缓存块列表,flush list是需要刷新到磁盘的缓存块列表,而LRU list是 InnoDB正在使用的缓存块,它是 InnoDB buffer pool的核心。

调整参数来优化InnoDB的性能

参数 说明
innodb_buffer_pool_size InnoDB 存储引擎表数据和索引数据的最大缓存区大小。在一个专用的数据库服务器上,可以将80%的物理内存分配给 InnoDB buffer pool,但一定要注意避免设置过大而导致页交换。
innodb_old_blocks_pct old sublist的大小,其取值范围是5~95,默认值是37(约等于3/8)
innodb_old_blocks_time 缓存数据块由old sublist转移到young sublist的快慢,当一个缓存数据块被插入到 midpoint(old sublist)后,至少要在 old sublist 停留超过innodb_old_blocks_time(ms)后,才有可能被转移到new sublist
innodb_buffer_pool_instances 调整缓存池数量,减少内部对缓存池数据结构的争用,InnoDB 缓存系统会将参数innodb_buffer_pool_size指定大小的缓存平分为 innodb_buffer_pool_instances个 buffer pool
innodb_max_dirty_pages_pct 缓冲池中脏页的最大比例,默认值是75%,如果脏页的数量达到或者超过该值,InnoDB的后台线程将开始缓存刷新
innodb_io_capacity 磁盘IO能力,一定程度上代表磁盘每秒可完成的IO次数
sort_buffer_size 调整排序缓存区,以改善带有 order by子句或group子句SQL的性能。对于无法通过索引进行连接操作的查询,可以尝试通过增大join_buffer_size的值来改善性能。
innodb_log_file_size 设置日志文件大小,一般来说,平均半小时写满一个日志文件比较合适
max_connections 允许连接到MySQL数据库的最大数量
innodb_lock_wait_timeout InnoDB事务等待行锁的时间,默认值是50ms

InnoDB doublewrite

在进行脏页刷新时,InnoDB 采用了双写(doublewrite)策略。

原因:

MySQL的数据页大小(一般是 16KB)与操作系统的 IO 数据页大小(一般是 4KB)不一致,无法保证InnoDB缓存页被完整、一致地刷新到磁盘,而InnoDB的redo日志只记录了数据页改变的部分,并未记录数据页的完整前像,当发生部分写或断裂写时(比如将缓存页的第一个 4KB写入磁盘后,服务器断电),就会出现页面无法恢复的问题,为解决这个问题,InnoDB引入了doublewrite技术。

InnoDB log机制及优化

InnoDB重做日志

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

  1. 数据读入InnoDB buffer pool,并对相关记录加独占锁;

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

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

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

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

innodb_flush_log_at_trx_commit

innodb_ flush_ log_ at_ trx_ commit参数可以控制将redo buffer中的更新记录写入到日志文件以及将日志文件数据刷新到磁盘的操作时机。通过调整这个参数,可以在性能和数据安全之间做取舍。

  1. 如果这个参数设置为0,在事务提交时,InnoDB 不会立即触发将缓存日志写到磁盘文件的操作,而是每秒触发一次缓存日志回写磁盘操作,并调用操作系统fsync刷新IO缓存。

  1. 如果这个参数设置为1,在每个事务提交时,InnoDB立 即将缓存中的redo日志回写到日志文件,并调用操作系统fsync刷新IO缓存。

  1. 如果这个参数设置为2,在每个事务提交时,InnoDB立即将缓存中的redo日志回写到日志文件,但并不马上调用fsync来刷新IO缓存,而是每秒只做一次磁盘IO缓存刷新操作。

 

innodb_flush_log_at_trx_commit参数的默认值是 1,即每个事务提交时都会从 log buffer写更新记录到日志文件,而且会实际刷新磁盘缓存,显然,这完全能满足事务的持久化要求,是最安全的,但这样会有较大的性能损失。

转载地址:http://piqen.baihongyu.com/

你可能感兴趣的文章
[以太坊源代码分析] II. 数据的呈现和组织,缓存和更新
查看>>
[以太坊源代码分析]III. 挖矿和共识算法的奥秘
查看>>
[以太坊源代码分析] IV. 椭圆曲线密码学和以太坊中的椭圆曲线数字签名算法应用
查看>>
[以太坊源代码分析] V. 从钱包到客户端
查看>>
[以太坊源代码分析] VI. 基于p2p的底层通信(上篇)
查看>>
谈谈基于Go的Aop设计
查看>>
Gorilla源码分析之gorilla/context源码分析
查看>>
Gorilla源码分析之gorilla/mux源码分析
查看>>
Gorilla源码分析之gorilla/rpc源码分析
查看>>
第一时间获取文章,可以关注本人公众号:月牙寂道长
查看>>
Fasthttp源码分析之http server源码分析
查看>>
groupcache源码分析
查看>>
go-metrics源码分析
查看>>
beego/cache源码分析---典型的工厂模式
查看>>
Boltdb源码分析(一)-------page结构
查看>>
Boltdb源码分析(二)----node结构
查看>>
Boltdb源码分析(三)----meta结构
查看>>
Boltdb源码分析(四)----bucket结构
查看>>
Go标准库plugin源码分析----动态库使用
查看>>
leaf源码分析(一)----chanrpc
查看>>