-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Affected files: docs/06数据库/MySQL/MySQL主从复制.md docs/06数据库/MySQL/MySQL体系架构.md docs/06数据库/MySQL/MySQL存储引擎介绍.md docs/06数据库/MySQL/MySQL数据迁移.md docs/06数据库/MySQL/MySQL的三种Log日志.md docs/06数据库/MySQL/MySQL的行锁.md docs/06数据库/MySQL/assets/MySQL主从复制/MySQL主从复制.png docs/06数据库/MySQL/assets/MySQL主从复制/半同步模式.png docs/06数据库/MySQL/assets/MySQL主从复制/异步模式.png docs/06数据库/MySQL/assets/MySQL体系架构/MySQL架构图.png docs/06数据库/MySQL/assets/MySQL的行锁/行锁算法.webp docs/06数据库/MySQL/assets/一条SQL语句在MySQL的执行流程/MySQL的执行流程.webp docs/06数据库/MySQL/一条SQL语句在MySQL的执行流程.md docs/06数据库/数据库原理/ACID解释.md docs/06数据库/数据库原理/assets/数据库设计三大范式/第一范式.png docs/06数据库/数据库原理/assets/数据库设计三大范式/第三范式.png docs/06数据库/数据库原理/assets/数据库设计三大范式/第二范式1.png docs/06数据库/数据库原理/assets/数据库设计三大范式/第二范式2.png docs/06数据库/数据库原理/事务隔离级别.md docs/06数据库/数据库原理/并发事务处理带来的问题.md docs/06数据库/数据库原理/数据库设计三大范式.md
- Loading branch information
Showing
21 changed files
with
299 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
|
||
## 主从复制 | ||
|
||
 | ||
|
||
MySQL 主从复制涉及到三个线程,一个运行在主节点(log dump thread),其余两个(I/O thread, SQL thread)运行在从节点。 | ||
|
||
- **Log Dump Thread**:当从节点连接主节点时,主节点会创建一个 log dump 线程,用于发送 bin-log 的内容。在读取 bin-log 中的操作时,此线程会对主节点上的 bin-log 加锁,当读取完成,甚至在发动给从节点之前,锁会被释放。 | ||
- **I/O Thread**:当从节点上执行 `start slave` 命令之后,从节点会创建一个 I/O 线程用来连接主节点,请求主库中更新的 bin-log。I/O线程接收到主节点 binlog dump 进程发来的更新之后,保存在本地 relay-log 中。 | ||
- **SQL Thread**:负责读取 relay log 中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。 | ||
|
||
一个 slave 节点可同时从多个 master 进行数据复制,在这种情况下,不同 master 的 bin-log 存储在不同的 relay log中。 | ||
|
||
## 同步模式 | ||
|
||
 | ||
|
||
**异步模式(mysql async-mode)**:MySQL增删改操作会全部记录在 binary log 中,当 slave 节点连接 master 时,会主动从 master 处获取最新的 bin log 文件。 | ||
|
||
 | ||
