mysql内存分配 1.MySQL内存申请公式: 1.1 per-thread buffers: 每个线程缓冲内存针对每个线程连接分配的。每个线程的connection buffer和result buffer 开始是给定net_buffer_length大小,可以动态增长到max_allowed_packet字节的大小。在使用过程 中result buffer每个语句执行完成以后会收缩到net_buffer_length字节大小。 每个连接线程的计算公式: (read_buffer_size+read_rnd_buffer_size+sort_buffer_size+thread_stack+ join_buffer_size+binlog_cache_size)*max_connections=total memory for all connections 这个内存使用叫:MySQL Thread Buffers(MTB) 1.2 global buffers: global buffer与每个线程分配的内存没有多大关系。当进程启动,预留的内存资源,直到服务器 关闭。这个内存叫MySQL Global Buffers(MGB) 1.3 总的内存申请 总的内存申请大小为: MTB+MGB=Total Memory Used by MySQL 1.4 参数说明: read_buffer_size: 每个线程每一次顺序扫描MyISAM表所申请的内存,该值默认为131072字节。该值应该为4K 整数倍,如果不为4K的整数倍会向下取值为4K的整数倍。这部分内存主要用于当需要顺序读取 数据的时候,如无法使用索引的情况下的全表扫描,全索引扫描等。在这种时候,MySQL 按照 数据的存储顺序依次读取数据块,每次读取的数据快首先会暂存在read_buffer_size中,当 buffer 空间被写满或者全部数据读取结束后,再将buffer中的数据返回给上层调用者,以提高效率. 该选项也被所有的村粗引擎使用: (1)当使用order by 排序时候会缓存临时文件中的索引。 (2)bulk insert into partitions操作。 (3)缓存内嵌或者嵌套的查询结果。 read_rnd_buffer_size: 和顺序读取相对应,当 MySQL 进行非顺序读取(随机读取)数据块的时候,会利用这个 缓冲区暂存读取的数据。如根据索引信息读取表数据,根据排序后的结果集与表进行Join等等。 总的来说,就是当数据块的读取需要满足一定的顺序的情况下,MySQL 就需要产生随机读取, 进而使用到 read_rnd_buffer_size 参数所设置的内存缓冲区。 thread_stack: 主要用来存放每一个线程自身的标识信息,如线程id,线程运行时基本信息等等, 我们可以通过 thread_stack 参数来设置为每一个线程栈分配多大的内存。 join_buffer_size: 应用程序经常会出现一些两表(或多表)Join的操作需求,MySQL在完成某些 Join 需求的时候(all/index join), 为了减少参与Join的“被驱动表”的读取次数以提高性能,需要使用到 Join Buffer 来协助完成 Join操作。 当 Join Buffer 太小,MySQL 不会将该 Buffer 存入磁盘文件,而是先将Join Buffer中的结果集与需要 Join 的表进行 Join 操作, 然后清空 Join Buffer 中的数据,继续将剩余的结果集写入此 Buffer 中,如此往复。这势必会造成被驱动表需要被多次读取, 成倍增加 IO 访问,降低效率。 sort_buffer_size: MySQL 用此内存区域进行排序操作(filesort),完成客户端的排序请求。 当我们设置的排序区缓存大小无法满足排序实际所需内存的时候, MySQL 会将数据写入磁盘文件来完成排序。由于磁盘和内存的读写性能完全不在一个数量级, 所以sort_buffer_size参数对排序操作的性能影响绝对不可小视。经常使用索引来完成排序操作。 主库执行: SQL>select sum(a.variable_value)/1024 kb from global_variables a where a.variable_name in ('read_buffer_size','read_rnd_buffer_size', 'sort_buffer_size','thread_stack', 'join_buffer_size','binlog_cache_size'); --------------------------------------------- 38144 SQL>select * from global_variables a where a.variable_name ='max_connections'; --------------------------------------------- MAX_CONNECTIONS 1500 SQL>select 38144*1500/1024/1024; ----------------------------------------- 54.56542969(这是计算线程需要的内存大小)