临时表的特性,临时表是怎么写binlog的
通过create temporary table …创建的临时表,仅对当前会话可见,当当前会话线程退出以后,将会自动删除临时表。
需要注意的是,如果创建的临时表和已存在的表重名,那么访问该表明时,是访问临时表,如:
mysql> use sam
Database changed
mysql> show tables;
+---------------+
| Tables_in_sam |
+---------------+
| bak |
| sam |
| test |
+---------------+
3 rows in set (0.00 sec)
mysql> desc sam;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> create temporary table sam (id int,name int);
Query OK, 0 rows affected (0.01 sec)
mysql> desc sam;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
当创建临时表以后,会在tmpdir下有一个区别于同名表的frm文件,并不是以临时表名来命名文件:
[root@mysql1 tmp]# ls
#sqlffe_12_0.frm
所以使用rename将临时表改名是不行的
mysql> create temporary table tmp(id int);
Query OK, 0 rows affected (0.01 sec)
mysql> rename table tmp to tmp_test;
ERROR 1017 (HY000): Can't find file: './sam/tmp.frm' (errno: 2 - No such file or directory)
但alter table … rename … 的方式可以执行:
mysql> alter table tmp rename to temp_test;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
所以可以判定,rename table是在数据库目录下去mv文件;而alter table … rename … 会先确认操作表对应的文件在哪里,再去改名。
那么临时表是怎么写binlog呢?
1.如果是row格式binlog,临时表的操作不会记录binlog;
2.如果是statement格式binlog,会记录临时表的操作,并且在会话退出时,会写入一个drop temporary table …,表示会话退出时自动删除临时表。
第一点很好理解,由于row格式是记录行的变化,不需要依赖临时表的数据,同时,如果使用binlog来恢复出实例,那么对于之前创建的临时表来说,恢复出来的实例的所有会话,都是不可见的,也就没有必要记录临时表的binlog了。
第二点,我们来做些实验:
我们创建一个临时表,插入一行数据,并且推出会话,看下binlog是怎么记录的。
mysql> flush logs;
Query OK, 0 row