美文网首页
MySQL的临时表

MySQL的临时表

作者: 冷若秋枫 | 来源:发表于2020-02-17 09:43 被阅读0次

    内存表与临时表的区别

    • 内存表,指的是使用 Memory 引擎的表,建表语法是 create table … engine=memory。这种表的数据都保存在内存里,系统重启的时候会被清空,但是表结构还在。除了这两个特性看上去比较“奇怪”外,从其他的特征上看,它就是一个正常的表。
    • 临时表,可以使用各种引擎类型 。如果是使用 InnoDB 引擎或者 MyISAM 引擎的临时表,写数据的时候是写到磁盘上的。临时表也可以使用 Memory 引擎。

    临时表的特性

    • 建表语法是 create temporary table …。
    • 一个临时表只能被创建它的 session 访问,对其他线程不可见。


    所以,图中 session A 创建的临时表 t,对于 session B 就是不可见的。

    • 临时表可以与普通表同名。session A 内有同名的临时表和普通表的时候,show create 语句,以及增删改查语句访问的是临时表。
    • show tables 命令不显示临时表。

    由于临时表只能被创建它的 session 访问,所以在这个 session 结束的时候,会自动删除临时表。也正是由于这个特性,临时表就特别适合我们文章开头的 join 优化这种场景。为什么呢?

    原因主要包括以下两个方面:

    • 不同 session 的临时表是可以重名的,如果有多个 session 同时执行 join 优化,不需要担心表名重复导致建表失败的问题。
    • 不需要担心数据删除问题。如果使用普通表,在流程执行过程中客户端发生了异常断开,或者数据库发生异常重启,还需要专门来清理中间过程中生成的数据表。而临时表由于会自动回收,所以不需要这个额外的操作。

    临时表为什么可以重名

    MySQL 维护数据表,除了物理上要有文件外,内存里面也有一套机制区别不同的表,每个表都对应一个 table_def_key。

    • 一个普通表的 table_def_key 的值是由“库名 + 表名”得到的,所以如果你要在同一个库下创建两个同名的普通表,创建第二个表的过程中就会发现 table_def_key 已经存在了。

    • 而对于临时表,table_def_key 在“库名 + 表名”基础上,又加入了“server_id+thread_id”。

    也就是说,session A 和 sessionB 创建的两个临时表 t1,它们的 table_def_key 不同,磁盘文件名也不同,因此可以并存。

    在实现上,每个线程都维护了自己的临时表链表。这样每次 session 内操作表的时候,先遍历链表,检查是否有这个名字的临时表,如果有就优先操作临时表,如果没有再操作普通表;在 session 结束的时候,对链表里的每个临时表,执行 “DROP TEMPORARY TABLE + 表名”操作。

    备库执行怎么处理主库上不同的线程创建同名的临时表

    主库 M 上的两个 session 创建了同名的临时表 t1,这两个 create temporary table t1 语句都会被传到备库 S 上。

    备库线程在执行的时候,要把这两个 t1 表当做两个不同的临时表来处理。

    MySQL 在记录 binlog 的时候,会把主库执行这个语句的线程 id 写到 binlog 中。这样,在备库的应用线程就能够知道执行每个语句的主库线程 id,并利用这个线程 id 来构造临时表的 table_def_key:

    • session A 的临时表 t1,在备库的 table_def_key 就是:库名 +t1+“M 的 serverid”+“session A 的 thread_id”;
    • session B 的临时表 t1,在备库的 table_def_key 就是 :库名 +t1+“M 的 serverid”+“session B 的 thread_id”。

    由于 table_def_key 不同,所以这两个表在备库的应用线程里面是不会冲突的。

    相关文章

      网友评论

          本文标题:MySQL的临时表

          本文链接:https://www.haomeiwen.com/subject/awovfhtx.html