mysql 会话临时表空间、全局临时表空间、临时表、内存临时表、磁盘临时表及其监控,

mysql在一些情况下会使用临时表,这些情况包括使用union 、global order by 、子查询、distinct、INSERT ... SELECT 、 multiple-table UPDATEGROUP_CONCAT() or COUNT(DISTINCT) 、窗口函数window functions等,这些条件下,如果用于临时表的内存足够,所有数据都在内存中完成运算,则称为 in-memory temporary table,如果内存不足,则数据最终会溢出到磁盘,最终生成磁盘临时表,称为on-disk temporary table。也有一些条件,不会经过in-memory temporary table 到on-disk temporary table的过程,而是一开始就是磁盘临时表,例如表字段包括BLOB or TEXT (从mysql8.0.13开始,TempTable 引擎支持在内存临时表使用BLOB)、在union、union all中包括了最大列长度大于 512 (对于binary string类型是512字节,对于字符类型是512字符)等。具体的条件还有例外在https://dev.mysql.com/doc/refman/8.0/en/internal-temporary-tables.html都有详细描述,这里不再赘述。

对于临时表,mysql使用了4种引擎:
MEMORY,内存临时表引擎;
TempTable ,8.0系列引入,内存临时表和mmap条件下的磁盘临时表引擎;
MyISAM 磁盘临时表引擎,在MySQL 8.0.16以前的版本中使用;
innodb 磁盘临时表引擎,在MySQL 8.0.16及以后的版本是唯一使用临时表空间的磁盘临时表引擎。

以下展开详述。

TempTable:mysql8.0以后,引入了一个新的临时表引擎TempTable,用于作为内存或者磁盘临时表的存储引擎。这也是8.0默认的临时表存储引擎,由参数internal_tmp_mem_storage_engine控制,这个参数接受两个值TempTable、Memory,默认值为TempTable。对于TempTable引擎,使用temptable_max_ram参数规定了整个mysql实例范围内临时表的可用内存,并且不包括线程本地内存:
The temptable_max_ram setting does not account for the thread-local memory block allocated to each thread that uses the TempTable storage engine. The size of the thread-local memory block depends on the size of the thread's first memory allocation request. If the request is less than 1MB, which it is in most cases, the thread-local memory block size is 1MB. If the request is greater than 1MB, the thread-local memory block is approximately the same size as the initial memory request. The thread-local memory block is held in thread-local storage until thread exit.
如果由于单个sql使用的临时表内存超出了此设置、或者过多的使用的临时表导致所有临时表使用的内存总和超过此大小,则会发生TempTable overflow。此时,根据temptable_use_mmap参数配置的不同(on or off),则会发生两种情况:

    1,temptable_use_mmap为on,此时,mysql会在tmpdir参数指定的目录下,使用open新创建若干个临时文件,并通过write函数将文件初始化为0.。这个过程是串行的,即创建临时文件,初始化内容,再接着创建下一个文件。临时文件的大小,按照128MB+8字节、256MB +8字节、512M +8字节,然后再64M+8、128M+8、256M + 8……直到所有session创建的临时文件大小+内存临时表占用的空间两者的和满足此sql所需要的空间大小。此过程可以通过对mysql session进行strace追踪发现。
select thread_os_id from performance_schema.threads b where b.processlist_id = connection_id() \G    
strace -t -T -p 25332 -o 25332.trace
awk  'BEGIN {last1="";last2=""} {if  ( $2!=last1 ||  $3!=last2 ) { print $0};last1=$2;last2=$3 }'  25332.trace

19:06:41 ppoll([{fd=36, events=POLLIN|POLLPRI}], 1, {28764, 825280278}, [HUP INT QUIT USR2 TERM TSTP], 8) = 1 ([{fd=36, revents=POLLIN}], left {28746, 459693634}) <18.365615>
19:07:00 recvfrom(36, "u\0\0\0", 4, MSG_DONTWAIT, NULL, NULL) = 4 <0.000009>
19:07:00 recvfrom(36, "\3select count(person_name) from "..., 117, MSG_DONTWAIT, NULL, NULL) = 117 <0.000009>
19:07:00 mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0) = 0x7efd84060000 <0.000028>
19:07:00 mbind(0x7efd84060000, 1048576, MPOL_PREFERRED, NULL, 0, 0) = 0 <0.000020>
19:07:00 mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0) = 0x7efd3ddfc000 <0.000015>
19:07:00 mbind(0x7efd3ddfc000, 2097152, MPOL_PREFERRED, NULL, 0, 0) = 0 <0.000009>
19:07:00 mmap(NULL, 4194304, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0) = 0x7efd3d9fc000 <0.000018>
19:07:00 mbind(0x7efd3d9fc000, 4194304, MPOL_PREFERRED, NULL, 0, 0) = 0 <0.000014>
19:07:00 mmap(NULL, 8388608, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0) = 0x7efd3d1fc000 <0.000013>
19:07:00 mbind(0x7efd3d1fc000, 8388608, MPOL_PREFERRED, NULL, 0, 0) = 0 <0.000012>
19:07:00 mmap(NULL, 16777216, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0) = 0x7efd3c1fc000 <0.000017>
19:07:00 mbind(0x7efd3c1fc000, 16777216, MPOL_PREFERRED, NULL, 0, 0) = 0 <0.000013>
19:07:00 mmap(NULL, 33554432, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0) = 0x7efd2e000000 <0.000019>
19:07:00 mbind(0x7efd2e000000, 33554432, MPOL_PREFERRED, NULL, 0, 0) = 0 <0.000014>
19:07:01 mmap(NULL, 67108864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0) = 0x7efd24000000 <0.000014>
19:07:01 mbind(0x7efd24000000, 67108864, MPOL_PREFERRED, NULL, 0, 0) = 0 <0.000009>
19:07:03 open("/tmp/", O_RDWR|O_DIRECTORY|O_CLOEXEC|O_TMPFILE, 0600) = -1 EISDIR (Is a directory) <0.000015>
19:07:03 open("/tmp/mysql_temptable.ZvRoFe", O_RDWR|O_CREAT|O_EXCL, 0600) = 74 <0.000129>
19:07:03 unlink("/tmp/mysql_temptable.ZvRoFe") = 0 <0.000068>
19:07:03 lseek(74, 0, SEEK_END)         = 0 <0.000006>
19:07:03 write(74, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096 <0.000023>
19:07:04 write(74, "\0\0\0\0\0\0\0\0", 8) = 8 <0.000013>
19:07:04 lseek(74, 0, SEEK_SET)         = 0 <0.000007>
19:07:04 mmap(NULL, 134217736, PROT_READ|PROT_WRITE, MAP_SHARED, 74, 0) = 0x7efd1bfff000 <0.000019>
19:07:07 open("/tmp/", O_RDWR|O_DIRECTORY|O_CLOEXEC|O_TMPFILE, 0600) = -1 EISDIR (Is a directory) <0.000013>
19:07:07 open("/tmp/mysql_temptable.SUPMOH", O_RDWR|O_CREAT|O_EXCL, 0600) = 75 <0.006869>
19:07:07 unlink("/tmp/mysql_temptable.SUPMOH") = 0 <0.000075>
19:07:07 lseek(75, 0, SEEK_END)         = 0 <0.000008&g
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值