另一种方法是直接将结果导出成.csv 文件。MySQL 提供语法,用来将查询结果导出到服务端本地目录:select * from db1.t where a>900 into outfile '/server_tmp/t.csv';得到.csv 导出文件后,你就可以用下面的 load data 命令将数据导入到目标表 db2.t 中:load data infile '/server_tmp/t.csv' into table db2.t; 物理拷贝:在 MySQL 5.6 版本引入了可传输表空间(transportable tablespace) 的方法,可以通过导出 + 导入表空间的方式,实现物理拷贝表的功能。 49、grant 和 flush privileges语句grant语句会同时修改数据表和内存,判断权限的时候使用的内存数据,因此,规范使用是不需要加上 flush privileges 语句。 flush privileges 语句本身会用数据表的数据重建一份内存权限数据,所以在权限数据可能存在不一致的情况下再使用。 50、要不要使用分区表?分区并不是越细越好。实际上,单表或者单分区的数据一千万行,只要没有特别大的索引,对于现在的硬件能力来说都已经是小表了。 分区也不要提前预留太多,在使用之前预先创建即可。比如,如果是按月分区,每年年底时再把下一年度的 12 个新分区创建上即可。对于没有数据的历史分区,要及时的 drop 掉。 51、join 用法使用 left join 左边的表不一定是驱动表 如果需要 left join 的语义,就不能把被驱动表的字段放在 where 条件里面做等值判断或不等值判断,必须都写在 on 里面 标准的 group by 语句,是需要在 select 部分加一个聚合函数,比如select a,count(*) from t group by a order by null; 52、MySQL 有哪些自增ID?各自场景是什么?表的自增 ID 达到上限之后,在申请值不会变化,进而导致联系插入数据的时候报主键冲突错误。 row_id 达到上限之后,归 0 在重新递增,如果出现相同的 row_id 后写的数据会覆盖之前的数据。 Xid 只需要不在同一个 binlog 文件出现重复值即可,理论上会出现重复值,但概率极小可忽略不计。 InnoDB 的 max_trx_id 递增值每次 MySQL 重启会保存起来。 Xid 是由 server 层维护的。InnoDB 内部使用 Xid,就是为了能够在 InnoDB 事务和 server 之间做关联。但是,InnoDB 自己的 trx_id,是另外维护的。 thread_id 是我们使用中最常见的,而且也是处理得最好的一个自增 id 逻辑了。使用了insert_unique算法 53、Xid 在 MySQL 内部是怎么生成的呢?MySQL 内部维护了一个全局变量 global_query_id,每次执行语句(包括select语句)的时候将它赋值给 Query_id,然后给这个变量加 1。如果当前语句是这个事务执行的第一条语句,那么 MySQL 还会同时把 Query_id 赋值给这个事务的 Xid。 而 global_query_id 是一个纯内存变量,重启之后就清零了。所以你就知道了,在同一个数据库实例中,不同事务的 Xid 也是有可能相同的。但是 MySQL 重启之后会重新生成新的 binlog 文件,这就保证了,同一个 binlog 文件里,Xid 一定是惟一的。 锁相关54、说一下 MySQL 的锁 MySQL 在 server 层 和 存储引擎层 都运用了大量的锁 MySQL server 层需要讲两种锁,第一种是MDL(metadata lock) 元数据锁,第二种则 Table Lock 表锁。 MDL 又名元数据锁,那么什么是元数据呢,任何描述数据库的内容就是元数据,比如我们的表结构、库结构等都是元数据。那为什么需要 MDL 呢? 主要解决两个问题:事务隔离问题;数据复制问题 InnoDB 有五种表级锁:IS(意向读锁);IX(意向写锁);S(读);X(写);AUTO-INC 在对表进行select/insert/delete/update语句时候不会加表级锁 IS和IX的作用是为了判断表中是否有已经被加锁的记录 自增主键的保障就是有 AUTO-INC 锁,是语句级别的:为表的某个列添加 AUTO_INCREMENT 属性,之后在插记录时,可以不指定该列的值,系统会动为它赋上单调递增的值。 InnoDB 4 种行级锁 RecordLock:记录锁 GapLock:间隙锁解决幻读;前一次查询不存在的东西在下一次查询出现了,其实就是事务A中的两次查询之间事务B执行插入操作被事务A感知了 Next-KeyLock:锁住某条记录又想阻止其它事务在改记录前面的间隙插入新纪录 InsertIntentionLock:插入意向锁;如果插入到同一行间隙中的多个事务未插入到间隙内的同一位置则无须等待 行锁和表锁的抉择 全表扫描用行级锁 55、什么是幻读?值在同一个事务中,存在前后两次查询同一个范围的数据,第二次看到了第一次没有查询到的数据。 幻读出现的场景: 事务的隔离级别是可重复读,且是当前读。 幻读指新插入的行。 幻读带来的问题: 对行锁语义的破坏 破坏了数据一致性 解决: 加间隙锁,锁住行与行之间的间隙,阻塞新插入的操作。 带来的问题:降低并发度,可能导致死锁。 其它为什么系列 56、为什么 MySQL 会抖一下?脏页会被后台线程自动 flush,也会由于数据页淘汰而触发 flush,而刷脏页的过程由于会占用资源,可能会让你的更新和查询语句的响应时间长一些。 57、为什么删除了表,表文件的大小还是没变?数据项删除之后 InnoDB 某个页 page A 会被标记为可复用。 delete 命令把整个表的数据删除,结果就是,所有的数据页都会被标记为可复用。但是磁盘上,文件不会变小。 经过大量增删改的表,都是可能是存在空洞的。这些空洞也占空间所以,如果能够把这些空洞去掉,就能达到收缩表空间的目的。 重建表,就可以达到这样的目的。可以使用 alter table A engine=InnoDB 命令来重建表。 58、count(*)实现方式以及各种 count 对比对于 count(主键 id) 来说,InnoDB 引擎会遍历整张表,把每一行的 id 值都取出来,返回给 server 层。server 层拿到 id 后,判断是不可能为空的,就按行累加。 |
