1、ID自增主键
一张表有ID自增主键,当insert到17条记录之后,删除15,16,17的记录,再把MySQL重启,再insert一条记录,这条记录的ID是18还是15?
- InnoDB : 如果不重启是15,重启后是18,因为InnoDB表将自增主键的最大ID记录到内存中,重启数据库数据库或者对表OPTIMEZE操作,都会使最大ID丢失
- MyISAM:18,MyISAM将自增主键记录在数据文件中,不会丢失
- 建议: 不建议物理删除
2、InnoDB于MyISAM的区别
| | InnoDB | MyISAM | | :—-: | :—-: | :—-: | | 事务 | 支持 | 不支持 | | 存储限制 | 64TB | 无 | | 锁粒度 | 行锁 | 表锁 | | 外键 | 支持 | 不支持 | | 崩溃恢复 | 支持 | 不支持 |
3、什么是索引?
索引是一种数据结构,数据库除了保存数据本身,还维护了一个满足特定查找算法的数据结构,这种数据结构就是索引。
4、索引的优缺点?
- 优点:
- 提高检索效率,降低IO成本
- 降低数据排序的成本,降低CPU消耗
缺点:
出现在where子句中的列
- 索引列基数越大,索引效果越好
- 根据情况,使用复合索引
- 避免创建过多索引
- 主键选择较短的数据类型
-
6、索引使用的注意点
where子句中避免使用 !=,<,>,or导致全表扫描
- 避免like ‘%….’
- 避免对索引列进行表达式操作,函数操作
- 注意复合索引的顺序
避免索引列的值进行类型转换,如 varchar 的参数必须要加引号
7、B-Tree树与B+树之间的区别
B-Tree : 每个节点存储key 和 数据data
- B+Tree:非叶子节点只存储key的信息,数据记录都存放在叶子节点
优化:B+Tree是对B-Tree树的优化,每页的存储空间是有序的,如果data的数据较大将会导致key的数量较小,当存储的数据量较大时会导致B-Tree深度较大增大了I/O次数。B+Tree树非叶子节点只存放key值,data按顺序存放在同一层的叶子节点上,达到降低树高度减少I/O的目的
8、B-Tree树有哪些索引
聚簇索引:叶子节点存放整条数据
-
9、聚簇索引的注意点
最好为自增主键
- 避免出现页分裂问题
- 避免数据移动,引起性能消耗
- 二级索引查询数据要先查询到叶子节点的主键,然后根据主键查询数据
- 主键ID建议使用整型,每个主键索引的B+Tree节点可以存储更多的key,减少二级索引叶子节点的内存占用
10、最左匹配原则
假如索引(a,b,c)那么 a 、(a,b)、(a,b,c)都可以用到索引,带头大哥不能死11、事务四种隔离级别
| 级别 | 定义 | 存在的问题 | | —- | —- | —- | | READ UNCOMMITTED | 未提交的事务对其他事务也可见 | 脏读 | | READ COMMITTED | 一个事务从开始到结束,所做的任何修改对其他事务都不可见 | 不可重复读 | | REPEATABLE READ(MySQL默认级别) | 一个事务中多次读取同样的记录是一致的 | 幻读 | | SERIALIZABLE | 强制事务串行,读取每一行数据都加锁 | 超时和锁竞争 |
12、MVCC
- 概念:多版本并发控制,用一种用来解决读写冲突的无锁并发控制,是通过保存数据在某个时间点的快照实现的。MVCC只在REPEATABLE READ 和 READ COMMITED两个隔离级别下工作
- InnoDB的MVCC,通过在每行记录后面保存两个隐藏的列来实现,一列保存行的创建时间(系统版本号),一个保存行的过期时间
演示增删改查四个操作下MVCC干了什么
INSERT : 事务开始时,获取自身版本号,假设 == V1 | 数据记录 | 版本号 | 过期时间 | | —- | —- | —- | | 表记录A | V1 | undefined |
UPDATE: 事务开始时,获取自身版本号,假设 == V2 | 数据记录 | 版本号 | 过期时间 | | —- | —- | —- | | 表记录A | V1 | V2 | | 表记录A | V2 | undefined |
SELECT (RR级别下): 事务开始时,获取自身版本号,假设 == V3,在V3开始后事务V4修改了表记录A | 数据记录 | 版本号 | 过期时间 | | —- | —- | —- | | 表记录A | V1 | V4 | | 表记录A | V4 | undefined |
- InnoDB只查询版本号小于或等于当前版本的记录行(<= V3)
- 行的过期时间要么未定义,要么大于当前版本( > V3)
- 这样查询到的就是V1版本,保证了REPEATABLE READ,至于怎么读到V1的版本,是每次更新记录的时候,InnoDB都会保存一条undo log 可以回退到上一个版本,比如原本 a= 4 改为 3,就会记录一条3+1,那么4-3-2-1,只要通过undo log反推就可以获取前几个版本的数据
- DELETE:事务开始时,获取自身版本号,假设 == V5 | 数据记录 | 版本号 | 过期时间 | | —- | —- | —- | | 表记录A | V1 | V5 |
13、锁的机制
- Innodb 的行锁是怎么实现的?
- Innodb 的锁的策略为 next-key 锁,即 record lock + gap lock ,是通过在 index 上加 lock 实现的。
- 如果 index 为 unique index ,则降级为 record lock 行锁。
- 如果是普通 index ,则为 next-key lock 。
- 如果没有 index ,则直接锁住全表,即表锁
- Innodb 的锁的策略为 next-key 锁,即 record lock + gap lock ,是通过在 index 上加 lock 实现的。
- 操作类型分类:读锁(共享锁),写锁(排他锁)
- 读锁:多个读锁可以共同访问互不影响
- 写锁:操作未完成前,会阻塞其他读写操作
- 粒度分类:表锁和行锁
- 悲观锁:读取数据时加锁,修改数据也加锁
- 乐观锁:大多数基本数据版本号实现,为数据库表增加一个version字段,读取的时候当版本号version读出,更新时version+1,如果新的版本号大于数据库内的版本号就更新,否则就判定为过期数据(CAS : Compare And Swap)
- 死锁:两个或者多个事务相互等待对方已锁定的资源,而彼此都不为协助对方达成操作目而主动释放已锁定的资源,这样的情况就称为死锁,解决方法如下:
- 减少锁的范围,合理设计索引
- 设置锁超时时间
- 锁检查机制 : InnoDB的死锁检测是通过等待图(Wait-For-Graph)的算法实现的,即检查所有在一个锁上等待的事务是否已经成环;如果成环了说明已经出现死锁,根据一定的策略将某个事务回退将环切断而解除死锁
- 间隙锁:当我们使用范围条件检索数据,并请求共享排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁,对于键值在范围内但不存在的记录,叫做间隙(比如数据库本来存在id为1、3、4、5的记录,然后事务A范围更新1~5的记录,此时如果另一个事务插入id = 2的记录,在事务A调教事务之前会被阻塞)
14、MySQL查询执行顺序
| (7) SELECT
(8) DISTINCT
(1) FROM
(3)JOIN
(2) ON
(4) WHERE
(5) GROUP BY
(6) HAVING
(9) ORDER BY
(10) LIMIT| | :—- |
15、sql优化
16、MySQL日志(具体可见一条SQL更新语句如何执行)
- InnoDB引擎独有的redo log、Service层的binlog
两者的区别:
statment : 每条会修改数据的sql都会记录,如 update A set a = 1 where id in (1,3,5);
- 优点:减少日志量,节约I/O,提高了性能
- 缺点:额外记录语句执行时的相关信息,另外 MySQL 的复制像一些特定函数功能,slave 可与 master 上要保持一致会有很多相关问题(如 sleep() 函数,last_insert_id(),以及 user-defined functions(udf) 会出现问题)。
- row : 会记录针对每行的修改,如上面的批量更新,就会记录三条记录
- 优点:记录每条修改记录
- 缺点:产生大量日志,如果存在alter语句,每行都发生了修改那么会产生大量的日志
- mixedlevel:两种的混合使用
- 总结:statement占用空间小,传输给slave快,但是没有row可靠
18、主从复制的流程
- Master上的binlog dump将master的binlog event传给slave
- slave的I/O线程接受binlog event并写入relay log
- slave的SQL线程读取relay log执行
19、mysqldump 和 xtrabackup
- mysqldump 原理:在备份 InnoDB 表的时候,加上 –master-data=1 –single-transaction 选项,在事务开始时刻,记录下 binlog pos 点,然后利用 MVCC 来获取一致的数据,由于是一个长事务,在写入和更新量很大的数据库上,将产生非常多的 undo ,显著影响性能,所以要慎用
- xtrabackup:实际上是物理备份+逻辑备份的组合
- 在备份 InnoDB 表的时候,它拷贝 ibd 文件,并一刻不停的监视 redo log 的变化,append 到自己的事务日志文件。在拷贝 ibd 文件过程中,ibd文件本身可能被写”花”,这都不是问题,因为在拷贝完成后的第一个 prepare 阶段,xtrabackup 采用类似于 Innodb 崩溃恢复的方法,把数据文件恢复到与日志文件一致的状态,并把未提交的事务回滚。
- 如果同时需要备份 MyISAM 表以及 InnoDB 表结构等文件,那么就需要用
flush tables with lock来获得全局锁,开始拷贝这些不再变化的文件,同时获得 binlog 位置,拷贝结束后释放锁,也停止对 redo log 的监视
