mysql深入底层了解

Posted 黄昏单车

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql深入底层了解相关的知识,希望对你有一定的参考价值。

索引数据结构

# 索引的本质:帮助mysql高效获取数据 排好序 的 数据结构

Myisam存储引擎索引实现

# 分三个文件存储:

1:frm存储表结构

2:MYD存储表数据

3:MYI存储表索引数据

底层查找过程:先通过MYI索引数据结构找到对应索引,拿到磁盘文件地址,通过地址定位MYD数据所在行记录

在这里插入图片描述
InnoDB存储引擎索引实现

# 分二个文件存储:

1:frm存储表结构

2:ibd存储数据和索引

# 为什么建议InnoDB表必须建主键?

	因为索引数据必须要有B+Tree结构组织数据,没有建有主键,会从表中找唯一列作为B+Tree结构存储
如果没有唯一列,会默认建立隐藏列Rowid自维护,用Rowid进行B+Tree组织数据结构,所以为了避免减少
数据库的性能维护,必须建主键。

# 为什么推荐使用整型的自增主键?

	整型可以直接比较大小,效率高,占用空间小,字符串比较需要转成ascii码逐位比较,
自增问题例如5,7,再插入一个6的时候,为了保持自增的顺序性,会在5,7之间插入元素,如果满了之后会分裂
重组索引变成5,67...,造成性能损耗

在这里插入图片描述

二叉树

# 特性

1)k-v结构,k就是数据,v就是索引所在行磁盘文件地址
2)右边的子节点大于父节点,左边的子节点小于父节点
	
注意:不适合单边增长数据,例如自增id(1,2,3,4,5,6...)

在这里插入图片描述

在这里插入图片描述

红黑树(二叉平衡树)


在这里插入图片描述
B-Tree
在这里插入图片描述
B+Tree

每个节点最大16kb

假如索引用bigint类型:占据8b,磁盘文件地址6b,根节点大概可以存储1170个索引,子节点一样
假如叶子节点1个索引1kb,最终1170 * 1170 * 16,大概两千万

根节点和子节点会常驻内存,不需要进行磁盘读取,最终只需要一次磁盘I/O交互

在这里插入图片描述
Hash
在这里插入图片描述
bin log和redo log日志

# Bin log归档日志(逻辑日志)

	1:二进制日志
	
	2:在Mysql的server层实现(引擎共用)
	
	3:记录的是一条语句的原始逻辑
	
	4:不限大小,追加写入,不会覆盖以前的日志

# 开启bin-log

	查看是否开启:show variables like '%log_bin%';

	mysql> show variables like '%log_bin%';
	+---------------------------------+-------+
	| Variable_name                   | Value |
	+---------------------------------+-------+
	| log_bin                         | OFF   |
	| log_bin_basename                |       |
	| log_bin_index                   |       |
	| log_bin_trust_function_creators | OFF   |
	| log_bin_use_v1_row_events       | OFF   |
	| sql_log_bin                     | ON    |
	+---------------------------------+-------+
	6 rows in set
	
	我是在本地使用的phpstudy,所以修改my.ini如下,由于存在了datadir,所以只需要配置:
	log-bin=mysql-bin即可,server_id=1默认存在,不用动
	
	[mysqld]
	datadir=D:/phpstudy_pro/Extensions/MySQL5.7.26/data/
	log-bin=mysql-bin
	server_id=1
	
	注意5.7以及更高版本需要配置本项:server-id=123454

	mysql> show variables like '%log_bin%';
	+---------------------------------+--------------------------------------------+
	| Variable_name                   | Value                         |
	+---------------------------------+---------------------------------------------+
	| log_bin                         | ON                            |
	| log_bin_basename | D:\\phpstudy_pro\\Extensions\\MySQL5.7.26\\data\\mysql-bin      
	| log_bin_index    | D:\\phpstudy_pro\\Extensions\\MySQL5.7.26\\data\\mysql-bin.index
	| log_bin_trust_function_creators | OFF                           |
	| log_bin_use_v1_row_events       | OFF                           |
	| sql_log_bin                     | ON                            |
	+---------------------------------+---------------------------------------------+
	6 rows in set
	
# bin-log命令(以下命令根据自己的文件目录所在清空变化)

	sync_binlog:设置为1,表示每次事务binlog都将持久化到磁盘 
	
	flush logs:会多一个最新的bin-log日志
	
	show master status:查看最后一个bin-log日志的相关信息 
	
	reset master:清空所有的bin-log日志
	
	查看 bin-log内容:
	/usr/local/mysq1/bin/mysqlbinlog --no-defaults
	/usr/local/mysql/data/mysql-bin.000001
	
	恢复日志(需要分开两个日志:一个插入,一个清空):
	/usr/bin/mysqlbinlog --no-defaults /var/run/mysqld/mysql-bins.000005 
	| mysql -u root -p laravel
	
	恢复指定位置段数据(从BEGIN前一个end_log_pos 348,到COMMIT前end_log_pos 424)/usr/bin/mysqlbinlog --no-defaults /var/run/mysqld/mysql-bins.000005 
	--stop-position="424" --start-position="348" | mysql -u root -p laravel
	
	恢复指定日期段数据(日期时间范围要小于开始时间,大于结束时间,不能等于):
	/usr/bin/mysqlbinlog --no-defaults /var/run/mysqld/mysql-bins.000005 
	--stop-datetime="2021-05-10 02:07:30" --start-datetime="2021-05-10 02:07:00" 
	| mysql -u root -p laravel
	
# Redo log重做日志(物理日志)

	记录InnoDB存储引擎的事务日志 
	
	MySQL的WAL机制(Write-Ahead Logging),先写日志再写磁盘
	
	文件名:ib_logfile*

#	Redo Log写入原理

	以循环方式写入日志文件,不断的写与擦除,文件1写满时,切换到文件2,
	文件2写满时,再次切换到文件1。
	
	 writepos当前记录的位置,循环边写边后移
	 
	 checkpoint当前要擦除的位置,循环边写边后移

以上是关于mysql深入底层了解的主要内容,如果未能解决你的问题,请参考以下文章

mysql深入底层了解

通过一条语句的执行,深入理解innoDB的底层架构

深入理解Mysql索引底层数据结构与算法

java 高薪计划

深入理解 Mysql 索引底层原理

全面深入理解MySQL底层原理与性能调优