You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
因为在一些特殊情况下,还是需要将主机的临时表同步到备机的,比如主机上执行 insert into t1 select * from temp1,其中t1是普通表,而temp1是临时表。当binlog格式为statement时,这条语句会被记录到binlog,然后同步到备机,在备机上replay,若备机之前没有将主机上的临时表同步过来,那这条语句的replay就会出现问题。因此在statement格式下,对临时表的操作如创建、删除及其它DML语句都必须记录binlog,然后同步到备机执行replay。但在row格式下,因为binlog中已经记录了实际的row,那么对临时表的创建、DML语句是不是记录binlog就不是那么重要了
两个容易误解的概念
临时表的特性
临时表适合 join 优化的原因
临时表在分库分表场景下的应用
一般分库分表的场景,就是要把一个逻辑上的大表分散到不同的数据库实例上。比如,将一个大表 ht,按照字段 f,拆分成 1024 个分表,然后分布到 32 个数据库实例上,如下图:
![image](https://user-images.githubusercontent.com/24617415/69517645-4d037180-0f90-11ea-808d-1ab61dfb739f.png)
在这个架构中,是以字段 f 作为分区键,如果查询条件中没有字段 f,例如:
这种情况就只能到所有分区中查询满足条件的数据,一般有两种解决方案:
优势是速度快,拿到分库的数据之后,直接在内存中参与计算。
缺点在于需要开发的工作量比较大,特别是涉及到复杂的操作,而且对 proxy 端的压力比较大,容易出现内存不够和 CPU 瓶颈问题
执行流程大致为:
流程图如下:
![image](https://user-images.githubusercontent.com/24617415/69518134-bc2d9580-0f91-11ea-87e1-dc6bb46d41a6.png)
临时表可以重名的原因
这个语句执行时,MySQL 要给这个 InnoDB 表创建一个 frm 文件保存表结构定义,这个 frm 文件放在临时文件目录下,文件名的后缀是 .frm,前缀是 #sql{进程id}_{线程id}_序列号
而表中数据的存放方式,在不同的 MySQL 版本中有不同的处理方式:
从文件的前缀规则来看,创建一个叫做 t1 的临时表和普通表 t1 在存储上是不同的,所以可以和普通表重名。
而且 MySQL 维护数据表时,除了物理上有文件外,内存里也有一套机制区别不同的表,每个表都对应一个 table_def_key
也就是说,session A 和 session B 创建的两个临时表 t1,它们的 table_def_key 不同,磁盘文件名也不同,所以可以并存。
在实现上,每个线程都维护了自己的临时表链表,每次 session 内操作表的时候,先遍历链表,检查是否有这个名字的临时表,如果有就优先操作临时表,如果没有再操作普通表;在 session 结束的时候,对链表里的每个临时表,执行 DROP TEMPORARY TABLE + 表名 的操作
临时表和主备复制
在 statement 和 mixed 格式下,所有对临时表的操作都要记录 binlog,但在 row 格式下,只有 Drop table 才会记录 binlog。
因为在一些特殊情况下,还是需要将主机的临时表同步到备机的,比如主机上执行 insert into t1 select * from temp1,其中t1是普通表,而temp1是临时表。当binlog格式为statement时,这条语句会被记录到binlog,然后同步到备机,在备机上replay,若备机之前没有将主机上的临时表同步过来,那这条语句的replay就会出现问题。因此在statement格式下,对临时表的操作如创建、删除及其它DML语句都必须记录binlog,然后同步到备机执行replay。但在row格式下,因为binlog中已经记录了实际的row,那么对临时表的创建、DML语句是不是记录binlog就不是那么重要了
对临时表的删除还是要记录binlog。因为用户可以随时修改binlog的格式,若之前创建临时表时是statement格式,而创建成功后,又修改为row格式,若row格式下删除表不记录binlog,那么在备机上就会产生问题,创建了临时表,但却没有删除它。因此对drop table语句,无论binlog格式采用statement或是row格式,都会记录binlog
The text was updated successfully, but these errors were encountered: