mysql服务器架构

  • mysql通过文件系统的目录和文件来保存数据和表定义(“表名.frm”表定义文件)
  • MySQL服务器架构:
  • 连接层:大多数基于网络的客户端和服务器都有连接层
    • 作用:基于用户名密码主机信息,进行安全认证,授权,连接等操作,连接成功之后还会进行特定查询权限的认证(比如特定的表查询)。
  • 服务层:mysql处理底层数据之前的所有操作都是在这层完成的(核心层)
  • 引擎层:有多种引擎组成,是真正的数据存取操作实现层
    • 开始一个事务;按照主键取出某条数据等,但是引擎层并不能解析Sql只是单纯的与服务层交互,响应服务层的的请求
    • 事务执行某些sql时需要当前的一系列的sql都被执行,不允许有某个片段执行失败或者未执行(要成功全部执行成功,否则全部执行失败并且该系列中已执行成功的sql数据会回滚);例如转账操作:当转账用户的金额被扣除之后那么被转账用户的金额则必须增加,如果被转账用户的金额增加失败那么转账用户已扣除的金额就需要回退。这样把多条sql语句作为一个整体执行的操为一个完整的事务。
当执行单条sql时数据库会自动作为一个事务来执行,这种为隐性事务不需要手动开启
      • 事务的特性:
        • 原子性:每个事务都是不可再分的,同一个事务中的所有sql是一个原子,要么共同执行成功要么共同不执行
        • 一致性:事务完成后数据的一致性,能量守恒定律,A账户转一百给B账户,那么A账户减少的100必须在B账户中出现
        • 隔离性:事务与事务之间是相互隔离互不影响的
  • 四种隔离状态:
