mysql问题

mysql InnoDB引擎查询的时候,会碰到第一次查询很慢很慢,然后后面的查询速度就会很快。这个是InnoDB引擎的预热机制。

InnoDB有innodb buffer pool(简称ibf)的概念

相关的参数innodb_buffer_pool_size,size越大,可以放到内存的数据越多,当热 点数据经过LRU算法进入到buffer pool之后,读的都是内存。

MySQL 5.0的预热

SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES

MySQL 5.1预热

 

SELECT table_schema, table_name FROM information_schema.tables

执行 select * from db.table limit 1 来实现我们的方法

可以在my.cnf 加入init-file=/XXX/init.sql ,在每次mysql重启的时候就自动执行这个预热的sql


mysql在连接的过程当中,发现连接速度很慢很慢,但是连接上之后,发现执行数据什么的都很快,后面经过经查,发现有一个 反向解析 的过程

不管你是使用域名还是IP连接数据库,mysqld都会做一个反向解析的过程,即从 IP->dns的反查,反查的过程是很慢的而且是受ISP控制,所以一旦ISP由于某些原因而无法响应就会出现unauthenticated user,而且mysql会出现停顿状态。解决的办法就是在my.cnf里面增加一个设置禁止mysql做任何解析的动作。

skip-name-resolve

在做这个设置的之前一定要检查系统,将所有连接改写为IP连接,因为一旦此设置生效,mysql是无法进行域名解析的,原有的域名连接将全部失效。


InnoDB引擎插入数据很慢。插入一条数据居然耗时100ms左右。

经过检查,有一个配置项需要注意。

innodb_flush_log_at_trx_commit = 2

该参数取值可以是0,1,2

innodb_flush_log_at_trx_commit = 0,Innodb 中的Log Thread 没隔1 秒钟会将log buffer中的数据写入到文件,同时还会通知文件系统进行文件同步的flush 操作,保证数据确实已经写入到磁盘上面的物理文件。但是,每次事务的结束(commit 或者是rollback)并不会触发Log Thread 将log buffer 中的数据写入文件。所以,当设置为0 的时候,当MySQL Crash 和OS Crash 或者主机断电之后,最极端的情况是丢失1 秒时间的数据变更。

innodb_flush_log_at_trx_commit = 1,这也是Innodb 的默认设置。我们每次事务的结束都会触发Log Thread 将log buffer 中的数据写入文件并通知文件系统同步文件。这个设置是最安全的设置,能够保证不论是MySQL Crash 还是OS Crash 或者是主机断电都不会丢失任何已经提交的数据。

innodb_flush_log_at_trx_commit = 2,当我们设置为2 的时候,Log Thread 会在我们每次事务结束的时候将数据写入事务日志,但是这里的写入仅仅是调用了文件系统的文件写入操作。而我们的文件系统都是有缓存机制的,所以Log Thread 的这个写入并不能保证内容真的已经写入到物理磁盘上面完成持久化的动作。文件系统什么时候会将缓存中的这个数据同步到物理磁盘文件Log Thread 就完全不知道了。所以,当设置为2 的时候,MySQL Crash 并不会造成数据的丢失,但是OS Crash 或者是主机断电后可能丢失的数据量就完全控制在文件系统上了。


高并发情况下,mysql出现Too many connections的错误。

出现这个错误有可能是代码连接泄露(忘记关闭网络接),也有可能是并发压力很大。

一般解决方法可以提高最大连接数,也就是设置

max_connections = 5000#默认只有100(根据需求提高这个数)
当然,如果要根本解决,还是要看具体问题,如果是连接泄露,还是修复bug为好,如果是高并发,修改此参数并且有条件的话可以读写分离,分担压力。
一些连接状态查看指令:
show status like 'Threads%';
show global variables like 'max_conn%';

如果不能连接上mysql,可以用gdb -p $(pidof mysqld) -ex "set max_connections=1500" -batch 来修改mysql进程参数。

                                  

发表评论