1. MySQL 深入总结

# mysql 集群架构
1. master-slave 架构模式
高可用: master 挂了,slave 可提升为 master,对位提供服务。
2. 复制模式
异步复制、半同步复制、全同步复制。
异步复制:不需要等待 slave 将 binlog 日志同步到 relay log 中,就提交事务。
半同步复制:需要等待一个 slave 将 binlog 日志同步到 relay log 中,就提交事务。
全同步复制:需要等待所有 slave 将 binlog 日志同步到 relay log 中,就提交事务。
3. 复制流程
3.1 从服务器连接主服务器:
从服务器上的 IO 线程通过网络连接主动连接到主服务器。
从服务器向主服务器发送一个复制请求,该请求包含从服务器所期望的开始位置(binlog 文件和位置)。
3.2 主服务器响应连接请求:
主服务器在接收到从服务器的复制请求后,会为该从服务器启动一个 binlog dump 线程。
binlog dump 线程从指定的 binlog 文件和位置开始读取二进制日志。
3.3 主服务器发送 binlog 数据:
binlog dump 线程将读取到的二进制日志事件发送给从服务器。
从服务器的 IO 线程接收这些 binlog 数据,并将其写入从服务器的中继日志(Relay Log)。
3.4 从服务器应用 binlog 数据:
从服务器的 SQL 线程从中继日志中读取事件,并逐个将其应用到从服务器的数据库中。

总示意图:
从服务器:
1. IO 线程 --------------> 向主服务器发起连接请求
(启动连接)

主服务器:
2. Binlog Dump 线程 -----> 响应连接请求,发送 binlog 数据
(传输二进制日志)

从服务器:
3. IO 线程 <-------------- 接收 binlog 数据,写入中继日志
4. SQL 线程 -------------> 从中继日志中读取并应用日志
(应用变化)

总结:
尽管主服务器的 binlog dump 线程中扮演了发送日志的角色,但这一过程的启动和驱动是由从服务器主动发起的。

# mysql 内部架构
1. mysql server 层 + 存储引擎层
2. InnoDB 和 MyISAM的区别。
锁的级别:MyISAM 采用表级锁定,一次只能有一个写操作。InnoDB 采用行级锁定,这在高并发写操作的情况下表现得较好。
事务:InnoDB 支持事务,确保数据的一致性和完整性。MyISAM 不支持事务。


# 事务
1. 定义 - what
事务(Transaction)是一个数据库操作序列,其中的操作要么全部成功,要么全部失败,保障了数据的完整性与一致性。
2. 使用场景 - why
保证业务场景的一致性。
3. 事务特性(设计原则):ACID - how
原子性(Atomicity):事务中的所有操作要么全部完成,要么全部不完成,即事务是一个不可分割的工作单元。
一致性(Consistency):执行事务前后,数据库都必须保持一致状态,不允许出现违反数据库约束的状态。比如外键约束。
隔离性(Isolation):一个事务的执行不能被其他事务干扰,各并发事务之间相互独立。
持久性(Durability):一旦事务提交,其结果必须永久保存到数据库中,即使系统发生故障也不能丢失。
4. 事务的隔离级别 - how
读未提交(READ UNCOMMITTED):最低隔离级别,允许看到未提交的事务,这会导致“脏读”。
读已提交(READ COMMITTED):一个事务只能看到已经提交的事务,这会导致“不可重复读”。
可重复读(REPEATABLE READ):默认的隔离级别,确保一个事务看到的一致数据快照,避免“不可重复读”。
串行化(SERIALIZABLE):最高隔离级别,确保事务完全串行化地执行,避免“幻读”。
5. innodb 存储引擎 各个隔离级别的实现原理 - how
RC 和 RR 隔离级别,采用的是 MVCC + 一致性读视图实现,提高了读写并发执行。 详见:https://www.cnblogs.com/DengGao/p/mysql.html
RC 隔离级别,每次读的时候,重新生成一份读视图,而 RR 隔离级别,复用第一次生成的读视图。

# 索引
1. 定义 - what

2. 使用场景 - why
加快查询。

3. 分类 - how
一级索引、二级索引

4. 实现原理 - how
Innodb 存储引擎使用的是 B+ 树。
因为B树不管叶子节点还是非叶子节点,都会保存数据,这样导致在非叶子节点中能保存的指针数量变少,指针少的情况下要保存大量数据,只能增加树的高度,导致IO操作变多,查询性能变低。


# 锁
1. 定义 - what

2. 使用场景 - why
使用场景:防止并发,产生脏数据。

3. 分类 - how
根据锁粒度不同,分为表锁、行锁。粒度越小,并发越高。
控制并发程度不同,分为共享锁、排它锁。排它锁和共享锁、排它锁和排它锁不可以并发执行。
行锁的具体实现:行锁、间隙锁、next-key 锁。

4. 对于 mysql innodb 存储引擎,锁的具体使用场景如下 - how
1. 事务里的【写】操作(insert、update、delete),四种隔离级别,都会加排他锁。
2. 事务里的【当前读】操作,四种隔离级别,都会加锁。加锁如下:
select * from table where ? lock in share mode; 加共享锁。
select * from table where ? for update; 加排他锁。
3. 事务里的【快照读】操作,前三种隔离级别,不会加锁,最后一种隔离级别,会加共享锁。简单的 select 操作,就是快照读。select * from table where ?;
4. 事务里的锁都是同一时刻释放的,就是事务提交或者回滚的那一刻。

5. 排它锁和共享锁、排它锁和排它锁是不可以并发执行的。

6. 在读未提交、读已提交和可重复度的隔离级别下,【快照读】是不加锁的,因此并发性能会高不少。

7. 在RC、RR隔离级别下,为了防止事务等待,我们近可能做到:
7.1 加锁时间要尽可能短。因此使用小事务。
7.2 加锁范围尽可能小。因此where条件尽可能锁定少量行。

# 死锁
1. 死锁产生的原因
两个事务循环等待对方持有的锁。比如事务1持有锁A,等待锁B;事务2持有锁B,等待锁A。
2. 死锁的解决方案
2.1 预防死锁
小事务:保持事务尽可能短,即减少事务在同一时间段内锁定的资源数量,降低死锁的概率。
按一致的顺序访问资源:确保所有事务按照相同的顺序请求锁定资源,避免循环等待。
设置合理的锁粒度:避免一次性锁定太多的资源,锁的粒度要适当,不要过大。
2.2 检测与处理死锁
当出现死锁,回滚其中一个事务。
2.3 等待超时。
加锁超时后,自动回滚。

# mysql 文件组成以及IO操作流程
https://www.cnblogs.com/DengGao/p/12734775.html
1. redo log:innodb 存储引擎