0
    • Read Uncommitted:读未提交会出现数据脏读:当A事务执行但是未提交B事务刚好查询(同一隔离状态下)那么B事务就会读出A事务执行但是未提交的数据,当A事务回滚B事务读出的数据就会跟上次不一样,这就是脏读(https://www.liaoxuefeng.com/wiki/1177760294764384/1219071817284064
    • Read Committed:读已提交会出现数据不可重复读:在A事务中多次读取同一条数据且事务未结束时B事务恰好对该条数据进行了修改,A事务中出现前后读取的数据不一致(https://www.liaoxuefeng.com/wiki/1177760294764384/1245266514539200
    • Repeatable Read:可重复读会出现幻读:B事务执行搜索符合条件X的数据,该条数据不存在,读取记录为空;此时A事务执行,添加了一条符合搜索条件X的数据并提交,这时B事务进行条件X的数据读取,读取记录还是为空,但是执行条件为X的数据修改时却成功,修改成功后再次搜索条件为X的数据时搜索成功(幻读:没有读到的数据以为不存在但是却能修改成功,修改成功之后才能读取成功https://www.liaoxuefeng.com/wiki/1177760294764384/1245268672511968
    • Serializable:最严隔离级别在此模式下脏读,不可重复读,幻读都不会出现,虽然安全级别高但是相当于排队执行(事务串行)降低性能和效率
    • mysql中innoDB搜索引擎支持事务,默认隔离级别是RepeatableRead
        • 持久性:事务一旦提交,那么就是永久性的,不会因为宕机等故障导致数据丢失,保障了数据的高可靠性。
  • MySQL语句执行流程图:
每个客户端进来链接都是一个单独的线程,存取都在单独的线程上进行
0
0
  • 锁的分类:
    • 按粒度(范围)
      • 表级所:开销小,加锁快,锁定粒度大,不会出现死锁,发生锁冲突最高,并发度最低,支持的搜索引擎:MyISAM,InnoDB,MEMORY
      • 行级锁:开销大,加锁慢,锁定粒度最小,会出现死锁,发生锁冲突最低,并发度最高,支持引擎InnoDb
        • Record Lock(记录锁):对索引项加锁,锁定一条记录(锁数据,不锁GAP);但当sql语句无法使用索引的时候,就会进行全表扫描把整张表所有数据都加记录锁,然后由Mysql的Server层进行过滤,把不满足where条件的数据解锁再解锁,这样会大大增加数据库的开销和锁资源的占用(https://zhuanlan.zhihu.com/p/149228460
        • Gap Lock(间隙锁):说白了gap就是索引树中插入新记录的空隙。相应的gap lock就是加在gap上的锁,锁定一个范围,但不包括记录本身(锁数据前的间隙,但不锁数据,也不包括边界值),InnoDB在RR隔离级别下解决幻读问题时引用的锁机制,除了通过范围条件加锁时使用间隙锁外,如果使用相等条件请求一个不存在的记录,InnoDB也会使用间隙锁(https://www.jianshu.com/p/32904ee07e56
        • Next-key Lock:记录锁和间隙锁的组合,锁定一个范围且包含范围之间的记录(同时锁住记录和记录之间的间隙)
      • 页级锁:所有参数介于表所和行锁之间
    • 使用方式
      • 乐观锁:认为本次操作数据库不会导致数据冲突,需要手动实现,在需要操作的数据上添加一个版本号字段,每次操作完把版本号数据加一,并不会对数据加锁,当对某条数据进行更新的时候先去比较数据的版本与之前查询出来的是否一致,版本一致才会进行更新。
      • 悲观锁:认为本次操作数据库会遇到数据冲突,所以每次都需要获取锁才能对相同数据进行操作,同一条数据一个线程正在操作,那么其余想要操作该数据的线程就会阻塞,悲观锁是由数据库自己实现的,只需要书写相关语句。而共享所和排它锁就是悲观锁的不同实现,他们都属于悲观锁的范畴
        • 按级别(对数据库的操作方式)
          • 共享所(S):事务对数据添加了读锁,其他事务也可对其添加共享所(读锁),但是不能修改(对于同一数据,多个读操作同时进行并不会互相影响)
          • 排它锁(X):事务对数据添加写锁后,其他事务不能再操作该数据(当前的操作如果没有完成,就会阻断其他的读写操作)
  • 死锁:当多个事务在同一资源上相互占用,并且请求对方已占用锁定的资源时发生的恶性循环(https://www.cnblogs.com/amunote/p/10354327.ht ml
0
    • 索引的本质是一种数据结构,是在存储层实现的,划分索引则是针对实际应用而言,数据库中就算逻辑相邻的数据物理磁盘上的存储地址也不一定相邻(https://www.cnblogs.com/dylan123/articles/13061152.html
    • 《一》根据数据结构
      • MySQL中用到了B+Tree和散列表(Hash表)作为索引的底层数据结构。
      • Mysql为什么选用B+Tree来作为数据结构(https://www.cnblogs.com/liqiangchn/p/12995831.html
      • Hash索引
        • MySQL并没有显式支持Hash索引,而是作为内部的一种优化,对于热点的数据会自动生成Hash索引,也叫自适应Hash索引
        • Hash索引在等值查询中,可以O(1)时间复杂度定位到数据,效率非常高,但是不支持范围查询。在许多编程语言以及数据库中都会用到这个数据结构,如Redis支持的Hash数据结构。具体结构如下:
0
      • B+Tree索引(https://www.cs.usfca.edu/~galles/visualization/BTree.html数据结构可视化工具)
        • B+Tree是基于B-Tree升级后的一种树状数据结构,通常用于数据库和操作系统的文件系统中。B+ 树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。B+ 树元素自底向上插入,这与二叉树恰好相反。
        • B+Tree只在叶子节点存储数据,而B-Tree(多路平衡搜索树)的数据存储在各个节点中(https://www.jb51.net/article/158135.htm
0
        • 最外层浅蓝色磁盘块1里有数据17、35(深蓝色)和指针P1、P2、P3(黄色)。P1指针表示小于17的磁盘块,P2是在17-35之间,P3指向大于35的磁盘块。真实数据存在于子叶节点也就是最底下的一层3、5、9、10、13……非叶子节点不存储真实的数据,只存储指引搜索方向的数据项,如17、35。
查找过程:例如搜索28数据项,首先加载磁盘块1到内存中,发生一次I/O,用二分查找确定在P2指针。接着发现28在26和30之间,通过P2指针的地址加载磁盘块3到内存,发生第二次I/O。用同样的方式找到磁盘块8,发生第三次I/O。
真实的情况是,上面3层的B+Tree可以表示上百万的数据,上百万的数据只发生了三次I/O而不是上百万次I/O,时间提升是巨大的。
        • B+Tree的叶子节点间通过指针链接,可以通过遍历叶子节点即可获取所有数据。
0
        • B+Tree的数据插入方式(自下而上)。
0
    • 《二》根据数据组织方式
      • 聚簇索引(聚集索引):聚簇索引就是按照每张表的主键构造一棵B+Tree,叶子节点存放了整张表的行记录数据
        • 在InnoDB中聚簇索引和主键索引概念等价,MySQL中规定所以每张表都必须有主键索引,主键索引只能有一个,不能为null同时必须保证唯一性。建表时如果没有指定主键索引,则会自动生成一个隐藏的字段作为主键索引。
0
      • 非聚簇索引(非聚集索引):非聚集索引又可以称之为为非主键索引,辅助索引,二级索引。主键索引的叶子节点存储了完整的数据行,而非主键索引的叶子节点存储的则是主键索引值,通过非主键索引查询数据时,会先查找到主键索引,然后再到主键索引上去查找对应的数据,这个过程叫做回表
0
        • MyISAM中索引和数据文件分开存储,所有的索引都是非聚簇索引。B+Tree的叶子节点存储的是数据存放的地址,而不是具体的数据 。
0
    • 《三》根据包含字段个数
      • 索引即可以仅包含一个字段,也可以同时包含多个字段。单个字段组成的索引可以称为单值索引,否则称之为复合索引(或者称为组合索引或多值索引)
    • 《四》其他分类
      • 唯一索引:主键索引一定是唯一索引,而唯一索引不一定是主键索引。唯一索引可以理解为仅仅是将索引设置一个唯一性的属性
      • 覆盖索引:
        • 回表:既如果通过非主键索引查询数据时,会先查询到主键索引的值,然后再去主键索引中查询具体的数据,整个查询流程需要扫描两次索引,显然回表是一个耗时的操作。
        • 为了减少回表次数,在设计索引时我们可以让索引中包含要查询的结果,在辅助索引中检索到数据后直接返回,而不需要进行回表操作。
posted @ 2020-09-18 14:48  穷帅哥依然纵横一方  阅读(363)  评论(0编辑  收藏  举报