- A+
MySql对于开发人员来说应该都比较熟悉,不管是小白还是老码农应该都能熟练使用。但是要说到的各种参数的配置,我敢说大部分人并不是很熟悉,当我们需要优化mysql,改变某项参数的时候。还是要到处在网上查找,有点不方便。今天就把我所知道的MySql的配置文件my.cnf做一个简单的说明吧,注意,我总结的mysql是Linux环境下的。
其实,如果你要做mysql性能优化,那么熟悉my.cnf 的相关参数是必不可少的。不然,很多时候就会出现:网上查资料说是调下某个参数性能能提升,实际你调完之后却没有任何效果。所以我建议大家一定要把mysql重要的配置参数弄懂(加粗部分为重点参数)。
配置文件位置
my.cnf文件可以自定义位置,也可以使用如下默认的位置,只要放在默认位置,MySQL自动识别:
/etc/my.cnf 全局选项
/etc/mysql/my.cnf 全局选项
SYSCONFDIR/my.cnf 全局选项
$MYSQL_HOME/my.cnf 服务器特定选项(仅限服务器)
defaults-extra-file 指定的文件 --defaults-extra-file(如果有的话)
~/.my.cnf 用户特定的选项, ~表示当前用户的主目录(的值 $HOME)。
~/.mylogin.cnf 用户特定的登录路径选项(仅限客户端) 在上表中, 首先它会找/etc/my.cnf 这个文件, 如果这个文件不存在,那么它接下来去找/etc/mysql/my.cnf这个文件
配置参数参考
[client]
port = 3306
[mysqld]
#默认存储引擎INNODB
default-storage-engine=INNODB
#GROUP_CONCAT长度
group_concat_max_len =99999
#端口号
port = 3306
#套接字文件
#这里要注意:有时候重启mysql会提示/tmp/mysql.sock不存在,此时通常会由于两种情况导致,解决方法可以参考我之前记录的文章,亲测有效:https://www.cnblogs.com/zhangweizhong/p/12179452.html
socket = /usr/local/mysql/mysql.sock
#pid写入文件位置
pid-file = /usr/local/mysql/mysqld.pid
#数据库文件位置
datadir = /home/data/mysql/data
#控制文件打开的个数;
open_files_limit = 10240
#SQL模式
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
#当外部锁定(external-locking)起作用时,每个进程若要访问数据表,
#则必须等待之前的进程完成操作并解除锁定。由于服务器访问数据表时经常需要等待解锁,
#因此在单服务器环境下external locking会让MySQL性能下降。
#所以在很多Linux发行版的源中,MySQL配置文件中默认使用了skip-external-locking来避免external locking。
skip-external-locking
#跳过DNS反向解析
skip-name-resolve
#关闭TIMESTAMP类型默认值
explicit_defaults_for_timestamp
#不受client字符集影响,保证sever端字符集
skip-character-set-client-handshake
#初始连接字符集UTF8
init-connect='SET NAMES utf8'
#默认数据库字符集
character-set-server=utf8
#查询缓存0,1,2,分别代表了off、on、demand
query_cache_type = 1
#单位秒,握手时间超过connect_timeout,连接请求将会被拒绝
connect_timeout = 20
#设置在多少秒没收到主库传来的Binary Logs events之后,从库认为网络超时,Slave IO线程会重新连接主库。
#该参数的默认值是3600s ,然而时间太久会造成数据库延迟或者主备库直接的链接异常不能及时发现。
#将 slave_net_timeout 设得很短会造成 Master 没有数据更新时频繁重连。一般线上设置为5s
slave_net_timeout = 30
#这个参数用来配置从服务器的更新是否写入二进制日志,这个选项默认是不打开的,
#但是,如果这个从服务器B是服务器A的从服务器,同时还作为服务器C的主服务器,那么就需要开发这个选项,
#这样它的从服务器C才能获得它的二进制日志进行同步操作
log-slave-updates=1
#用于slave服务器,io线程会把server id与自己相同的event写入日志,与log-slave-updates选项冲突
replicate-same-server-id=0
server_id=10112879101
# 打开二进制日志功能.
# 在复制(replication)配置中,作为MASTER主服务器必须打开此项
# 如果你需要从你最后的备份中做基于时间点的恢复,你也同样需要二进制日志
log-bin =/home/data/mysql/binlog/mysql-bin.log
#relay-log日志
relay-log=mysql-relay-bin
#master-info-repository以及relay-log-info-repository打开以启用崩溃安全的二进制日志/从服务器功能(在事务表而不是平面文件中存储信息)
master-info-repository=TABLE
relay-log-info-repository=TABLE
#不写入binlog二进制日志中的数据库
binlog-ignore-db=mysql # No sync databases
binlog-ignore-db=test # No sync databases
binlog-ignore-db=information_schema # No sync databases
binlog-ignore-db=performance_schema # No sync databases
#写入binlog二进制日志中数据库
binlog-do-db=business_db
binlog-do-db=user_db
binlog-do-db=plocc_system
#清理binlog
expire-logs-days=15
max_binlog_size = 1073741824 # Bin logs size ( 1G )
#使binlog在每1000次binlog写入后与硬盘同步
sync_binlog = 1000
#指定只复制哪个库的数据
replicate-do-db=business_db
replicate-do-db=user_db
replicate-do-db=plocc_system
#开启事件调度器Event Scheduler
event_scheduler=1
#MySQL能暂存的连接数量。当主要MySQL线程在一个很短时间内得到非常多的连接请求,这就起作用。
#如果MySQL的连接数据达到max_connections时,新来的请求将会被存在堆栈中,以等待某一连接释放资源,
#该堆栈的数量即back_log,如果等待连接的数量超过back_log,将不被授予连接资源
#如果系统在短时间内有很多连接,则需要增大该参数的值,该参数值指定到来的TCP/IP连接的监听队列的大小。默认值50。
back_log = 500
#MySQL允许最大的进程连接数,
#如果经常出现Too Many Connections的错误提示,则需要增大此值。
max_connections = 6000
#每个用户的最大的进程连接数
max_user_connection = 3000
#每个客户端连接请求异常中断的最大次数,如果达到了此限制.
#这个客户端将会被MySQL服务阻止,直到执行了”FLUSH HOSTS” 或者服务重启
#非法的密码以及其他在链接时的错误会增加此值.
#查看 “Aborted_connects” 状态来获取全局计数器
max_connect_errors = 6000
#表调整缓冲区大小。
#table_cache 参数设置表高速缓存的数目。每个连接进来,都会至少打开一个表缓存。
#因此,table_cache 的大小应与 max_connections 的设置有关。例如,对于 200 个并行运行的连接,应该让表的缓存至少有 200 × N ,这里 N 是应用可以执行的查询的一个联接中表的最大数量。此外,还需要为临时表和文件保留一些额外的文件描述符。
#当Mysql访问一个表时,如果该表在缓存中已经被打开,则可以直接访问缓存;如果还没有被缓存但是在 Mysql 表缓冲区中还有空间,那么这个表就被打开并放入表缓冲区;如果表缓存满了,则会按照一定的规则将当前未用的表释放,或者临时扩大表缓存来存放,使用表缓存的好处是可以更快速地访问表中的内容。
#执行 flush tables 会清空缓存的内容。
#一般来说,可以通过查看数据库运行峰值时间的状态值 Open_tables 和 Opened_tables ,判断是否需要增加 table_cache 的值(其中 open_tables 是当前打开的表的数量, Opened_tables 则是已经打开的表的数量)。
#即如果open_tables接近table_cache的时候,并且Opened_tables这个值在逐步增加,那就要考虑增加这个#值的大小了。还有就是Table_locks_waited比较高的时候,也需要增加table_cache。
table_cache = 614
#表描述符缓存大小,可减少文件打开/关闭次数
table_open_cache = 2048
#设置在网络传输中一次消息传输量的最大值。系统默认值 为1MB,最大值是1GB,必须设置1024的倍数。
#当与大的BLOB字段一起工作时相当必要
max_allowed_packet = 64M
# 在一个事务中binlog为了记录SQL状态所持有的cache大小
# 如果你经常使用大的,多声明的事务,你可以增加此值来获取更大的性能.
# 所有从事务来的状态都将被缓冲在binlog缓冲中然后在提交后一次性写入到binlog中
# 如果事务比此值大, 会使用磁盘上的临时文件来替代.
# 此缓冲在每个连接的事务第一次更新状态时被创建
binlog_cache_size = 1M
# 独立的内存表所允许的最大容量.
# 此选项为了防止意外创建一个超大的内存表导致用尽所有的内存资源.
max_heap_table_size = 256M
#Sort_Buffer_Size被用来处理类似ORDER BY以及GROUP BY队列所引起的排序,每一个要做排序的请求,都会分到一个sort_buffer_size大的缓存
#Sort_Buffer_Size 是一个connection级参数,在每个connection(session)第一次需要使用这个buffer的时候,一次性分配设置的内存。
#Sort_Buffer_Size 并不是越大越好,由于是connection级的参数,过大的设置+高并发可能会耗尽系统内存资源。例如:500个连接将会消耗 500*sort_buffer_size(8M)=4G内存
#如果超过Sort_Buffer_Size设置的大小,MySQL会将数据写入磁盘来完成排序,导致效率降低。
#属重点优化参数
sort_buffer_size = 8M
#用于表间关联缓存的大小,和sort_buffer_size一样,该参数对应的分配内存也是每个连接独享。
#大部分表关联都比较影响查询性能,
#所以将此值设大能够减轻性能影响。
#通过 “Select_full_join” 状态变量查看表关联的数量
join_buffer_size = 8M
#thread_cache_size表示可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放到缓存中,
#如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,如果有很多新的线程,减少线程创建的开销
#可以通过比较 Connections 和 Threads_created 状态变量,来查看thread_cache_size的设置是否起作用。
#设置规则:1GB 内存配置为8,2GB配置为16,3GB配置为32,4GB或更高内存,可配置更大。
thread_cache_size = 128
#此值表示允许应用程序在同一时间运行的线程的数量.
#设置thread_concurrency的值的正确与否,对mysql的性能影响很大, 在多个cpu(或多核)的情况下,错误设置了thread_concurrency的值, 会导致mysql不能充分利用多cpu(或多核), 出现同一时刻只能一个cpu(或核)在工作的情况。
#thread_concurrency应设为CPU核数的2倍
#属重点优化参数
thread_concurrency = 8
#此值用来缓冲 SELECT 的结果并且在下一次同样查询的时候不再执行直接返回结果,如果你有大量的相同的查询并且很少修改表,那么query_cache_size可以极大的提高数据库性能,
#需要注意的是:有时候数据库出现了性能问题,大家就习惯的认为把这个值调大就行了。然而,这个参数加大后也引发了一系列问题。
#我们首先分析一下 query_cache_size的工作原理:一个SELECT查询在DB中工作后,DB会把该语句缓存下来,当同样的一个SQL再次来到DB里调用时,DB在该表没发生变化的情况下把结果从缓存中返回给Client。
#这里有一个关建点,就是DB在利用Query_cache工作时,要求该语句涉及的表在这段时间内没有发生变更。那如果该表在发生变更时,Query_cache里的数据又怎么处理呢?
#首先要把Query_cache和该表相关的语句全部置为失效,然后在写入更新。那么如果Query_cache非常大,该表的查询结构又比较多,查询语句失效也慢,一个更新或是Insert就会很慢,这样看到的就是Update或是Insert怎么这么慢了。
#所以在数据库写入量或是更新量也比较大的系统,该参数不适合分配过大。而且在高并发,写入量大的系统,建议把该功能禁掉。
#重点优化参数
query_cache_size = 64M
#指定单个查询能够使用的缓冲区大小,只有小于此设定值的结果才会被缓冲
#此设置用来保护查询缓冲,防止极大的结果集将其他所有的查询结果都覆盖
#缺省为1M
query_cache_limit = 2M
#被全文检索索引的最小的字长.
#你也许希望减少它,如果你需要搜索更短字的时候.
#注意在你修改此值之后,
#你需要重建你的 FULLTEXT 索引
ft_min_word_len = 4
#设置MYSQL线程使用的堆大小,此容量的内存在每次连接时被预留.
#MySQL 本身常不会需要超过64K的内存
#如果你使用你自己的需要大量堆的UDF函数
#或者你的操作系统对于某些操作需要更多的堆,
#你也许需要将其设置的更高一点.
thread_stack = 192K
#设定默认的事务隔离级别.可用的级别如下:
#READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE
transaction_isolation = READ-COMMITTED
#此值表示内存中临时表的最大大小,超过限值后就往硬盘写
#此限制是针对单个表的,而不是总和
#注意:
# 1. max_heap_table_size 比 tmp_table_size 小时,则系统会把 max_heap_table_size 的值作为最大的内存临时表的上限。这样可达到提高联接查询速度的效果,建议尽量优化查询,要确保查询过程中生成的临时表在内存中,避免临时表过大导致生成基于硬盘的MyISAM表。
# 2. 通过show global status like '%created_tmp%' 查询:Created_tmp_disk_tables和Created_tmp_tables的值,Created_tmp_disk_tables / Created_tmp_tables 值越小越好
tmp_table_size = 256M
#binlog日志类型
#mixed:混合型
binlog_format=mixed
#开启慢查询日志
slow_query_log
#文件格式
log_output = FILE
# 所有的使用了比这个时间(以秒为单位)更多的查询会被认为是慢速查询.
# 不要在这里使用”0″, 否则会导致所有的查询,甚至非常快的查询页被记录下来(由于MySQL 目前时间的精确度只能达到秒的级别).
long_query_time = 0.5
#慢查询日志位置
slow_query_log_file=/usr/local/mysql/mysqld_slow.log
MyISAM 相关选项
#用于索引的缓冲区大小,增加它可以提高索引处理性能,
#对于内存在4GB左右的服务器来说,该参数可设置为256MB或384MB。
#通过show variables like ‘%key_buffer_size%';
#通过 show global status like ‘%key_blocks_unused%' 查看是否还有剩余,如果剩余很多,就不需要再加大key_buffer_size了
#注意:
#1. 只用用于MyISAM表
#2. 可以设置为内存的30%-40%左右
#3. 即使你并不使用MyISAM 表, 最好也设置8-64M内存,由于它同样会被内部临时表使用
key_buffer_size = 2048M
#MySql读入缓冲区大小。当对表进行全表扫描请求是,将MySql会为它分配一个读入缓冲区
#如果对表的顺序扫描请求非常频繁,并且你认为频繁扫描进行得太慢,可以通过增加该变量值以及内存缓冲区大小提高其性能。
#该参数对应的分配内存也是每个连接独享。
read_buffer_size = 2M
#MySql的随机读(查询操作)缓冲区大小。可以提高很多ORDER BY的性能,当需要时由每个线程分配。
#当进行排序查询时,MySql会分配一个随机读缓存区。首先扫描一遍该缓冲,以避免磁盘搜索,提高查询速度,
#如果需要排序大量数据,可适当调高该值。
#需要注意的是:MySql会为每个客户连接发放该缓冲空间,所以应尽量适当设置该值,以避免内存开销过大。
read_rnd_buffer_size = 16M
#批量插入数据缓存大小,可以有效提高批量插入效率,默认为8M
#注意:
# 1. 不要将此值设置大于 “key_buffer_size”.
# 2. 设置0会关闭此参数。
bulk_insert_buffer_size = 16M
#MyISAM表发生变化,重建索引时所需的缓冲
#注意:此参数每个线程中分配,不宜设置过大。
myisam_sort_buffer_size = 128M
#MySQL重建索引时所允许的临时文件的大小 (当 REPAIR, ALTER TABLE 或者 LOAD DATA INFILE).
#如果临时文件大于此值,索引会通过键值缓冲创建(更慢)
myisam_max_sort_file_size = 1G
#如果一个表拥有多个索引, MyISAM 会通过并行排序使用多个线程去修复他们。
#一般用于拥有多个CPU以及大量内存情况。
myisam_repair_threads = 1
# 自动检查和修复没有适当关闭的 MyISAM 表.
myisam_recover
INNODB相关选项
#如果你的MySQL服务包含InnoDB支持但是并不打算使用的话,
#使用此选项会节省内存以及磁盘空间,并且加速某些部分
#skip-innodb
#这对Innodb表来说非常重要,Innodb把所有的数据和索引都缓存起来,此参数设置越大,数据存取时所需要的磁盘I/O越少。
#Innodb比MyISAM表对缓冲更为敏感。MyISAM可以在默认的 key_buffer_size 设置下运行的可以,然而Innodb在默认的 innodb_buffer_pool_size 设置下却跟蜗牛似的。
#注意:
#1. 当然如果你的数据量不大,并且不会暴增,也无需把 innodb_buffer_pool_size 设置的太大
#2. 如果在一个独立使用的数据库服务器上,你可以设置这个变量到服务器物理内存大小的80%
#3. 注意在32位系统上你每个进程可能被限制在 2-3.5G,
#属重点优化参数
innodb_buffer_pool_size = 2048M
# InnoDB 将数据保存在一个或者多个数据文件中成为表空间
# 如果你只有单个逻辑驱动保存你的数据,一个单个的自增文件就足够好了
# 其他情况下.每个设备一个文件一般都是个好的选择
# 你也可以配置InnoDB来使用裸盘分区
innodb_data_file_path = ibdata1:1024M:autoextend
# 文件IO的线程数,一般为 4
# 此值在Unix下被硬编码为4,但是在Windows下可以设置得较大.
innodb_file_io_threads = 4
# 允许线程数量。
# 服务器有几个CPU就设置为几,建议用默认设置。
# 过高的值可能导致线程的互斥。
innodb_thread_concurrency = 16
# 如果设置为1 ,InnoDB会在每次事务提交后将事务日志写到磁盘上,
# 基于性能考虑,可以设置为0或2,但要承担在发生故障时丢失数据的风险。
# 0代表日志只大约每秒写入日志文件并且日志文件刷新到磁盘.
# 2代表每次提交后日志写入日志文件,但是日志文件每秒刷新到磁盘上。
# 几点说明:
# 1. 如果是游戏服务器,建议此值设置为2;如果是对数据安全要求极高的应用,建议设置为1;
# 2. 设置为0性能最高,但如果发生故障,数据可能会有丢失的危险!
# 3. 默认值1每一次事务提交都需要把日志写到硬盘,这是很费时的。
# 4. 特别是使用电池供电缓存(Battery backed up cache)时。设成2对于很多运用,特别是从MyISAM表转过来的是可以的,
# 5. 它的意思是不写入硬盘而是写入系统缓存。日志仍然会每秒flush到硬盘,所以你一般不会丢失超过1-2秒的更新。
# 6. 设成0会更快一点,但安全方面比较差,即使MySQL挂了也可能会丢失事务的数据。而值2只会在整个操作系统挂了时才可能丢数据
#属重点优化参数
innodb_flush_log_at_trx_commit = 2
#此参数用于写日志文件所用的内存大小,以M为单位。缓冲区更大能提高性能,但意外的故障将会丢失数据。
#当缓存大小达到设定值后, InnoDB会将这些数据写到到磁盘上。
#由于基本上每秒都会刷新一次,所以没有必要将此值设置的太大,MySQL开发人员建议设置为1-8M之间
innodb_log_buffer_size = 16M
#此参数用于确定日志文件的大小
#为避免在日志文件覆写上不必要的缓冲池刷新
#一般设置为日志文件总合大小到你缓冲池大小的25%~100%
#但这同时也会增加恢复故障数据库所需的时间
innodb_log_file_size = 1024M
#日志组中的文件总数. 为提高性能,MySQL会以循环方式将日志写到多个文件中
#通常来说2~3是比较好的.
innodb_log_files_in_group = 3
# InnoDB的日志文件所在位置. 默认是MySQL的datadir.
# 你可以将其指定到一个独立的硬盘上或者一个RAID1卷上来提高其性能
#innodb_log_group_home_dir
# 在InnoDB缓冲池中最大允许的脏页面的比例.
# 如果达到限额, InnoDB会开始刷新他们防止他们妨碍到干净数据页面.
# 这是一个软限制,不被保证绝对执行.
innodb_max_dirty_pages_pct = 90
# InnoDB用来刷新日志的方法.
# 表空间总是使用双重写入刷新方法
# 默认值是 “fdatasync”, 另一个是 “O_DSYNC”.
innodb_flush_method=O_DSYNC
# 在被回滚前,一个InnoDB的事务应该等待一个锁被批准多久.
# InnoDB在其拥有的锁表中自动检测事务死锁并且回滚事务.
# 如果你使用 LOCK TABLES 指令, 或者在同样事务中使用除了InnoDB以外的其他事务安全的存储引擎
# 那么一个死锁可能发生而InnoDB无法注意到.
# 这种情况下这个timeout值对于解决这种问题就非常有帮助.
innodb_lock_wait_timeout = 30
[mysqldump]
# 不要在将内存中的整个结果写入磁盘之前缓存. 在导出非常巨大的表时需要此项
quick
max_allowed_packet = 64M
[mysql]
no-auto-rehash
#指定一个请求的最大连接时间,对于4GB左右的内存服务器来说,可以将其设置为5-10。
wait_timeout = 10
#开启该选可以彻底关闭MySQL的TCP/IP连接方式,如果WEB服务器是以远程连接的方式访问MYSQL数据库服务器的,则不要开启该选项,否则将无法正常连接。
skip_networking
#将没有使用索引的查询也记录下来
log-queries-not-using-indexes