学习 mysql实战45讲 笔记,用于后期检验

仅供自己复习用

 

第一章

1. MySQL的框架有几个组件, 各是什么作用? 

 连接器,缓存器,分析器,优化器,执行器
2. Server层和存储引擎层各是什么作用?

server层提供核心组件的功能,同时提供视图,执行过程等和一些函数操作,引擎层主要对应数据的操作

3. you have an error in your SQL syntax 这个保存是在词法分析里还是在语法分析里报错?

语法分析,词法分析主要解析出sql语句中的字符串代表什么意思

4. 对于表的操作权限验证在哪里进行?

执行器中

5. 执行器的执行查询语句的流程是什么样的? 

比如要查询数据id=10的语句

1.调用数据引擎的查询接口获取第一行数据,判断是不是张三,如果是则记录到结果集

2.获取下一行,执行上面的判断,一直到最后一行.

3.将上面执行所有满足条件的结果集返回给客户端.

针对索引也是差不多的,第一次取满足条件的第一行,之后取满足条件的下一行.

 

第二章

1. redo log的概念是什么? 为什么会存在.

重做日志,redolog是对记录修改之后的物理日志,记录的是数据页的物理修改,而不是某一行或某几行修改成怎样怎样,它用来崩溃恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)。记录格式(数据文件、数据页、数据行、操作类型、操作值)

正常mysql修改数据时,要将操作写入磁盘,然后磁盘每次也需要找到对应的那条数据,这样io成本过高,当有数据更新操作时,innodb会先将数据记录在redo log中,并更新内存,在合适的时间再将操作写入磁盘.同时由于更新数据的时候引擎并不是按条更新的,而是以页为最小单位更新。如果没有redolog,每次更新一条数据都要把整页的数据刷新到磁盘。如果更新多条数据,很可能一次就要更新多页,而且这些io是随机io,磁盘i/o就会多且慢。有了redolog,就不需要每次直接按页更新磁盘,而是把更新写到redolog中,然后等空闲时间再把redolog中的更新写入到磁盘。这样做的好处是redolog是顺序写的,而且是按条不是按页写。所以虽然多了一步,实际上是比直接更新快的。

redo log是固定大小的,从头开始写,当写到末尾时会循环重头再来,其中存在write pos代表当前记录位置,同时ckeckpoint记录当前要擦除的位置,系统空闲时会将部分redolog操作记录到硬盘,同时更新checkpoint.

 

2. 什么是WAL(write-ahead log)机制, 好处是什么.

先记录日志,再记录磁盘,好处就是上面的redo log 减少IO操作\

 

3. redo log 为什么可以保证crash safe机制.

crash safe,即当服务器突然断电或宕机,需要保证已提交的数据或修改不会丢失,未提交的数据能够自动回滚


4. binlog的概念是什么, 起到什么作用, 可以做crash safe吗? 

binlog是逻辑日志。其中一种形式是记录的原始sql语句,另一种形式是记录row上的数据,比如update t set c = c +1 where id = 1; binlog是数据库server层的。和数据是隔离开来的,他可以用来主从复制,和备份恢复数据库用,他不能做到crash safe,假设数据先存入,再记录binlog,存入后mysql崩溃,此时数据库中有数据,而binlog中没有,反之,先记录binlog再提交事务,记录binlog后mysql崩溃,此时binlog比数据库中多出一条数据


5. binlog和redolog的不同点有哪些? 

binlog属于数据引擎的上层server层,redolog是属于数据引擎层

redo log是物理日志,记录的是“在某个数据页上做了什么修改”;binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这一行的c字段加1 ”。

redo log是循环写的,空间固定会用完;binlog是可以追加写入的。“追加写”是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。


7. 执行器和innoDB在执行update语句时候的流程是什么样的?

执行器先去找数据引擎要需要更新的行,引擎查找该行,如果改行数据页在内存中则直接返回给执行器,如果不在则从硬盘中读到内存,然后再返回

执行器拿到引擎给的行数据,将数据修改,得到这行新数据,再调用引擎接口写入这行的新数据

引擎将这行更新到内存中,同时记录redo log 此时redo log处于准备阶段 然后告诉执行器执行完成,随时可以提交事务

执行器记录binlog,并记录到磁盘

执行器调用引擎的提交事务接口,引擎把刚刚写入的redolog改为提交状态,更新完成


8. 如果数据库误操作, 如何执行数据恢复?

binlog会记录所有的逻辑操作,并且是采用“追加写”的形式

同时系统会定期做整库备份。这里的“定期”取决于系统的重要性,可以是一天一备,也可以是一周一备

首先,找到最近的一次全量备份

然后,从备份的时间点开始,将备份的binlog依次取出来,重放到误删表之前的那个时刻。


9. 什么是两阶段提交, 为什么需要两阶段提交, 两阶段提交怎么保证数据库中两份日志间的逻辑一致性?

为了保证redo log 和 bin log的一致性