|
||
**半同步模式(mysql semi-sync)**:这种模式下主节点只需要接收到其中一台从节点的返回信息,就会 `commit` ;否则需要等待直到超时时间然后切换成异步模式再提交;这样做的目的可以使主从数据库的数据延迟缩小,可以提高数据安全性,确保了事务提交后,binlog 至少传输到了一个从节点上,不能保证从节点将此事务更新到 db 中。性能上会有一定的降低,响应时间会变长。 | ||
|
||
**全同步模式** 是指主节点和从节点全部执行了commit并确认才会向客户端返回成功。 | ||
|
||
## 主从复制的延迟问题 | ||
|
||
进行主从同步的过程中,如果使用异步或半异步模式,均会有主从节点数据不一致的窗口时间。同时,从节点上的 `SQL Thread` 只能串行执行 `relay-log` 中的记录,当某条 DDL/DML 耗时较长时,会加剧这个窗口时间;再者在某些场景下会使用 slave 节点进行数据读取,这也可能导致数据加锁等待。基于以上原因在处理主从复制延迟问题上有以下几种方向: | ||
|
||
1. 优化主从节点之间的网络延迟 | ||
2. 降低 master 负载,以减少 TPS | ||
3. 降低 slave 负载,slave 只做备份使用,不提供服务 | ||
4. 调整 slave 参数:关闭 slave bin-log 等 | ||
5. 多线程的主从复制:不同 schema 下的表并发提交时的数据不会相互影响,即 slave 节点可以用对 relay log 中不同的 schema 各分配一个SQL Thread,来重放 relay log 中主库已经提交的事务 | ||
|
||
**参考:** | ||
|
||
1. [快速搭建MySQL主从系统](https://cloud.tencent.com/developer/article/1955482) | ||
2. [MySQL 主从复制模式](https://www.cnblogs.com/haihefeng/articles/17602976.html) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
|
||
 | ||
|
||
从MySQL的架构图,我们可以看出MySQL的架构自顶向下大致可以分为网络连接层、数据库服务层、存储引擎层和系统文件层四大部分。接下来,我们就来简单说说每个部分的组成信息。 | ||
|
||
## 网络连接层 | ||
|
||
网络连接层位于整个MySQL体系架构的最上层,主要担任客户端连接器的角色。提供与MySQL服务器建立连接的能力,几乎支持所有主流的服务端语言,例如:Java、C、C++、Python等,各语言都是通过各自的API接口与MySQL建立连接。 | ||
|
||
## 数据库服务层 | ||
|
||
数据库服务层是整个数据库服务器的核心,主要包括了系统管理和控制工具、连接池、SQL接口、解析器、查询优化器和缓存等部分。 | ||
|
||
连接池:主要负责存储和管理客户端与数据库的连接信息,连接池里的一个线程负责管理一个客户端到数据库的连接信息。 | ||
|
||
系统管理和控制工具:提供数据库系统的管理和控制功能,例如对数据库中的数据进行备份和恢复,保证整个数据库的安全性,提供安全管理,对整个数据库的集群进行协调和管理等。 | ||
|
||
SQL接口:主要负责接收客户端发送过来的各种SQL命令,并将SQL命令发送到其他部分,并接收其他部分返回的结果数据,将结果数据返回给客户端。 | ||
|
||
解析树:主要负责对请求的SQL解析成一棵“解析树”,然后根据MySQL中的一些规则对“解析树”做进一步的语法验证,确认其是否合法。 | ||
|
||
查询优化器:在MySQL中,如果“解析树”通过了解析器的语法检查,此时就会由优化器将其转化为执行计划,然后与存储引擎进行交互,通过存储引擎与底层的数据文件进行交互。 | ||
|
||
缓存:MySQL的缓存是由一系列的小缓存组成的。例如:MySQL的表缓存,记录缓存,MySQL中的权限缓存,引擎缓存等。MySQL中的缓存能够提高数据的查询性能,如果查询的结果能够命中缓存,则MySQL会直接返回缓存中的结果信息。 | ||
|
||
## 存储引擎层 | ||
|
||
MySQL中的存储引擎层主要负责数据的写入和读取,与底层的文件进行交互。值得一提的是,MySQL中的存储引擎是插件式的,服务器中的查询执行引擎通过相关的接口与存储引擎进行通信,同时,接口屏蔽了不同存储引擎之间的差异。MySQL中,最常用的存储引擎就是InnoDB和MyISAM。 | ||
|
||
## 系统文件层 | ||
|
||
系统文件层主要包括MySQL中存储数据的底层文件,与上层的存储引擎进行交互,是文件的物理存储层。其存储的文件主要有:日志文件、数据文件、配置文件、MySQL的进行pid文件和socket文件等。 | ||
|
||
- MySQL中的日志主要包括:错误日志、通用查询日志、二进制日志、慢查询日志等。 | ||
- 数据文件中主要包括了:db.opt文件、frm文件、MYD文件、MYI文件、ibd文件、ibdata文件、ibdata1文件、ib_logfile0和ib_logfile1文件等。 | ||
- 配置文件用于存储MySQL所有的配置信息,在Unix/Linux环境中是my,cnf文件,在Windows环境中是my.ini文件。 | ||
- pid文件是存放MySQL进程运行时的进程号的文件,主要存在于Unix/Linux环境中,具体的存储目录可以在my.cnf或者my.ini文件中进行配置。 | ||
- socket文件和pid文件一样,都是MySQL在Unix/Linux环境中运行才会有的文件。在Unix/Linux环境中,客户端可以直接通过socket来连接MySQL。 | ||
|
||
(转载自:[一文搞懂MySQL体系架构!!](https://www.cnblogs.com/binghe001/p/14654973.html)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
|
||
在上述的水平扩容方案中,如何进行数据迁移,是在扩容中需要考虑的问题。一般情况下,数据迁移分为:停机迁移、双写迁移。 | ||
|
||
**停机迁移** 是最简单、最安全、最快速的迁移方案,但一般线上业务系统很少允许停机迁移。在停机迁移中,首先停掉数据库 A 的写入请求,复制 A 数据到 B,待复制完成后,切换线上数据源。 | ||
|
||
**双写迁移** 方案就是同时写两个库,一个是老库,一个是新库。也就是在线上系统里面,除了对所有老库的增删改地方,同时对新库同样执行增删改。主要经历以下三个阶段: | ||
|
||
1. 导入历史数据,数据库双写(事务成功以老数据源为准),查询走老数据源,通过定时任务补全新老差异数据 | ||
2. 新老数据无差异,依旧双写(事务成功以新数据源为准),查询走新数据源 | ||
3. 稳定运行无误后,下线老数据源 | ||
|
||
参考:[两种数据库迁移方案你了解吗](https://blog.csdn.net/belongtocode/article/details/106002715) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
|
||
## BinLog | ||
|
||
binlog有三种格式:Statement、Row以及Mixed。 | ||
|
||
- 基于SQL语句的复制(statement-based replication,SBR) | ||
- 基于行的复制(row-based replication,RBR) | ||
- 混合模式复制(mixed-based replication,MBR) | ||
|
||
**Statement** | ||
|
||
每一条会修改数据的sql都会记录在binlog中。 | ||
|
||
优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。 | ||
|
||
缺点:由于记录的只是执行语句,为了这些语句能在slave上正确运行,因此还必须记录每条语句在执行的时候的一些相关信息,以保证所有语句能在slave得到和在master端执行时候相同 的结果。另外mysql 的复制,像一些特定函数功能,slave可与master上要保持一致会有很多相关问题。 | ||
|
||
ps:相比row能节约多少性能与日志量,这个取决于应用的SQL情况,正常同一条记录修改或者插入row格式所产生的日志量还小于Statement产生的日志量,但是考虑到如果带条件的update操作,以及整表删除,alter表等操作,ROW格式会产生大量日志,因此在考虑是否使用ROW格式日志时应该跟据应用的实际情况,其所产生的日志量会增加多少,以及带来的IO性能问题。 | ||
|
||
**Row** | ||
|
||
5.1.5版本的MySQL才开始支持row level的复制,它不记录sql语句上下文相关信息,仅保存哪条记录被修改。 | ||
|
||
优点: binlog中可以不记录执行的sql语句的上下文相关的信息,仅需要记录那一条记录被修改成什么了。所以rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节。而且不会出现某些特定情况下的存储过程,或function,以及trigger的调用和触发无法被正确复制的问题. | ||
|
||
缺点:所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容。 | ||
|
||
ps:新版本的MySQL中对row level模式也被做了优化,并不是所有的修改都会以row level来记录,像遇到表结构变更的时候就会以statement模式来记录,如果sql语句确实就是update或者delete等修改数据的语句,那么还是会记录所有行的变更。 | ||
|
||
**Mixed** | ||
|
||
从5.1.8版本开始,MySQL提供了Mixed格式,实际上就是Statement与Row的结合。 | ||
|
||
在Mixed模式下,一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。 | ||
|
||
## RedoLog | ||
|
||
重做日志用来实现事务的持久性,即D特性。 | ||
|
||
在innoDB的存储引擎中,事务日志通过重做(redo)日志和innoDB存储引擎的日志缓冲(InnoDB Log Buffer)实现。事务开启时,事务中的操作,都会先写入存储引擎的日志缓冲中,在事务提交之前,这些缓冲的日志都需要提前刷新到磁盘上持久化,这就是DBA们口中常说的“日志先行”(Write-Ahead Logging)。当事务提交之后,再慢慢写入。此时如果数据库崩溃或者宕机,那么当系统重启进行恢复时,就可以根据redo log中记录的日志,把数据库恢复到崩溃前的一个状态。 | ||
|
||
在系统启动的时候,就已经为redo log分配了一块连续的存储空间,以顺序追加的方式记录Redo Log,通过顺序IO来改善性能。所有的事务共享redo log的存储空间,它们的Redo Log按语句的执行顺序,依次交替的记录在一起。 | ||
|
||
``` | ||
举个例子,对于Insert操作,物理日志记录的是每个页的变化: | ||
若执行SQL语句: | ||
`INSERT INTO t SELECT 1,2;` | ||
其记录的重做日志大致类似这个样子: | ||
`page(2,3),offset 32,value 1,2` | ||
``` | ||
|
||
## UndoLog | ||
|
||
它可以实现如下两个功能:1.实现事务回滚;2.实现MVCC。 | ||
|
||
undo log和redo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。 | ||
|
||
**参考:** | ||
|
||
1. [MySQL中binlog的三种格式](https://cloud.tencent.com/developer/article/1533697) | ||
2. [mysql日志redo log、undo log、binlog](https://www.cnblogs.com/caicz/p/15097461.html) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
|
||
**表级锁**:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低(MyISAM 和 MEMORY 存储引擎采用的是表级锁); | ||
|
||
**行级锁**:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高(InnoDB 存储引擎既支持行级锁也支持表级锁,在索引检索时,采用行锁,否则表锁); | ||
|
||
**页面锁**:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。 | ||
|
||
| | 行锁 | 表锁 | 页锁 | | ||
| ------ | --- | --- | --- | | ||
| MyISAM | | Yes | | | ||
| InnoDB | Yes | Yes | | | ||
| Memory | | Yes | | | ||
|
||
行锁的三种算法: | ||
|
||
 | ||
|
||
Record Lock记录锁:单行记录上的锁。select或update时,必须是主键或唯一索引列且是精确匹配=,否则退化为临键锁。 | ||
|
||
Gap Lock间隙锁:锁定一个范围,不包括记录本身。解决可重复读级别下的幻读问题(非唯一索引)。 | ||
|
||
Next-Key Lock临键锁(记录锁+间隙锁):锁定一个范围,包括记录本身。 | ||
|
||
默认隔离级别REPEATABLE-READ下,InnoDB中行锁**默认使用算法Next-KeyLock**,只有当查询的索引是**唯一索引或主键**时,InnoDB会对Next-KeyLock进行优化,将其降级为RecordLock,即仅锁住索引本身,而不是范围。当查询的索引为辅助索引时,InnoDB则会使用Next-KeyLock进行加锁。InnoDB对于辅助索引有特殊的处理,不仅会锁住辅助索引值所在的范围,还会将其下一键值加上GapLOCK。 | ||
|
||
``` | ||
例子: | ||
对于**非唯一索引**b,有值1,1,3,6,8 | ||
对于where b=3,先加Next-Key锁(1,3],再加Gap锁(3,6)综合来看就是锁了(1,6) | ||
``` | ||
|
||
参考:[MySQL 探秘(七):InnoDB 行锁算法](https://toutiao.io/posts/q34ohu/preview) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
|
||
 | ||
|
||
执行步骤为: | ||
|
||
1. 客户端请求 | ||
2. 连接器(验证用户身份,给予权限) | ||
3. 查询缓存(存在缓存则直接返回,不存在则执行后续操作) | ||
4. 分析器(对SQL进行词法分析和语法分析操作) | ||
5. 优化器(主要对执行的sql优化选择最优的执行方案方法) | ||
6. 执行器(执行时会先看用户是否有执行权限,有才去使用这个引擎提供的接口) | ||
7. 去引擎层获取数据返回(如果开启查询缓存则会缓存查询结果) | ||
|
||
参考:https://blog.csdn.net/m0_52973251/article/details/129028829 |
Oops, something went wrong.