关系型数据库
一、数据库
1. 如何设计一个关系型数据库
(1)程序实例:存储管理;缓存机制;SQL解析;日志管理;权限划分;容灾机制;索引管理;锁管理
(2)存储(文件系统):持久化数据
2. MySQL基本架构
(1)连接器:身份认证和权限认证;
(2)查询缓存:执行查询语句的时候,会先查询缓存;
(3)分析器:分析SQL语句,检查语法错误;
(4)优化器:按照MySQL认为最优的方案去执行;
(5)执行器:执行语句;
3. 查询语句执行流程
(1)检查权限
(2)分析器分析语法
(3)优化器确定执行方案
(4)权限校验,若有则返回执行结果
4. 一张自增表中总共有7条数据,删除了最后2条数据,重启MySQL,又插入一条,此时id是6,不重启就是8。如果是MyISAM重不重启都是8。(重要)
5. 更新语句执行流程
(1)查询原始数据
(2)写入,redo Log状态改为prepared状态;
(3)Binlog记录,redo log为提交状态;
(4)更新完成;
6. 数据库三大范式
(1)第一范式:数据库的每一列都是不可分割的原子数据项;
(2)第二范式:要求实体的属性完全依赖于主关键字;
(3)第三范式:任何非主属性不依赖于其他非主属性;
7. 数据库事务
事务(Transaction)是并发控制的基本单位。所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性。
8. drop、delete与truncate分别在什么场景之下使用
(1)delete和truncate只删除表的数据不删除表的结构
(2)速度:一般来说: drop> truncate >delete
(3)delete语句是dml,这个操作会放到rollback segement中,事务提交之后才生效;
(4)如果有相应的trigger,执行的时候将被触发。Truncate,drop是ddl, 操作立即生效,原数据不放到rollback segment中,不能回滚。操作不触发trigger。
9. 数据库对象(数据库的组成部分)
(1)用户(user):拥有数据库访问权限的人;
(2)视图(view):在数据库中并不存在,通过控制用户对数据的访问权限,简化数据,只显示用户需要的数据项;
(3)索引(index):
(4)触发器(trigger):触发器,在数据库表中属于用户定义的SQL事务命令集合。如果你对一个数据库表执行删除、插入、修改变时候,命令就能够自动去执行;
(5)存储过程(stored procedure):存储过程是为了实现某个特定功能而汇集在一起的一组SQL语句,经过编译之后会存储在数据库里面的SQL程序;
(6)表(table):
(7)缺省值(default):数据库表中插入数据或创建列时,有些列或者列的数据没有予以设定具体数值,那么就会直接以预先设置的内容赋值;
二、数据库引擎
1. MyISAM与Innodb的区别
(1)InnoDB支持事物,而MyISAM不支持事物
(2)InnoDB支持行级锁,而MyISAM支持表级锁
(3)InnoDB支持MVCC, 而MyISAM不支持
(4)InnoDB支持外键,而MyISAM不支持
(5)InnoDB不支持全文索引,而MyISAM支持
2. innodb引擎的4大特性
(1)插入缓冲(insert buffer);
(2)二次写(double write);
(3)自适应哈希索引(ahi);
(4)预读(read ahead)
3. innodb引擎中的日志
(1)错误日志:记录出错信息,也记录一些警告信息或者正确的信息。
(2)查询日志:记录所有对数据库请求的信息,不论这些请求是否得到了正确的执行。
(3)慢查询日志:设置一个阈值,将运行时间超过该值的所有SQL语句都记录到慢查询的日志文件中。慢查询日志是SQL优化的重要依据。
(4)二进制日志(bin log):记录对数据库执行更改的所有操作。主从复制中需要查询的日志。
(5)中继日志:
(6)事务日志:
二、索引
1. 二叉查找树
(1)左子树节点上的值均小于父节点;
(2)右子树节点上的值均大于父节点;
(3)若是平衡BST,则左右子树的高度差不能超过1;
(4)时间复杂度O(logn);
(5)BST可能会退化到线性查找;
2. B树
(1)定义:根节点至少包括两个孩子;树中每个节点最多含有m个孩子(m>=2);除根节点和叶节点外,其他每个节点至少有ceil(m/2)个孩子;所有叶子节点都在同一层
(2)假设每个非终端节点中包含有n个关键字信息,其中
a. Ki(i=1,2,...,n)为关键字,且关键字按顺序升序排序K(i-1)<Ki;
b. 关键字的个数n必须满足:[ceil(m/2)-1]<=n<=m-1;
c. 非叶子节点指针:P[1],P[2],...,P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其他P[i]指向关键字属于(K[i-1],K[i])的子树
3. B+树
(1)其结构与B树基本相同;
(2)非叶子节点的子树指针与关键字个数相同;
(3)非叶子节点的子树指针P[i],指向关键字值[K[i],K[i-1])的子树
(4)非叶子节点仅用来索引,数据都保存在叶子节点中
(5)每一个叶子节点都带有指向下一个节点的指针
(6)B+树更适合用来做存储索引
a. B+树的磁盘读写代价更低,因为非叶子节点不包含数据;
b. B+树的查询效率更加稳定,因为每次查找都需要找到叶子节点;
c. B+树更有利于对数据库进行扫描
d. B+树支持range-query(区间查询)非常方便,而B树不支持。这是数据库选用B+树的最主要原因。
(7)B+树的聚簇索引和非聚簇索引
a. 聚簇索引:B+树的叶子节点存储的是整张表的行记录数据;
b. 非聚簇索引:B+树的叶子节点存储的是行记录的主键,非聚簇索引比聚簇索引多了一次读取数据的IO操作(回表,可以通过索引覆盖来减少回表次数),所以查找性能上会差;
4. Hash和bitMap
(1)hash索引的缺点
a. 仅仅能满足“=”,“in”,不能使用范围查询;
b. 无法被用来避免数据的排序操作
c. 不能利用部分索引键查询
d. 不能避免表扫描
e. 遇到大量hash值相等(数据碰撞)的情况后,性能并不一定比B树高(但是当值的差异性较大时,hash效率会更高,查找效率都是O(n)
(2)bitMap位图索引
5. 密集索引和稀疏索引的区别
(1)密集索引文件中的每个索引键值都对应一个索引项,一个表只能创建一个密集索引;
(2)稀疏索引文件只有部分索引键值对应一个索引项
6. InnoDB索引
(1)有且仅有一个密集索引,即一定需要一个主键,因为它是先找主键再找行数据;
(2)若一个主键被定义,该主键则所为密集索引;
(3)若没有主键被定义,该表的第一个唯一非空索引则作为密集索引;
(4)若不满足以上条件,innoDB内部会生成一个隐藏主键(密集索引)
(5)非主键索引存储相关键位和其对应的主键值,包含两次查找,一次是查找次级索引自身,一次是查找主键
7. 索引是越建越多越好吗?不是
(1)数据量小的表不需要建立索引,建立会增加额外的索引开销;
(2)数据变更需要维护索引,因此更多的索引意味着更多维护成本
8. 联合索引的最左匹配原则的成因
(1)联合索引是两个或更多列上的索引。
(2)最左匹配原则:对于联合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持a、a,b、a,b,c 3种组合进行查找,但不支持 b,c进行查找。当最左侧字段是常量引用时,索引就十分有效。
9. 索引
(1)为什么要使用索引?
快速查询数据,避免全表扫描,提升检索效率,类似于字典的目录。
(2)索引是数据库中一个或多个列进过排序的一个结构,简单来说就是一种数据结构。SELECT * FROM ‘table_name’ WHERE ...。真实使用索引时,禁止使用“*”。
(3) 什么样的信息能称为索引?
主键、唯一键以及普通键等字段。
(4)索引的数据结构
BST;AVL;RBT;B-Tree;B+-Tree;hash
(5)检测索引有效:SHOW STATUS LIKE ‘...’;
(6)MySQL在5.6版本后添加索引下推功能,默认开启。
10. MySQL索引添加指令
(1)主键索引:
ALTER TABLE ‘table_name’ ADD PRIMARY KEY (‘colmn’);
(2)唯一索引:
ALTER TABLE ‘table_name’ ADD UNIQUE KEY (‘colmn’);
(3)普通索引:
ALTER TABLE ‘table_name’ ADD INDEX index_name (‘colmn’);
(4)全文索引:
ALTER TABLE ‘table_name’ ADD FULLTEXT KEY (‘colmn’);
(5)多列索引(联合):
ALTER TABLE ‘table_name’ ADD INDEX index_name (‘colmn1’,’colmn2’,’colmn3’);
11. 内连接,左连接和右连接
(1)内连接:两张表共同的部分;
select * from ‘table_nameA’ inner join ‘table_nameB’ on A.s_id=B.s_id;
(2)左连接:将返回左表的所有行。如果左表的某行在右表中没有匹配行,则将为右表返回空值。
select *from ‘table_nameA’ LEFT JOIN ‘table_nameB’ ON A.s_id=B.s_id
(3)右连接:将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。
select *from ‘table_nameA’ RIGHT JOIN ‘table_nameB’ ON A.s_id=B.s_id
12. 索引创建注意事项
(1)索引最好不要以null值多的列
(2)索引不适合键值重复度高的列
(3)前导模糊查询不可以用索引
(4)一个表的索引不宜超过3个
四、MVCC多版本并发控制
1. MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问。MVCC手段只适用于Msyql隔离级别中的读已提交(Read committed)和可重复读(Repeatable Read)。
2. 基本原理:MVCC的实现,通过保存数据在某个时间点的快照来实现的。这意味着一个事务无论运行多长时间,在同一个事务里能够看到数据一致的视图。根据事务开始的时间不同,同时也意味着在同一个时刻不同事务看到的相同表里的数据可能是不同的。
3. 基本特征
(1)每行数据都存在一个版本,每次数据更新时都更新该版本;
(2)修改时Copy出当前版本随意修改,各个事务之间无干扰;
(3)保存时比较版本号,如果成功(commit),则覆盖原记录;失败则放弃copy(rollback)
4. InnoDB存储引擎MVCC的实现策略
在每一行数据中额外保存两个隐藏的列:当前行创建时的版本号和删除时的版本号。事务开始时刻的系统版本号会作为事务的版本号,用来和查询每行记录的版本号进行比较。每个事务又有自己的版本号,这样事务内执行CRUD操作时,就通过版本号的比较来达到数据版本控制的目的。
5. MVCC下InnoDB的增删查改的工作原理
(1)插入:记录的版本号就是当前事务的版本号;
(2)更新:采用的是先标记旧的那行记录为已删除,并且删除版本号是事务版本号,然后插入一行新的记录的方式;
(3)删除:当前事务版本号作为删除操作版本号;
(4)查询:
a. InnoDB只查找版本早于(包含等于)当前事务版本的数据行;
b. 行的删除版本要么未定义,要么大于当前事务版本号,确保事务读取的行,在事务开始之前未删除(如果小于当前版本号,说明删除操作早于插询操作)
五、SQL性能调优
1. 如何定位并优化慢查询sql?
(1)根据慢日志定位慢查询sql;
(2)使用explain等工具分析sql,explain显示了MySQL是否使用以及如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句;
a. type列,连接类型。一个好的sql语句至少要达到range级别。杜绝出现all级别;
b. key列,使用到的索引名。如果没有选择索引,值是NULL。可以采取强制索引方式;
c. key_len列,索引长度;
d. rows列,扫描行数。该值是个预估值;
e. extra列,详细说明。注意常见的不太友好的值有:Using filesort, Using temporary。
(3)优化:
- 优化sql或者尽量让sql走索引;
- 升级硬件;
- 减少一次查询的范围;
六、锁模块
1. 什么是数据库中的锁?
锁是计算机协调多个进程或线程并发访问某一资源的机制。
2. MyISAM与InnoDB关于锁方面的区别是什么?
(1)MyISAM默认用的是表级锁,不支持行级锁;
(2)InnoDB默认用的是行级锁,也支持表级锁(不走索引时)
3. 如何指定数据库引擎
(1)利用type属性可以指定:
alter table tableName type=InnoDB
(2)修改配置文件my.ini;
4. 对于MyISAM,当进行select操作时,会自动增加表级读锁;当进行增删改操作时,会自动增加一个表级写锁;当读锁未被释放,写锁将被阻塞。
5. 共享锁和排它锁
(1)读锁即共享锁:即在上了读锁后,依然可以对其他范围同时进行读操作;
(2)写锁即排它锁:用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。确保不会同时同一资源进行多重更新。如果事务T对数据A加上排他锁后,则其他事务不能再对A加任何类型的锁。Select也可以上写锁。
6. 表级锁、行级锁和页面锁
(1)表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。与索引无关。表级锁是不会发生死锁的,因为它会一次性获得所有锁
(2)行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。InnoDB发生死锁后一般能自动检测到,使一个事务释放锁并回退,另一个事务获得锁,继续完成事务。InnoDB是基于索引来完成行锁
(3)页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
7. MyISAM适合的场景
(1)频繁执行全表count语句
(2)对数据进行增删改的频率不高,查询非常频繁
(3)没有事务
8. InnoDB适合的场景
(1)数据增删相当频繁,更新操作一般只要求锁住一行即可;
(2)可靠性要求比较高;要求支持事务
9. 数据库锁的分类
(1)按锁的粒度划分:行级锁、表级锁、页级锁;
(2)按锁级别划分:共享锁、排它锁;
(3)按加锁方式划分:自动锁、排它锁;
(4)按操作划分:DML锁、DDL锁
(5)按使用方式划分:乐观锁、悲观锁
10. 乐观锁和悲观锁
(1)乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,若果发现更新则事务回滚。
(2)悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。再比如Java里面的同步原语synchronized关键字的实现也是悲观锁。
(3)CAS:CAS是乐观锁技术,即Compare and Swap,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。
七、数据库事务的四大特性
1. ACID
(1)原子性Atomic:原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚;
(2)一致性Consistency:一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
(3)隔离性Isolation:隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
(4)持久性Durability:持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
八、事务的隔离级别以及各级别下的并发访问问题
1. 事务并发访问引起的问题
(1)更新丢失:
(2)脏读:脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
(3)不可重复读:不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
(4)幻读:幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。
2. 如何避免问题
3. 当前读和快照读
(1)当前读:select ... lock in share mode;select ... for update;insert;update delete;读取最新的数据,
(2)快照读:简单的select操作,不加锁;只能看到第一次select后的数据
4. RC、RR级别下的innoDB的非阻塞读如何实现?
(1)数据行里的DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID字段
(2)Undo日志
(3)Read view:可见性判断,判断可以看哪个版本的数据
5. InnoDB可重复读隔离级别下如何避免幻读
事务对数据增加了next-key锁(即行锁+gap锁)
(1)行锁:单行加锁;
(2)Gap锁:主要是解决可重复读模式下的幻读问题
(3)Gap锁加的条件:
a. 如果where条件全部命中,则不会用Gap锁,只会加记录锁;
b. 如果where条件部分命中或者全不命中,则会加gap锁
c. Gap锁会用在非唯一索引或者不走索引的当前读中
九、语法
1. 关键语法
(1)GROUP BY:根据给定数据的查询结果进行分组统计
a. 满足“SELECT子句中的列名必须为分组列或列函数”
b. 列函数对于GROUP BY子句定义的每个组各返回一个结果
(2)HAVING:
a. 通常与GROUP BY 子句一起使用,指定过滤的条件
b. WHERE过滤行,HAVING过滤组
c. 出现在同一SQL的顺序:WHERE>GROUP BY>HAVING,调整顺序会报错
d. having语句可以使用聚合函数,而where不使用。
(3)聚合函数
a. COUNT:总数
b. SUM:求和
c. MAX:最大值
d. MIN:最小值
e. AVG:求平均
十、分页
1. 分段与分页的区别
(1)页是信息的物理单位,分页是为实现离散分配方式,以消减内存的外零头,提高内存的利用率,或者说,分页是出于系统管理的需要而不是用户需要;段是信息的逻辑单位,它含有一组其意义相对完整的信息,分段的目的是为了更好地满足用户的需要。
(2)页的大小固定而且由系统决定,由系统把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的,因而在系统中只能有一种大小的页面;段的长度不固定,决定于用户所编写的程序,通常由编译程序在对程序进行编译时,根据信息的性质来划分。
(3)分页的作业地址空间是维一的,即单一的线性空间,程序员只须利用一个记忆符,即可表示一地址;分段的作业地址空间是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。
2. 物理分页与逻辑分页
(1)概述
a. 物理分页:物理分页依赖的是某一物理实体,这个物理实体就是数据库,比如MySQL数据库提供了limit关键字,程序员只需要编写带有limit关键字的SQL语句,数据库返回的就是分页结果。
b. 逻辑分页:逻辑分页依赖的是程序员编写的代码。数据库返回的不是分页结果,而是全部数据,然后再由程序员通过代码获取分页数据,常用的操作是一次性从数据库中查询出全部数据并存储到List集合中,因为List集合有序,再根据索引获取指定范围的数据。
(2)区别:
a. 数据库负担:物理分页每次都访问数据库,逻辑分页只访问一次数据库,物理分页对数据库造成的负担大。
b. 服务器负担:逻辑分页一次性将数据读取到内存,占用了较大的内容空间,物理分页每次只读取一部分数据,占用内存空间较小。
c. 实时性:逻辑分页一次性将数据读取到内存,数据发生改变,数据库的最新状态不能实时反映到操作中,实时性差。物理分页每次需要数据时都访问数据库,能够获取数据库的最新状态,实时性强。
d. 适用场合:逻辑分页主要用于数据量不大、数据稳定的场合,物理分页主要用于数据量较大、更新频繁的场合。
十一、MySQL问题排查
1. 问题归类
(1)SQL语句不规范;
(2)配置类问题;
(3)Bug;
2. 排查方法
(1)查询事务隔离级别;
(2)查询输出数据当前状态;
(3)查询数据库连接信息;
(4)查询事务信息;
(5)查询数据库信息;
3. 查询当前执行的SQL;SQL查询慢的原因和优化
(1)原因
a. SQL编写问题,比如没有使用索引或者索引用的不好;
b. 锁的粒度大了;
c. 业务实例相互干绕对IO/CPU资源争用;
d. 服务器硬件问题;
e. MYSQL BUG;
(2)排查
a. pt-query-digest:定位影响中的慢查询;
b. Explain:分析慢查询的原因,尤其是type,rows和extra三个字段;
c. show profiling:定位到底是那个环节出现的问题。
(3)索引使用规则
a. 字段类型转换导致不用索引,如字符串类型的不用引号,数字类型的用引号等,这有可能会用不到索引,导致全表扫描;
b. MySQL不支持函数转换,所以字段前面不能加函数,否则这将用不到索引;
c. 不要在字段前面加减运算;
d. 字符串比较长的可以考虑索引一部份减少索引文件大小,提高写入效率;
e. like % 在前面用不到索引;
f. 根据联合索引的第二个及以后的字段单独查询用不到索引;
g. 不要使用 select *;
h. 排序请尽量使用升序 ;
i. or 的查询尽量用 union 代替 (Innodb);
j. 复合索引高选择性的字段排在前面;
k. order by / group by 字段包括在索引当中减少排序,效率会更高。
(4)SQL使用注意
a. 尽量规避大事务的 SQL,大事务的 SQL 会影响数据库的并发性能及主从同步;
b. 分页语句 limit 的问题;
c. 删除表所有记录请用 truncate,不要用 delete;
d. 不让 mysql 干多余的事情,如计算;
e. 输写 SQL 带字段,以防止后面表变更带来的问题,性能也是比较优的 ( 涉及到数据字典解析,请自行查询资料);
f. 在 Innodb上用 select count(*),因为 Innodb 会存储统计信息;
g. 慎用 Oder by rand()。
十二、主从复制原理
1. 概念
MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。
2. MySQL 主从复制主要用途
(1)读写分离
在开发工作中,有时候会遇见某个sql 语句需要锁表,导致暂时不能使用读的服务,这样就会影响现有业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作。
(2)热备
作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。实现HA。
(3)架构扩展
随着系统中业务访问量的增大,如果是单机部署数据库,就会导致I/O访问频率过高。有了主从复制,增加多个数据存储节点,将负载分布在多个从节点上,降低单机磁盘I/O访问的频率,提高单个机器的I/O性能。
3. 主从复制原理
MySQL主从复制涉及到三个线程,一个运行在主节点(log dump thread),其余两个(I/O thread, SQL thread)运行在从节点,如下图所示:
(1)主节点binary log dump线程
当从节点连接主节点时,主节点会创建一个log dump 线程,用于发送bin-log的内容。在读取bin-log中的操作时,此线程会对主节点上的bin-log加锁,当读取完成,甚至在发动给从节点之前,锁会被释放。
(2)从节点I/O线程
当从节点上执行‘start slave’命令之后,从节点会创建一个I/O线程用来连接主节点,请求主库中更新的bin-log。I/O线程接收到主节点binlog dump 进程发来的更新之后,保存在本地relay-log中。
(3)从节点SQL执行线程
SQL线程负责读取relay log中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。
4. 复制的基本过程
(1)从节点上的I/O 进程连接主节点,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;
(2)主节点接收到来自从节点的I/O请求后,通过负责复制的I/O进程根据请求信息读取指定日志指定位置之后的日志信息,返回给从节点。返回信息中除了日志所包含的信息之外,还包括本次返回的信息的bin-log file 的以及bin-log position;从节点的I/O进程接收到内容后,将接收到的日志内容更新到本机的relay log中,并将读取到的binary log文件名和位置保存到master-info 文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从某个bin-log 的哪个位置开始往后的日志内容,请发给我”;
(3)Slave 的 SQL线程检测到relay-log 中新增加了内容后,会将relay-log的内容解析成在祝节点上实际执行过的操作,并在本数据库中执行。
5. 主从复制模式
(1)异步模式(默认)
这种模式下,主节点不会主动push bin log到从节点,这样有可能导致failover的情况下,也许从节点没有即时地将最新的bin log同步到本地。
(2)半同步模式
这种模式下主节点只需要接收到其中一台从节点的返回信息,就会commit;否则需要等待直到超时时间然后切换成异步模式再提交;这样做的目的可以使主从数据库的数据延迟缩小,可以提高数据安全性,确保了事务提交后,binlog至少传输到了一个从节点上,不能保证从节点将此事务更新到db中。性能上会有一定的降低,响应时间会变长。
(3)全同步模式
全同步模式是指主节点和从节点全部执行了commit并确认才会向客户端返回成功。这种模式下不会发生主从延迟,但是性能会下降;
6. 主库意外挂机
选择备份数据最多的从库作为新的主库,其余从库停止与旧主库的关系,开始与新主库的关系。
十三、分布式事务
1. 分布式事务
分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。一个节点的数据库中的数据库发生变化,相关联的数据库的信息都要变换。
2. 分布式事务基础
(1)CAP理论
(2)BASE理论:BASE允许通过牺牲一定的强一致性来换取最终一致性,即允许数据在一段时间内是不一致的,但最终达到一致状态。
3. 分布式事务解决方案
(1)2阶段提交(会牺牲掉部分可用性,不适合高并发)
a. 事务管理器要求每个涉及到事务的数据库预提交(precommit)此操作,并反映是否可以提交。
b. 事务协调器要求每个数据库提交数据,或者回滚数据。
(2)TCC
a. Try阶段:尝试执行,完成所有业务检查(一致性),预留必须业务资源(准隔离性)
b. Confirm阶段:确认执行真正执行业务,不作任何业务检查,只使用Try阶段预留的业务资源,Confirm操作满足幂等性。要求具备幂等设计,Confirm失败后需要进行重试。
c. Cancel阶段:取消执行,释放Try阶段预留的业务资源 Cancel操作满足幂等性Cancel阶段的异常和Confirm阶段异常处理方案基本上一致。
(3)本地消息表
(4)MQ事务
(5)Saga事务