《Mysql实战45讲》读书笔记

Mysql逻辑架构
MySQLåºæ¬æ¶æ示æå¾

  • 连接器。负责与客户端建立连接、权限认证、维持与管理连接。若用户名密码无误,连接器去权限表检查此用户相应的权限。问:用户A登录成功后,登录权限被管理员禁用,此时A是否会掉线。答:不会。权限认证是在连接中进行认证的,不会影响已经登陆成功的用户。此时如果A退出重新登录,就会显示“ACCESS DENIED for users”
  • 查询缓存。执行过的SQL语句会以key_value对的形式被缓存在内存中。key是SQL语句,value是结果。如果再次执行此SQL,会将value直接返回给客户端。优点:若是一张静态表,很少被更新,查询缓存的命中率会很高,可以节约查询时间;缺点:如果对表做了更新操作,缓存会被清空,不适用于频繁更新的表。用法如下:
mysql> select SQL_CACHE * from T where ID=10;
  • 分析器。词法分析:解析出SQL语句中的字符串、空格,即关键字、表名、字段名。语法分析:分析SQL语法。如果SQL语句中查询了不存在的字段,则会在此阶段报错。
  • 优化器。选择合适的索引;多表join时,确定驱动表、被驱动表;选择最优的SQL执行方案。
  • 执行器。先判断用户对表是否有相应的权限(查询也会在优化器之前调用precheck验证权限),执行SQL语句。
  • 存储引擎。
  InnoDB MyISAM Memory
事务 支持 不支持  
锁粒度

基于MVCC支持高并发;

实现四个事务隔离级别;

锁粒度是行锁

不支持行锁;

读表时加共享锁;

写表时加排它锁;

对整张表加锁

 
数据存储形式

数据存在内存中;

表结构存于磁盘,文件名与表名同名,扩展名.frm

索引     默认使用哈希索引

Mysql日志功能

在 MySQL 中,如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程 IO 成本、查找成本都很高。为了解决这个问题,MySQL 的设计者就采用了日志(redo log)来提升更新效率。

WAL:预写日志技术。先写日志,在写磁盘

redo log概念

redo log是InnoDB引擎的特点。更新数据时,InnoDB先将记录写到redo log里面,再更新内存,直到这一步更新操作就完成了。InnoDB在适当的时机,讲操作记录写入磁盘。
redo log可以固定大小,一组可以配置4个文件,每个文件为1GB。环形写入redo log文件。

redolog循ç¯å

check_point是当前要擦出的位置(擦除前会将对应的数据会被写入磁盘),write_pos开始写入的位置。check_point与write_pos相遇,代表redo log被写满了,需要停止数据库更新操作,将redo log的数据同步到磁盘。redo log保证在Mysql异常重启后,之前的数据不会丢失,这个能力较crash-safe。

binlog概念

是Mysql server层的日志归档文件,与存储引擎无关。

  binlog

redo log

  Mysql server层实现 InnoDB特有
  逻辑日志;记录这个语句的原始逻辑,例如“给id为1的行中字段a加1” 物理日志;记录“某个数据页上做联什么修改”
  追加写入,不会覆盖 空间固定,循环写入,会覆盖

更新操作的执行流程

  1. 引擎将Id是2的一行数据取出,id若为主键,则直接使用树搜索找到这一行数据。若引擎发现这一行数据所在的内存页本来就在内存中,则直接返回给执行器;若不在,则从磁盘读入内存,再返回给执行器。
  2. 执行器将数据更新,调用引擎接口将数据传给存储引擎,
  3. 引擎将数据更新到内存(InnoDB buffer Pool),同时数据吸入redo log,此时redo log处于prepare状态。引擎将此信息传递给执行器。
  4. 执行器将此操作信息写入binlog。
  5. 执行器调用引擎事务提交接口,引擎将redo log状态改成commit状态。

update语å¥æ§è¡æµç¨

为保证redo log与binlog数据一致性,使用两阶段提交

事务隔离

事务:一组SQL语句操作,事务内的SQL语句要么执行成功,要么执行失败。

事务的四个特点:ACID

原子性()

Mysql为什么默认是可重复读?

  • 脏读:脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。

  • 不可重复读:不可重复读是指在对于数据库中的某条数据,一个事务范围内多次查询返回不同的数据值(这里不同是指某一条或多条数据的内容前后不一致,但数据条数相同),这是由于在查询间隔,该事务需要用到的数据被另一个事务修改并提交了。不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了其他事务提交的数据。需要注意的是在某些情况下不可重复读并不是问题。

  • 幻读:幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读可能发生在update,delete操作中,而幻读发生在insert操作中。

索引

索引是存储引擎中一种用于快速查找记录的数据结构。常见的用于索引的数据结构包括哈希表,有序数组,搜索树。

哈希表

输入需要查找的key,根据哈希函数计算得出其对应的value。如果不同的key得到了相同的value,则此位置再传建一个链表,存放相同key的数据。

优点:增删改操作较快,适用于等值查找。

缺点:key的无序性。当指定区间查找时,需要全表扫描。

有序数组

优点:适用于等值查找、范围查询

查找某一个指定值,可以使用数组下标索引,此时时间复杂度O(1);若为有序数组,可以使用二分查找方法,时间复杂度是O(log(n));

查找某一区间范围的值,可以使用二分查找,找到区间左侧数据,查找直到不大于区间右侧数据为止。

适用于保存静态数据的存储引擎

缺点:增加、删除数据的开销很大,最好的情况是O(1),最差的情况是O(n),平均复杂度是O(n)

搜索树

先讨论一下比较基础的二叉搜索树

二叉搜索树的相关详细信息参考本博客。

二叉搜索树的特点是左子节点小于父节点,父节点小于右子节点。搜索的时间复杂度是O(log(n))

实际中,数据库的索引几乎不使用二叉搜索树。因为当数据量非常大时,如果将索引全部存入内存,代价会非常大。例如100w的数据量的平衡二叉树大约是20层高度。即访问一个数据,可能需要访问20个硬盘上的数据块。机械硬盘的数据块寻址时间大约10ms,即对于100w的数据,查找某个数据大约需要20*10ms,这样非常耗费时间。

为减少读取的数据块,应该减少树的高度。即将树变化成N叉树。树根的数据块存储在内存中。

InnoDB的索引模型

表是根据主键顺序以索引的形式存放的,这种存储表的方式成为索引组织表。

主键索引(InnoDB称为聚簇索引):主键索引的叶子结点存储整行数据。根据主键,做一次B+树的搜索,即可取到相应的值。

非主键索引(InnoDB称为二级索引):非主键索引的叶子结点存储主键的值。根据非主键索引,先获取到主键的值,再根据主键的值获取这一行的数据(这一过程称为回表),查询时应该按照主键索引查询。

全局锁与表锁

全局锁:对于整个库加读锁,适用于给备用库全局备份。

表级锁:

读写锁:

元数据锁:查询表的数据时,会对其将其元数据表锁定,读锁

存储引擎对比

https://www.cnblogs.com/kevingrace/p/5685355.html

binlog与redo log区别

https://juejin.im/post/5db191cf5188254b7b003f12

发布了61 篇原创文章 · 获赞 2 · 访问量 7303

猜你喜欢

转载自blog.csdn.net/hebaojing/article/details/103403350