前⾔
在 MySQL 中,线程独享内存主要⽤于各客户端连接线程存储各种操作的独享数据,如线程栈信息,分组排序操作,数据读写缓冲,结果集暂存等等,⽽且⼤多数可以通过相关参数来控制内存的使⽤量。线程栈信息使⽤内存(thread_stack)
主要⽤来存放每⼀个线程⾃⾝的标识信息,如线程id,线程运⾏时基本信息等等,我们可以通过 thread_stack 参数来设置为每⼀个线程栈分配多⼤的内存。排序使⽤内存(sort_buffer_size)
MySQL ⽤此内存区域进⾏排序操作(filesort),完成客户端的排序请求。当我们设置的排序区缓存⼤⼩⽆法满⾜排序实际所需内存的时候,MySQL 会将数据写⼊磁盘⽂件来完成排序。由于磁盘和内存的读写性能完全不在⼀个数量级,所以sort_buffer_size参数对排序操作的性能影响绝对不可⼩视。经常使⽤索引来完成排序操作。Join操作使⽤内存(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 访问,降低效率。
顺序读取数据缓冲区使⽤内存(read_buffer_size)
这部分内存主要⽤于当需要顺序读取数据的时候,如⽆法使⽤索引的情况下的全表扫描,全索引扫描等。在这种时
候,MySQL 按照数据的存储顺序依次读取数据块,每次读取的数据快⾸先会暂存在read_buffer_size中,当 buffer 空间被写满或者全部数据读取结束后,再将buffer中的数据返回给上层调⽤者,以提⾼效率。随机读取数据缓冲区使⽤内存(read_rnd_buffer_size)
和顺序读取相对应,当 MySQL 进⾏⾮顺序读取(随机读取)数据块的时候,会利⽤这个缓冲区暂存读取的数据。如根据索引信息读取表数据,根据排序后的结果集与表进⾏Join等等。总的来说,就是当数据块的读取需要满⾜⼀定的顺序的情况下,MySQL 就需要产⽣随机读取,进⽽使⽤到 read_rnd_buffer_size 参数所设置的内存缓冲区。连接信息及返回客户端前结果集暂存使⽤内存(net_buffer_size)
这部分⽤来存放客户端连接线程的连接信息和返回客户端的结果集。当 MySQL 开始产⽣可以返回的结果集,会在通过⽹络返回给客户端请求线程之前,会先暂存在通过 net_buffer_size 所设置的缓冲区中,等满⾜⼀定⼤⼩的时候才开始向客户端发送,以提⾼⽹络传输效率。不过,net_buffer_size 参数所设置的仅仅只是该缓存区的初始化⼤⼩,MySQL 会根据实际需要⾃⾏申请更多的内存以满⾜需求,但最⼤不会超过 max_allowed_packet 参数⼤⼩。批量插⼊暂存使⽤内存(bulk_insert_buffer_size)
当我们使⽤如 insert … values(…),(…),(…)… 的⽅式进⾏批量插⼊的时候,MySQL 会先将提交的数据放如⼀个缓存空间中,当该缓存空间被写满或者提交完所有数据之后,MySQL 才会⼀次性将该缓存空间中的数据写⼊数据库并清空缓存。此外,当我们进⾏ LOAD DATA INFILE 操作来将⽂本⽂件中的数据 Load 进数据库的时候,同样会使⽤到此缓冲区。临时表使⽤内存(tmp_table_size)
当我们进⾏⼀些特殊操作如需要使⽤临时表才能完成的 Order By,Group By 等等,MySQL 可能需要使⽤到临时表。当我们的临时表较⼩(⼩于 tmp_table_size 参数所设置的⼤⼩)的时候,MySQL 会将临时表创建成内存临时表,只有当
tmp_table_size 所设置的⼤⼩⽆法装下整个临时表的时候,MySQL 才会将该表创建成 MyISAM 存储引擎的表存放在磁盘上。不过,当另⼀个系统参数 max_heap_table_size 的⼤⼩还⼩于 tmp_table_size 的时候,MySQL 将使⽤
max_heap_table_size 参数所设置⼤⼩作为最⼤的内存临时表⼤⼩,⽽忽略 tmp_table_size 所设置的值。⽽且tmp_table_size 参数从 MySQL 5.1.2 才开始有,之前⼀直使⽤ max_heap_table_size。总结
上⾯所列举的 MySQL 线程独享内存仅仅只是所有线程独享内存中的部分,并不是全部,选择的原则是可能对 MySQL 的性能产⽣较⼤的影响,且可以通过系统参数进⾏调节。
由于以上内存都是线程独享,极端情况下的内存总体使⽤量将是所有连接线程的总倍数。所以各位朋友在设置过程中⼀定要谨
慎,切不可为了提升性能就盲⽬的增⼤各参数值,避免因为内存不够⽽产⽣ Out Of Memory 异常或者是严重的 Swap 交换反⽽降低整体性能。
因篇幅问题不能全部显示,请点此查看更多更全内容