前几天有读者找到我,说想要一套全面的Mysql面试题,今天陈某特意为她写了一篇。mysql
文章的目录以下: 面试
结构化查询语言(Structured Query Language)简称SQL,是一种数据库查询语言。redis
做用:用于存取数据、查询、更新和管理关系数据库系统。算法
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。在Java企业级开发中很是经常使用,由于 MySQL 是开源免费的,而且方便扩展。sql
第一范式
:每一个列都不能够再拆分。数据库
第二范式
:在第一范式的基础上,非主键列彻底依赖于主键,而不能是依赖于主键的一部分。缓存
第三范式
:在第二范式的基础上,非主键列只依赖于主键,不依赖于其余非主键。安全
在设计数据库结构的时候,要尽可能遵照三范式,若是不遵照,必须有足够的理由。好比性能。事实上咱们常常会为了性能而妥协数据库的设计。服务器
user权限表
:记录容许链接到服务器的用户账号信息,里面的权限是全局级的。session
db权限表
:记录各个账号在各个数据库上的操做权限。
table_priv权限表
:记录数据表级的操做权限。
columns_priv权限表
:记录数据列级的操做权限。
host权限表
:配合db权限表对给定主机上数据库级操做权限做更细致的控制。这个权限表不受GRANT和REVOKE语句的影响。
statement模式下,每一条会修改数据的sql都会记录在binlog中。不须要记录每一行的变化,减小了binlog日志量,节约了IO,提升性能。因为sql的执行是有上下文的,所以在保存的时候须要保存相关的信息,同时还有一些使用了函数之类的语句没法被记录复制。
row级别下,不记录sql语句上下文相关信息,仅保存哪条记录被修改。记录单元为每一行的改动,基本是能够所有记下来可是因为不少操做,会致使大量行的改动(好比alter table),所以这种模式的文件保存的信息太多,日志量太大。
mixed,一种折中的方案,普通操做使用statement记录,当没法使用statement的时候使用row。
此外,新版的MySQL中对row级别也作了一些优化,当表结构发生变化的时候,会记录语句而不是逐行记录。
长度:整数类型能够被指定长度,例如:INT(11)表示长度为11的INT类型。长度在大多数场景是没有意义的,它不会限制值的合法范围,只会影响显示字符的个数,并且须要和UNSIGNED ZEROFILL属性配合使用才有意义。
例子:假定类型设定为INT(5),属性为UNSIGNED ZEROFILL,若是用户插入的数据为12的话,那么数据库实际存储数据为00012。
二、实数类型,包括FLOAT、DOUBLE、DECIMAL。DECIMAL能够用于存储比BIGINT还大的整型,能存储精确的小数。而FLOAT和DOUBLE是有取值范围的,并支持使用标准的浮点进行近似计算。计算时FLOAT和DOUBLE相比DECIMAL效率更高一些,DECIMAL你能够理解成是用字符串进行处理。
VARCHAR用于存储可变长字符串,它比定长类型更节省空间。
VARCHAR使用额外1或2个字节存储字符串长度。列长度小于255字节时,使用1字节表示,不然使用2字节表示。
VARCHAR存储的内容超出设置的长度时,内容会被截断。
CHAR是定长的,根据定义的字符串长度分配足够的空间。
CHAR会根据须要使用空格进行填充方便比较。
CHAR适合存储很短的字符串,或者全部值都接近同一个长度。
CHAR存储的内容超出设置的长度时,内容一样会被截断。
有时可使用ENUM代替经常使用的字符串类型。
ENUM存储很是紧凑,会把列表值压缩到一个或两个字节。
ENUM在内部存储时,其实存的是整数。
尽可能避免使用数字做为ENUM枚举的常量,由于容易混乱。
排序是按照内部存储的整数
用整数保存时间戳一般不方便处理。
若是须要存储微妙,可使用bigint存储。
看到这里,这道真题是否是就比较容易回答了。
InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引。
InnoDB的主键索引的叶子节点存储着行数据,所以主键索引很是高效。
MyISAM索引的叶子节点存储的是行数据地址,须要再寻址一次才能获得数据。
InnoDB非主键索引的叶子节点存储的是主键和其余带索引的列数据,所以查询时作到覆盖索引会很是高效。
插入缓冲(insert buffer)
二次写(double write)
自适应哈希索引(ahi)
预读(read ahead)
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里全部记录的引用指针。
索引是一种数据结构。数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现一般使用B树及其变种B+树。
更通俗的说,索引就至关于目录。为了方便查找书中的内容,经过对内容创建索引造成目录。索引是一个文件,它是要占据物理空间的。
能够大大加快数据的检索速度,这也是建立索引的最主要的缘由。
经过使用索引,能够在查询的过程当中,使用优化隐藏器,提升系统的性能。
时间方面:建立索引和维护索引要耗费时间,具体地,当对表中的数据进行增长、删除和修改的时候,索引也要动态的维护,会下降增/改/删的执行效率;
空间方面:索引须要占物理空间。
主键索引
: 数据列不容许重复,不容许为NULL,一个表只能有一个主键。
惟一索引
: 数据列不容许重复,容许为NULL值,一个表容许多个列建立惟一索引。
能够经过 ALTER TABLE table_name ADD UNIQUE (column);
建立惟一索引
能够经过 ALTER TABLE table_name ADD UNIQUE (column1,column2);
建立惟一组合索引
普通索引
: 基本的索引类型,没有惟一性的限制,容许为NULL值。
能够经过ALTER TABLE table_name ADD INDEX index_name (column);
建立普通索引
能够经过ALTER TABLE table_name ADD INDEX index_name(column1, column2, column3);
建立组合索引。
全文索引
: 是目前搜索引擎使用的一种关键技术。
能够经过ALTER TABLE table_name ADD FULLTEXT (column);
建立全文索引
索引的数据结构和具体存储引擎的实现有关,在MySQL中使用较多的索引有Hash索引,B+树索引等,而咱们常用的InnoDB存储引擎的默认索引实现为:B+树索引。对于哈希索引来讲,底层的数据结构就是哈希表,所以在绝大多数需求为单条记录查询的时候,能够选择哈希索引,查询性能最快;其他大部分场景,建议选择BTree索引。
1. B树索引
mysql经过存储引擎取数据,基本上90%的人用的就是InnoDB了,按照实现方式分,InnoDB的索引类型目前只有两种:BTREE(B树)索引和HASH索引。B树索引是Mysql数据库中使用最频繁的索引类型,基本全部存储引擎都支持BTree索引。一般咱们说的索引不出意外指的就是(B树)索引(实际是用B+树实现的,由于在查看表索引时,mysql一概打印BTREE,因此简称为B树索引)
2. B+tree性质
n棵子tree的节点包含n个关键字,不用来保存数据而是保存数据的索引。
全部的叶子结点中包含了所有关键字的信息,及指向含这些关键字记录的指针,且叶子结点自己依关键字的大小自小而大顺序连接。
全部的非终端结点能够当作是索引部分,结点中仅含其子树中的最大(或最小)关键字。
B+ 树中,数据对象的插入和删除仅在叶节点上进行。
B+树有2个头指针,一个是树的根节点,一个是最小关键码的叶节点。
3. 哈希索引
简要说下,相似于数据结构中简单实现的HASH表(散列表)同样,当咱们在mysql中用哈希索引时,主要就是经过Hash算法(常见的Hash算法有直接定址法、平方取中法、折叠法、除数取余法、随机数法),将数据库字段数据转换成定长的Hash值,与这条数据的行指针一并存入Hash表的对应位置;若是发生Hash碰撞(两个不一样关键字的Hash值相同),则在对应Hash键下以链表形式存储。固然这只是简略模拟图。
索引用来快速地寻找那些具备特定值的记录。若是没有索引,通常来讲执行查询时遍历整张表。
把建立了索引的列的内容进行排序
对排序结果生成倒排表
在倒排表内容上拼上数据地址链
在查询的时候,先拿到倒排表内容,再取出数据地址链,从而拿到具体数据
索引算法有 BTree算法和Hash算法
1. BTree算法
BTree是最经常使用的mysql数据库索引算法,也是mysql默认的算法。由于它不只能够被用在=,>,>=,<,<=和between这些比较操做符上,并且还能够用于like操做符,只要它的查询条件是一个不以通配符开头的常量。
2. Hash算法
Hash Hash索引只能用于对等比较,例如=,<=>(至关于=)操做符。因为是一次定位数据,不像BTree索引须要从根节点到枝节点,最后才能访问到页节点这样屡次IO访问,因此检索效率远高于BTree索引。
适合索引的列是出如今where子句中的列,或者链接子句中指定的列。
基数较小的类,索引效果较差,没有必要在此列创建索引
使用短索引,若是对长字符串列进行索引,应该指定一个前缀长度,这样可以节省大量索引空间
不要过分索引。索引须要额外的磁盘空间,并下降写操做的性能。在修改表内容的时候,索引会进行更新甚至重构,索引列越多,这个时间就会越长。因此只保持须要的索引有利于查询便可。
最左前缀匹配原则,组合索引很是重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就中止匹配,好比a = 1 and b = 2 and c > 3 and d = 4 若是创建(a,b,c,d)顺序的索引,d是用不到索引的,若是创建(a,b,d,c)的索引则均可以用到,a,b,d的顺序能够任意调整。
较频繁做为查询条件的字段才去建立索引
更新频繁字段不适合建立索引
如果不能有效区分数据的列不适合作索引列(如性别,男女未知,最多也就三种,区分度实在过低)
尽可能的扩展索引,不要新建索引。好比表中已经有a的索引,如今要加(a,b)的索引,那么只须要修改原来的索引便可。
定义有外键的数据列必定要创建索引。
对于那些查询中不多涉及的列,重复值比较多的列不要创建索引。
对于定义为text、image和bit的数据类型的列不要创建索引。
非空字段:应该指定列为NOT NULL,除非你想存储NULL。在mysql中,含有空值的列很难进行查询优化,由于它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值;
取值离散大的字段:(变量各个取值之间的差别程度)的列放到联合索引的前面,能够经过count()函数查看字段的差别值,返回值越大说明字段的惟一值越多字段的离散程度高;
索引字段越小越好:数据库的数据存储以页为单位一页存储的数据越多一次IO操做获取的数据越大效率越高。
一般,经过索引查询数据比全表扫描要快。可是咱们也必须注意到它的代价。
索引须要空间来存储,也须要按期维护, 每当有记录在表中增减或索引列被修改时,索引自己也会被修改。 这意味着每条记录的INSERT,DELETE,UPDATE将为此多付出4,5 次的磁盘I/O。 由于索引须要额外的存储空间和处理,那些没必要要的索引反而会使查询反应时间变慢。使用索引查询不必定能提升查询性能,索引范围查询(INDEX RANGE SCAN)适用于两种状况:
基于一个范围的检索,通常查询返回结果集小于表中记录数的30%
基于非惟一性索引的检索
因此咱们想要删除百万数据的时候能够先删除索引(此时大概耗时三分多钟)
而后删除其中无用数据(此过程须要不到两分钟)
删除完成后从新建立索引(此时数据较少了)建立索引也很是快,约十分钟左右。
与以前的直接删除绝对是要快速不少,更别说万一删除中断,一切删除会回滚。那更是坑了。
顾名思义,就是最左优先,在建立多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。
最左前缀匹配原则,很是重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就中止匹配,好比a = 1 and b = 2 and c > 3 and d = 4 若是创建(a,b,c,d)顺序的索引,d是用不到索引的,若是创建(a,b,d,c)的索引则均可以用到,a,b,d的顺序能够任意调整。
=和in能够乱序,好比a = 1 and b = 2 and c = 3 创建(a,b,c)索引能够任意顺序,mysql的查询优化器会帮你优化成索引能够识别的形式
在B树中,你能够将键和值存放在内部节点和叶子节点;但在B+树中,内部节点都是键,没有值,叶子节点同时存放键和值。
B+树的叶子节点有一条链相连,而B树的叶子节点各自独立。
B树能够在内部节点同时存储键和值,所以,把频繁访问的数据放在靠近根节点的地方将会大大提升热点数据的查询效率。这种特性使得B树在特定数据重复屡次查询的场景中更加高效。
因为B+树的内部节点只存放键,不存放值,所以,一次读取,能够在内存页中获取更多的键,有利于更快地缩小查找范围。 B+树的叶节点由一条链相连,所以,当须要进行一次全数据遍历的时候,B+树只须要使用O(logN)时间找到最小的一个节点,而后经过链进行O(N)的顺序遍历便可。而B树则须要对树的每一层进行遍历,这会须要更多的内存置换次数,所以也就须要花费更多的时间
聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据
非聚簇索引:将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam经过key_buffer把索引先缓存到内存中,当须要访问数据时(经过索引访问数据),在内存中直接搜索索引,而后经过索引找到磁盘相应数据,这也就是为何索引不在key buffer命中时,速度慢的缘由。
不必定,这涉及到查询语句所要求的字段是否所有命中了索引,若是所有命中了索引,那么就没必要再进行回表查询。
举个简单的例子,假设咱们在员工表的年龄上创建了索引,那么当进行select age from employee where age < 20的查询时,在索引的叶子节点上,已经包含了age信息,不会再次进行回表查询。
MySQL可使用多个字段同时创建一个索引,叫作联合索引。在联合索引中,若是想要命中索引,须要按照创建索引时的字段顺序挨个使用,不然没法命中索引。
MySQL使用索引时须要索引有序,假设如今创建了"name,age,school"的联合索引,那么索引的排序为: 先按照name排序,若是name相同,则按照age排序,若是age的值也相等,则按照school进行排序。
当进行查询时,此时索引仅仅按照name严格有序,所以必须首先使用name字段进行等值查询,以后对于匹配到的列而言,其按照age字段严格有序,此时可使用age字段用作索引查找,以此类推。所以在创建联合索引的时候应该注意索引列的顺序,通常状况下,将查询需求频繁或者字段选择性高的列放在前面。此外能够根据特例的查询或者表结构进行单独的调整。
事务是一个不可分割的数据库操做序列,也是数据库并发控制的基本单位,其执行的结果必须使数据库从一种一致性状态变到另外一种一致性状态。事务是逻辑上的一组操做,要么都执行,要么都不执行。
原子性
: 事务是最小的执行单位,不容许分割。事务的原子性确保动做要么所有完成,要么彻底不起做用;
一致性
: 执行事务先后,数据保持一致,多个事务对同一个数据读取的结果是相同的;
隔离性
: 并发访问数据库时,一个用户的事务不被其余事务所干扰,各并发事务之间数据库是独立的;
持久性
: 一个事务被提交以后。它对数据库中数据的改变是持久的,即便数据库发生故障也不该该对其有任何影响。
脏读
(Drity Read):某个事务已更新一份数据,另外一个事务在此时读取了同一份数据,因为某些缘由,前一个RollBack了操做,则后一个事务所读取的数据就会是不正确的。
不可重复读
(Non-repeatable read):在一个事务的两次查询之中数据不一致,这多是两次查询过程当中间插入了一个事务更新的原有的数据。
幻读
(Phantom Read):在一个事务的两次查询中数据笔数不一致,例若有一个事务查询了几列(Row)数据,而另外一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。
为了达到事务的四大特性,数据库定义了4种不一样的事务隔离级别,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别能够逐个解决脏读、不可重复读、幻读这几类问题。
READ-UNCOMMITTED
(读取未提交): 最低的隔离级别,容许读取还没有提交的数据变动,可能会致使脏读、幻读或不可重复读。
READ-COMMITTED
(读取已提交): 容许读取并发事务已经提交的数据,能够阻止脏读,可是幻读或不可重复读仍有可能发生。
REPEATABLE-READ
(可重复读): 对同一字段的屡次读取结果都是一致的,除非数据是被自己事务本身所修改,能够阻止脏读和不可重复读,但幻读仍有可能发生。
SERIALIZABLE
(可串行化): 最高的隔离级别,彻底服从ACID的隔离级别。全部的事务依次逐个执行,这样事务之间就彻底不可能产生干扰,也就是说,该级别能够防止脏读、不可重复读以及幻读。
Mysql 默认采用的 REPEATABLE_READ隔离级别 Oracle 默认采用的 READ_COMMITTED隔离级别
在Read Uncommitted级别下,读取数据不须要加共享锁,这样就不会跟被修改的数据上的排他锁冲突
在Read Committed级别下,读操做须要加共享锁,可是在语句执行完之后释放共享锁;
在Repeatable Read级别下,读操做须要加共享锁,可是在事务提交以前并不释放共享锁,也就是必须等待事务执行完毕之后才释放共享锁。
SERIALIZABLE 是限制性最强的隔离级别,由于该级别锁定整个范围的键,并一直持有锁,直到事务完成。
行级锁
:行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操做的行进行加锁。行级锁能大大减小数据库操做的冲突。其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁 和 排他锁。特色:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的几率最低,并发度也最高。
表级锁
: 表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操做的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持。最常使用的MYISAM与INNODB都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)。特色:开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的几率最高,并发度最低。
页级锁
:页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。因此取了折衷的页级,一次锁定相邻的一组记录。
共享锁: 又叫作读锁。 当用户要进行数据的读取时,对数据加上共享锁。共享锁能够同时加上多个。
排他锁: 又叫作写锁。 当用户要进行数据的写入时,对数据加上排他锁。排他锁只能够加一个,他和其余的排他锁,共享锁都相斥。
Record lock:单个行记录上的锁
Gap lock:间隙锁,锁定一个范围,不包括记录自己
Next-key lock:record+gap 锁定一个范围,包含记录自己
死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而致使恶性循环的现象。
若是不一样程序会并发存取多个表,尽可能约定以相同的顺序访问表,能够大大下降死锁机会。
在同一个事务中,尽量作到一次锁定所须要的全部资源,减小死锁产生几率;
对于很是容易产生死锁的业务部分,能够尝试使用升级锁定颗粒度,经过表级锁定来减小死锁产生的几率;
若是业务处理很差能够用分布式事务锁或者使用乐观锁
数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段。
悲观锁
:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操做。在查询完数据的时候就把事务锁起来,直到提交事务。实现方式:使用数据库中的锁机制
乐观锁
:假设不会发生并发冲突,只在提交操做时检查是否违反数据完整性。在修改数据的时候把事务锁起来,经过version的方式来进行锁定。实现方式:乐通常会使用版本号机制或CAS算法实现。
优化shema、sql语句+索引;
第二加缓存,memcached, redis;
主从复制,读写分离;
垂直拆分,根据你模块的耦合度,将一个大的系统分为多个小的系统,也就是分布式系统
水平切分,针对数据量大的表,这一步最麻烦,最能考验技术水平,要选择一个合理的sharding key, 为了有好的查询效率,表结构也要改动,作必定的冗余,应用也要改,sql中尽可能带sharding key,将数据定位到限定的表上去查,而不是扫描所有的表
数据库层面,这也是咱们主要集中关注的(虽然收效没那么大),相似于select * from table where age > 20 limit 1000000,10这种查询其实也是有能够优化的余地的. 这条语句须要load1000000数据而后基本上所有丢弃,只取10条固然比较慢. 当时咱们能够修改成select * from table where id in (select id from table where age > 20 limit 1000000,10).这样虽然也load了一百万的数据,可是因为索引覆盖,要查询的全部字段都在索引中,因此速度会很快. 同时若是ID连续的好,咱们还能够select * from table where id > 1000000 limit 10,效率也是不错的,优化的可能性有许多种,可是核心思想都同样,就是减小load的数据
从需求的角度减小这种请求…主要是不作相似的需求(直接跳转到几百万页以后的具体某一页.只容许逐页查看或者按照给定的路线走,这样可预测,可缓存)以及防止ID泄漏且连续被人恶意攻击
主键是数据库确保数据行在整张表惟一性的保障,即便业务上本张表没有主键,也建议添加一个自增加的ID列做为主键。设定了主键以后,在后续的删改查的时候可能更加快速以及确保操做数据范围安全。
推荐使用自增ID,不要使用UUID。
由于在InnoDB存储引擎中,主键索引是做为聚簇索引存在的,也就是说,主键索引的B+树叶子节点上存储了主键索引以及所有的数据(按照顺序),若是主键索引是自增ID,那么只须要不断向后排列便可,若是是UUID,因为到来的ID与原来的大小不肯定,会形成很是多的数据插入,数据移动,而后致使产生不少的内存碎片,进而形成插入性能的降低。
总之,在数据量大一些的状况下,用自增主键性能会好一些。
关于主键是聚簇索引,若是没有主键,InnoDB会选择一个惟一键来做为聚簇索引,若是没有惟一键,会生成一个隐式的主键。
null值会占用更多的字节,且会在程序中形成不少与预期不符的状况。
密码散列,盐,用户身份证号等固定长度的字符串应该使用char而不是varchar来存储,这样能够节省空间且提升检索效率。
一个好的数据库设计方案对于数据库的性能每每会起到事半功倍的效果。
须要考虑数据冗余、查询和更新的速度、字段的数据类型是否合理等多方面的内容。
将字段不少的表分解成多个表:对于字段较多的表,若是有些字段的使用频率很低,能够将这些字段分离出来造成新表。由于当一个表的数据量很大时,会因为使用频率低的字段的存在而变慢。
增长中间表:对于须要常常联合查询的表,能够创建中间表以提升查询效率。经过创建中间表,将须要经过联合查询的数据插入到中间表中,而后将原来的联合查询改成对中间表的查询。
增长冗余字段:设计数据表时应尽可能遵循范式理论的规约,尽量的减小冗余字段,让数据库设计看起来精致、优雅。可是,合理的加入冗余字段能够提升查询速度。表的规范化程度越高,表和表之间的关系越多,须要链接查询的状况也就越多,性能也就越差。
当 cpu 飙升到 500%时,先用操做系统命令 top 命令观察是否是 mysqld 占用致使的,若是不是,找出占用高的进程,并进行相关处理。
若是是 mysqld 形成的, show processlist,看看里面跑的 session 状况,是否是有消耗资源的 sql 在运行。找出消耗高的 sql,看看执行计划是否准确, index 是否缺失,或者实在是数据量太大形成。
通常来讲,确定要 kill 掉这些线程(同时观察 cpu 使用率是否降低),等进行相应的调整(好比说加索引、改 sql、改内存参数)以后,再从新跑这些 SQL。
也有多是每一个 sql 消耗资源并很少,可是忽然之间,有大量的 session 连进来致使 cpu 飙升,这种状况就须要跟应用一块儿来分析为什么链接数会激增,再作出相应的调整,好比说限制链接数等。
主数据库出现问题,能够切换到从数据库。
能够进行数据库层面的读写分离。
能够在从数据库上进行平常备份。
数据分布:随意开始或中止复制,并在不一样地理位置分布数据备份
负载均衡:下降单个服务器的压力
高可用和故障切换:帮助应用程序避免单点失败
升级测试:能够用更高版本的MySQL做为从库
在主库上把数据更高记录到二进制日志
从库将主库的日志复制到本身的中继日志
从库读取中继日志的事件,将其重放到从库数据中。