首先: 日志 大于 代码开发。
其次: 有哪些,怎么用?(见名知义的就不写了)
err_log | |
query_log | |
slow_log | |
bin_log | |
redo_log | innodb 独有; 用于崩溃恢复,保证持久性;单独文件ib_logfile0 和 ib_logfile1 循环写覆盖 |
undo_log | innodb 独有;用于MVCC和事务回滚,保证原子性,隔离性; 存储随表空间ibdata;ibd 存数据和索引; |
ddl_log | 8.0+,表恢复 |
拓展到文件:
* myd -myisam的数据, myi-myisam 的索引, frm 表结构
拓展到ACID:
Atom: undo_log 写入时记录旧址,回滚时恢复
Consist : undo redo 一起保证一致性
ioslate: mvcc 和 锁机制 , undo 通过 read view 机制
duration: redo ,通过WAL 机制,持久性 崩溃恢复
拓展到机制:
wal write-ahead log 写数据文件前先写redo log ; 如此即使崩溃也可通过redo 恢复
read-view , 决策mvcc, 当前事务生成的readview 包括 m_ids, min_trx_id,max_trx_id,creator_trx_id; rr 隔离级别下, 第一次select生成read-view, rc 隔离级别下每次select 生成 read-view,select 的数据trx_id<min_trx_id可见,大于等于max_trx_id不可见,在min-max 之间且在m_ids中不可见,否则可见,=creator_trx_id 可见。
mvcc, ibdata 的数据内容每行3个隐藏字段row-id, roll_ptr, trx-id 结合read view 机制决定了当前事务的可见范围
S锁,X锁, 快照度走mvcc 默认不加锁,select for update,update,delete 加X锁,select..lock in share mode 加S锁,S锁可被多事务持有,与X锁互斥;
拓展到锁:
是否排他: S锁,X锁
粒度: 行锁 表锁, 行锁 默认使用的next-key, 存在key 时退化为记录锁, 否则为间隙锁, 当select .. for update 或 select .. for share 中的where 为范围时 持有next-key
拓展到隔离级别:
默认 rr , 使用了mvcc ,readview 机制保证解决了脏读 和 不可重复读, 但由于 mvcc 的默认读范围不加锁, 所以无法彻底解决幻读;
rc 解决不了不可重复读, rc 每次读生成 新的 read view , 在mvcc 下,两次读到的同一行数据会不一致。
ru 已经没人用了吧, serialization 串行应该没人舍得用吧..
拓展到索引:
记录锁是数据, 间隙锁是索引,索引不到时锁表,索引到唯一就是记录锁,索引到范围(非唯一) 就是next-key 或退化为gap;
索引类型:
聚簇索引:叶子节点包含完整数据的; 由于myisam 的myi 和 myd不可能有聚簇索引; innodb 的主键索引是聚簇;
非聚簇索引: 叶子节点存储主键。
聚簇索引优先级: 主键索引---> 唯一非空索引(多个按时间顺序排序取第一个)--->创建row_id隐藏字段进行索引。 高优先级索引存在时会自动重建聚簇索引, 非聚簇索引也得重建,花销非常大,默认使用copy,用inplace 是一个优化办法
ALTER TABLE users ADD PRIMARY KEY (id), ALGORITHM=INPLACE, LOCK=NONE;
索引优化的机制:
索引覆盖: 查询的where 和 select 都命中索引,不需要回表。
索引下推: 查询的where 部分命中索引
索引合并: 查询可以利用多个索引
当然还有查询优化: 分区 分库 读写分离 ...
索引数据结构:实操一下更直观 B+ Tree Visualization
什么时候做分库分表:b+的深度到某个值,这个值根据业务自定义就行
非叶子节点的度:16kb的页大小/(索引键的大小+指针大小6字节)
为什么是6字节ptr : 以前是4字节,4*8=32 个bit,2^32 个 地址 = 4G的内存寻址空间; 不够使要扩容 6字节 48个bit ,2^48个地址 = 256t寻址空间
叶子节点存储数据,两个指针,当前节点记录数量 记录最小最大值,page锁信息
一个记录存储大小 : 记录头 + 数据 + 事物 + 回滚ptr
一页存储受 填充因子,压缩格式, 记录大小 影响
SQL优化: explain 查看执行计划, using index, using where ; type 不要是all (全表扫描)基本就够了
MYSQL架构:
┌───────────────────────────────────────────────────────────────────────────────┐
│ **MySQL 架构分层** │
├───────────────────────────────────────────────────────────────────────────────┤
│ **1. 连接层(Connection Layer)** │
│ ├─ 连接器(Connector) │
│ ├─ 线程池(Thread Pool) │
│ ├─ 用户认证(Authentication) │
│ └─ 权限校验(Authorization) │
│ │
│ **2. 服务层(Service Layer)** │
│ ├─ SQL 解析器(Parser) │
│ ├─ 查询优化器(Optimizer) │
│ ├─ 查询缓存(Query Cache,MySQL 8.0 已移除) │
│ ├─ 存储引擎接口(Storage Engine Interface) │
│ └─ 跨引擎功能(如视图、存储过程、触发器) │
│ │
│ **3. 存储引擎层(Storage Engine Layer)** │
│ ├─ InnoDB(事务、行锁、外键) │
│ ├─ MyISAM(非事务、表锁、全文索引) │
│ ├─ Memory(内存存储) │
│ └─ 其他引擎(如 Archive、CSV) │
│ │
│ **4. 文件系统层(File System Layer)** │
│ ├─ 数据文件(.ibd、.MYD) │
│ ├─ 日志文件: │
│ │ ├─ Redo Log(事务持久性) │
│ │ ├─ Undo Log(事务回滚) │
│ │ └─ Binary Log(主从复制) │
│ └─ 配置文件(my.cnf/my.ini) │
└───────────────────────────────────────────────────────────────────────────────┘