十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
相关查看命令
创新互联建站网站建设服务商,为中小企业提供做网站、成都做网站服务,网站设计,网站改版维护等一站式综合服务型公司,专业打造企业形象网站,让您在众多竞争对手中脱颖而出创新互联建站。
sql show global variables like 'innodb_buffer_pool_size';
sql show global status like 'Innodb_buffer_pool_pages_data';
sql show global status like 'Innodb_page_size';
有的参数对应不同引擎,比如对于innodb引擎的,都是innodb_打头。
例如:
innodb_buffer_pool_size = 81920M
join_buffer_size = 1024M
innodb_sort_buffer_size =1024M
sort_buffer_size = 2048M
read_rnd_buffer_size = 2048M
innodb_log_buffer_size = 128M
innodb_log_file_size =2048M
innodb_log_files_in_group=10
bulk_insert_buffer_size=4096M
myisam_sort_buffer_size = 512M
myisam_max_sort_file_size = 10G
thread_cache_size = 300
ft_min_word_len = 1 #for chinese full text search
query_cache_size = 512M
query_cache_limit = 4M
query_cache_type = 0
query_cache_min_res_unit = 2k
thread_stack = 512K
tmp_table_size = 3G
max_heap_table_size = 3G
long_query_time = 3
log-slave-updates
max_binlog_cache_size = 8M
调优参考计算方法:
val = Innodb_buffer_pool_pages_data / Innodb_buffer_pool_pages_total * 100%
val 95% 则考虑增大 innodb_buffer_pool_size, 建议使用物理内存的75%
val 95% 则考虑减小 innodb_buffer_pool_size, 建议设置为:Innodb_buffer_pool_pages_data * Innodb_page_size * 1.05 / (1024*1024*1024)
设置命令:set global innodb_buffer_pool_size = 2097152; //缓冲池字节大小,单位kb,如果不设置,默认为128M
设置要根据自己的实际情况来设置,如果设置的值不在合理的范围内,并不是设置越大越好,可能设置的数值太大体现不出优化效果,反而造成系统的swap空间被占用,导致操作系统变慢,降低sql查询性能。
修改配置文件的调整方法,修改my.cnf配置:
innodb_buffer_pool_size = 2147483648 #设置2G
innodb_buffer_pool_size = 2G #设置2G
innodb_buffer_pool_size = 500M #设置500M
MySQL5.7及以后版本,改参数时动态的,修改后,无需重启MySQL,但是低版本,静态的,修改后,需要重启MySQL。
我们仍然使用两个会话,一个会话 run,用于运行主 SQL;另一个会话 ps,用于进行 performance_schema 的观察:
主会话线程号为 29,
将 performance_schema 中的统计量重置,
临时表的表大小限制取决于参数 tmp_table_size 和 max_heap_table_size 中较小者,我们实验中以设置 max_heap_table_size 为例。
我们将会话级别的临时表大小设置为 2M(小于上次实验中临时表使用的空间),执行使用临时表的 SQL:
查看内存的分配记录:
会发现内存分配略大于 2M,我们猜测临时表会比配置略多一点消耗,可以忽略。
查看语句的特征值:
可以看到语句使用了一次需要落磁盘的临时表。
那么这张临时表用了多少的磁盘呢?
我们开启 performance_schema 中 waits 相关的统计项:
重做实验,略过。
再查看 performance_schema 的统计值:
可以看到几个现象:
1. 临时表空间被写入了 7.92MiB 的数据。
2. 这些数据是语句写入后,慢慢逐渐写入的。
来看看这些写入操作的特征,该方法我们在 实验 03 使用过:
可以看到写入的线程是 page_clean_thread,是一个刷脏操作,这样就能理解数据为什么是慢慢写入的。
也可以看到每个 IO 操作的大小是 16K,也就是刷数据页的操作。
结论:
我们可以看到,
1. MySQL 会基本遵守 max_heap_table_size 的设定,在内存不够用时,直接将表转到磁盘上存储。
2. 由于引擎不同(内存中表引擎为 heap,磁盘中表引擎则跟随 internal_tmp_disk_storage_engine 的配置),本次实验写磁盘的数据量和 实验 05 中使用内存的数据量不同。
3. 如果临时表要使用磁盘,表引擎配置为 InnoDB,那么即使临时表在一个时间很短的 SQL 中使用,且使用后即释放,释放后也会刷脏页到磁盘中,消耗部分 IO。
1.查参数配置
目前积累的使用经验中,存储过程函数触发器视图 在MySQL场景下是不适合的。性能不好,又容易发现内存不释放的问题,所以建议尽量避免.
2.存储过程函数
3.视图
4.触发器
5.1 总内存使用
5.2 分事件统计内存
5.3 账号级别统计
5.4 线程对应sql语句,内存使用统计
5.5 打开所有内存性能监控,会影响性能,需注意
5.6 系统表内存监控信息
6.top 命令
8.ps命令
9.pmap 命令
pmap是Linux调试及运维一个很好的工具,查看进程的内存映像信息
用法1:执行一段时间记录数据变化,最少20个记录,下面69265是MySQL pid
用法2:linux 命令pmap MySQL pid导出内存,下面69265是MySQL pid
RSS就是这个process实际占用的物理内存。
Dirty: 脏页的字节数(包括共享和私有的)。
Mapping: 占用内存的文件、或[anon](分配的内存)、或[stack](堆栈)。
writeable/private:进程所占用的私有地址空间大小,也就是该进程实际使用的内存大小。
1.首先使用/top/free/ps在系统级确定是否有内存泄露。如有,可以从top输出确定哪一个process。
2.pmap工具是能帮助确定process是否有memory leak。确定memory leak的原则:writeable/private (‘pmap –d’输出)如果在做重复的操作过程中一直保持稳定增长,那么一定有内存泄露
MySQL 自身内存规划
说到 MySQL 自身的内存规划,最先想到的就是 MySQL 中各种 buffer 的大小,innodb buffer pool 就是最鹤立鸡群的那个。innodb_buffer_pool_size 参数的大小究竟如何设置,才能保证 MySQL 的性能呢?在官网文档中可以找到这个参数的一些描述:
A larger buffer pool requires less disk I/O to access the same table data more than once. On a dedicated database server, you might set the buffer pool size to 80% of the machine's physical memory size.
意思是在专用数据库服务器上,可以将 innodb_buffer_pool_size 设置为计算机物理内存大小的 80%。在许许多多前辈的的经验中了解到,此参数的值设置为物理内存的 50%~80% 颇为合理。
举个栗子:
innodb buffer pool 分配 76G,每个连接线程最大可用 160M,最大有 3000 连接数,最大可能使用内存总量 545G,但是这台实例所在服务器的物理内存仅仅有 97G,远超物理内存总量。结果可想而知,这个实例在运行中经常被 oom-killer 杀死,想必原因之一即是因为一开始 MySQL 自身的内存规划欠妥。
innodb buffer pool 缓存数据的作用相信大家都懂,比如这个 case 中,可以发现该实例为写密集,读请求很少,innodb buffer 对性能改善作用不大,80% 的内存没必要,完全可以降低到物理内存的50%。
线程管理,服务器程序为了提高效率,会将一些信息存储于buffer(cache)。
Memory(HEAP)引擎将数据存储在那种中内存中。
临时表如果没有超过设定的限制会存储在内存中。
每个客户端连接都会使用一定的buffer空间
全局的Buffer和Cache(比如MyISAM的keybuffer,InnoDB的buffer pool, Query cache等 )
查看mysql数据库大小的四种办法,分别有以下四种:
第一种:进去指定schema 数据库(存放了其他的数据库的信息)
use information_schema
第二种:查询所有数据的大小
select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES()
第三种:查看指定数据库的大小,比如说:数据库apoyl
select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES where table_schema='apoyl';
第四种:查看指定数据库的表的大小,比如说:数据库apoyl 中apoyl_test表
select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES where table_schema='apoyl' and table_name='apoyl_test';