1 prepare阶段 2 写binlog 3 commit
当在2之前崩溃时
重启恢复:后发现没有commit,回滚。备份恢复:没有binlog 。
一致
当在3之前崩溃
重启恢复:虽没有commit,但满足prepare和binlog完整,所以重启后会自动commit。备份:有binlog. 一致 

 

第三章

1、事务的特性:原子性、一致性、隔离性、持久性
2、多事务同时执行的时候,可能会出现的问题:脏读、不可重复读、幻读
3、事务隔离级别:读未提交、读提交、可重复读、串行化
4、不同事务隔离级别的区别:
读未提交:一个事务还未提交,它所做的变更就可以被别的事务看到
读提交:一个事务提交之后,它所做的变更才可以被别的事务看到
可重复读:一个事务执行过程中看到的数据是一致的。未提交的更改对其他事务是不可见的
串行化:对应一个记录会加读写锁,出现冲突的时候,后访问的事务必须等前一个事务执行完成才能继续执行
5、配置方法:启动参数transaction-isolation
6、事务隔离的实现:每条记录在更新的时候都会同时记录一条回滚操作。同一条记录在系统中可以存在多个版本,这就是数据库的多版本并发控制(MVCC)。
7、回滚日志什么时候删除?系统会判断当没有事务需要用到这些回滚日志的时候,回滚日志会被删除。
8、什么时候不需要了?当系统里么有比这个回滚日志更早的read-view的时候。
9、为什么尽量不要使用长事务。长事务意味着系统里面会存在很老的事务视图,在这个事务提交之前,回滚记录都要保留,这会导致大量占用存储空间。除此之外,长事务还占用锁资源,可能会拖垮库。
10、事务启动方式:一、显式启动事务语句,begin或者start transaction,提交commit,回滚rollback;二、set autocommit=0,该命令会把这个线程的自动提交关掉。这样只要执行一个select语句,事务就启动,并不会自动提交,直到主动执行commit或rollback或断开连接。
11、建议使用方法一,如果考虑多一次交互问题,可以使用commit work and chain语法。在autocommit=1的情况下用begin显式启动事务,如果执行commit则提交事务。如果执行commit work and chain则提交事务并自动启动下一个事务。

 

第四章

.1.索引的作用:提高数据查询效率
2.常见索引模型:哈希表、有序数组、搜索树
3.哈希表:键 - 值(key - value)。
4.哈希思路:把值放在数组里,用一个哈希函数把key换算成一个确定的位置,然后把value放在数组的这个位置
5.哈希冲突的处理办法:链表
6.哈希表适用场景:只有等值查询的场景
7.有序数组:按顺序存储。查询用二分法就可以快速查询,时间复杂度是:O(log(N))
8.有序数组查询效率高,更新效率低
9.有序数组的适用场景:静态存储引擎。
10.二叉搜索树:每个节点的左儿子小于父节点,父节点又小于右儿子
11.二叉搜索树:查询时间复杂度O(log(N)),更新时间复杂度O(log(N))
12.数据库存储大多不适用二叉树,因为树高过高,会适用N叉树
13.InnoDB中的索引模型:B+Tree
14.索引类型:主键索引、非主键索引
主键索引的叶子节点存的是整行的数据(聚簇索引),非主键索引的叶子节点内容是主键的值(二级索引)
15.主键索引和普通索引的区别:主键索引只要搜索ID这个B+Tree即可拿到数据。普通索引先搜索索引拿到主键值,再到主键索引树搜索一次(回表)
16.一个数据页满了,按照B+Tree算法,新增加一个数据页,叫做页分裂,会导致性能下降。空间利用率降低大概50%。当相邻的两个数据页利用率很低的时候会做数据页合并,合并的过程是分裂过程的逆过程。
17.从性能和存储空间方面考量,自增主键往往是更合理的选择。

 

第五章

回表:回到主键索引树搜索的过程,称为回表

学习 mysql实战45讲 笔记,用于后期检验

左图是主键索引,右图是非主键索引,主键索引叶子节点上是数据行,非主键索引叶子节点上是改行数据的主键.

比如要通过K字段作为条件,查询一个非主键列,则需要先查询到主键,在用主键回表到主键索引上查询到整行数据

 

覆盖索引:某索引已经覆盖了查询需求,称为覆盖索引,例如:select ID from T where k between 3 and 5
这里因为主键ID在k索引上,所以覆盖了查询需求,所以不需要回表.

如果不光查询ID,还需要查询另一个字段u 可以考虑把 k u作为联合索引,这样他们也会变成覆盖索引,避免回表查询


最左前缀原则:B+Tree这种索引结构,可以利用索引的"最左前缀"来定位记录
只要满足最左前缀,就可以利用索引来加速检索。
最左前缀可以是联合索引的最左N个字段,也可以是字符串索引的最左M个字符
第一原则是:如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。
索引下推:在MySQL5.6之前,只能从根据最左前缀查询到ID开始一个个回表。到主键索引上找出数据行,再对比字段值。
MySQL5.6引入的索引下推优化,可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。