MySQL存储引擎和工具日志管理(十)

1. MySQL的锁机制

1.1 锁的介绍

相当于厕所的门,大门相当于表锁,小门相当于行锁

1.2 锁的作用

保证事务之间的隔离性。也保证了数据的一致性。
保证资源不会争用。锁时属于资源的,不是某个事务的特性。
每次事务需要资源的时候,需要申请持有资源的锁。

1.3 锁的类型

资源分类:
	内存锁:mutex latch,保证内存数据页资源不被争用,不被置换。
	对象锁:
		MDL(元数据锁): 修改元数据时。DDL--> alter,备份
		Table_lock : 表锁,DDL,备份(FTWRL全局表锁),lock tables t1 read,也	可以能升级为表锁。
		record(row) lock : 行锁,索引锁,锁定聚簇索引。
		GAP : 间隙锁,RR级别,普通辅助索引间隙锁。
		Next-lock : 下一键锁,GAP+recore lock,普通辅助索引的范围锁
对象锁粒度分类:
		MDL(元数据锁): 修改元数据时。DDL--> alter,备份
		Table_lock : 表锁,DDL,备份(FTWRL全局表锁),lock tables t1 read,也可以能升级为表锁。
		record(row) lock : 行锁,索引锁,锁定聚簇索引。
		GAP : 间隙锁,RR级别,普通辅助索引间隙锁。
		Next-lock : 下一键锁,GAP+recore lock,普通辅助索引的范围锁。它的锁范围就是row lock加上GAP锁的范围。
功能分类:
	IS : 意向共享锁,表级别
	S : 共享锁,读锁,行级别
	IX : 意向排他锁,表级别
	X : 排他锁,写锁,行级别
小提示: 这里的读和写是存储引擎层的读和写,不是selectdeleteupdate这种读写
为什么会有意向锁这种东西:因为要跟要给行数据加读锁,先探测一下,意向共享锁有没有进行标记,
如果没有继续标记,就进行进行下一步操作,判断行数据有没有加锁,如果加锁了,就进行等待。

功能分类:
在这里插入图片描述
在这里插入图片描述

举个栗子:

在这里插入图片描述

1.4 锁的演示

1.4.1 实验部分

会话A

mysql> begin
mysql> select * from x;
id		num
1	     1
2		 3
3        5
4        7
5        11
6        13
...
mysql> begin
mysql> update x set num=10 where num<10;
# 开始操作会话B


# 第二次实验
# 查看语句的执行计划索引是range范围扫描
mysql> desc update x set num=10 where num<10;
# 查看语句的执行计划索引是index全索引扫描,会对整个索引进行锁定,导致聚簇索引的行全部都加上了锁 
mysql> desc update x set num=10 where num<100;

mysql> begin
mysql> update x set num=10 where num<100;
# 开始操作会话B

会话B

# 这个时候卡住了,进行了锁等待,锁等待默认等待50秒,超过50秒就timeout
mysql> insert into x values(41,4);
# 因为会话A中这条语句update x set num=10 where num<10; 引入了行锁(row lock)和间隙锁(GAP lock), 这两个锁加起来也就是范围锁(Next-lock),不能在修改的范围进行修改,插入等操作。

# 这个是正常执行的,因为会话A的锁范围是[1,9]
mysql> insert into x values(41,30);

# 第二次实验
# 这时候还是被锁住了,因为会话A中的update x set num=10 where num<100;的索引类型是index,全表扫描,把整个表都给锁住了,所以num在[1,99]之外,也会被锁上
mysql> insert into x values(41,200);

1.5 扩展知识

1.5.1 扩展知识-查看锁等待的锁类型

如果有锁等待,可以用select * from sys.innodb_lock_waits\G进行查看是哪种锁的等待,进而去排错

在这里插入图片描述
在这里插入图片描述

1.5.2 扩展知识-死锁

死锁:事务之间抢占资源,造成死锁。mysql会自动处理,会消耗大量资源,需要回滚(cpu等)

# (1)可以查看死锁的信息---> 得到监控数据---> trx_id,thread_id --->SQL语句
mysql> show engine innodb status\G
mysql> show variables like '%deadlock%';
[root@db01 ~]#  vim /etc/my.cnf
# 死锁严重,经常出现,加这个参数,会把死锁的情况记录到本地日志文件里面,可以看到死锁情况
innodb_print_all_deadlocks=1

乐观锁和悲观锁:

# 举个栗子
北京 --> 上海  1张地铁票
小明(悲观)-------- 一定会有人跟我抢票,先把票给抢上,直接锁死(请在15分钟内付款,别人不可以抢)
小乐(乐观) -------  肯定没人跟我强,先把票抢上,但是没有锁定(请在15分钟内付款,别人可以抢)

# 乐观锁应用
乐观锁的使用一般配合队列的 比如 kafka  redis mq
MGR主复制(paxos分布式一致性协议)
redis 事务
mongodb replication set 复制集

# 悲观锁应用
mysql事务和语句之间的锁机制(锁行锁表,排他锁)大部分是悲观锁

1.5 锁的小提示

小提示:

(1) 事务与事务之间没有锁的影响,都是可以并发进行的,互不影响。锁不是事务本身的特性,而是属于资源的特性。

(2)record(row) lock, GAP,next-lock这些都是索引锁。myisam引擎默认就是表锁

(3) 模拟手动加锁 lock tables t1 read;#加锁 unlock tables; # 解锁。innodb自动加的锁

(4)table_lock record lock GAP next-lock是排他锁

(5)X锁和其他锁都是冲突的,其实innnodb是自动帮我们维护的,自动去加的锁,基本上不需要手工去做,查看锁等待:select * from sys.innodb_lock_waits\G

(6) 模拟间隙锁出现问题,查询的范围不同,索引的类型会出现变化

# 查看sql执过程,锁的一个类型,索引结果为range,range时范围索引,间隙锁正常执行,锁定修改的范围
decs update x set num=10 where num<10;  

# 索引类型时index,查询范围太大,导致了全索引扫描,导致聚簇索引的行全部被锁定
decs update x set num=10 where num<100;  

(7) MVCC快照实现了事务的隔离,同时也实现事务的高并发

2. 事务的一致性ACID的C特性

A : 原子性 undo redo
B : 持久性 redo(WAL)
I : 隔离性 ISOLATION LEVEL, lock, MVCC(undo)

C : 保证工作前,中,后,数据的状态都是完整的,一致的。
    所以C的特性是以上所有特性都是来保证一致性的。

写一致性: undo redo lock
读一致性: isolation level  MVCC(undo)

数据页的一致性:

故障原因:
WAL先把redo日志写入磁盘,然后把数据写入磁盘,现在有这一种情况
把一个16kb的数据页从内存中写入到磁盘中(一个数据页拆成四个block去写),突然断电了
只在内存中写了8kb,相当于这时一个坏的数据页,这时就不能恢复到宕机之前的状态了

double write buffer解决:
所以mysql在涉及回写机制的时候,往磁盘刷数据页的时候,刷脏页的时候,不是内存直接
对数据页了,而是加入了一种机制时double write buffer(默认时开启的),当数据库触发要往磁盘写之前,按1M,1M分两次写入ibdata中,顺序io,然后在往真实的ibd文件里面写入,这保证了内存往磁盘中写
一半不能恢复。可以利用double write buffer来进行恢复硬盘中的数据。(大部分数据页往磁盘上写大部分时随机io)

# 查看double write buffer是否开启
select @@innodb_doublewrite
1  # 默认时开启的

所以double write buffer也是保证数据的一致性

在这里插入图片描述

3. 存储引擎核心参数

3.1.1 innodb_flush_log_at_trx_commit

innodb_flush_log_at_trx_commit=1/0/2

# innodb_flush_log_at_trx_commit的默认值为1(双一标准之一)
mysql> select @@innodb_flush_log_at_trx_commit;
+----------------------------------+
| @@innodb_flush_log_at_trx_commit |
+----------------------------------+
|                                1 |
+----------------------------------+

作用:主要控制了innodb将log buffer中的数据写入日志文件并flush磁盘的时间点,取值分别为012三个。

1,每次事物的提交都会引起日志文件写入、flush磁盘的操作,确保了事务的ACID;flush  到操作系统的文件系统缓存  fsync到物理磁盘.
0,表示当事务提交时,不做日志写入操作,而是每秒钟将log buffer中的数据写入文件系统缓存并且秒fsync磁盘一次;
2,每次事务提交引起写入文件系统缓存,但每秒钟完成一次fsync磁盘操作。
--------
The default setting of 1 is required for full ACID compliance. Logs are written and flushed to disk at each transaction commit.
With a setting of 0, logs are written and flushed to disk once per second. Transactions for which logs have not been flushed can be lost in a crash.
With a setting of 2, logs are written after each transaction commit and flushed to disk once per second. Transactions for which logs have not been flushed can be lost in a crash.
-------

在这里插入图片描述

3.1.2 innodb_flush_method

innodb_flush_method=fsync/O_DIRECT/O_DIRECT/O_DSYNC

作用:

作用: 控制MySQL刷写磁盘时,是否使用OS Cache
作用:控制的是,log buffer 和data buffer,刷写磁盘的时候是否经过文件系统缓存

默认使用的模式:

# 如果是Null,默认使用fsync模式
mysql> select @@Innodb_flush_method;
+-----------------------+
| @@Innodb_flush_method |
+-----------------------+
| NULL                  |
+-----------------------+
1 row in set (0.11 sec)

mysql> show variables like '%innodb_flush%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_timeout    | 1     |
| innodb_flush_log_at_trx_commit | 1     |
| innodb_flush_method            |       |
| innodb_flush_neighbors         | 1     |
| innodb_flush_sync              | ON    |
| innodb_flushing_avg_loops      | 30    |
+--------------------------------+-------+
6 rows in set (0.32 sec)

官网描述: 如果Linux系统Innodb_flush_method为Null,那么默认使用fsync
在这里插入图片描述
官方建议:Linux系统使用O_DIRIECT模式(生产中要么使用fsync,要么使用O_DIRECT)
在这里插入图片描述
三种模式工作流程:

fsync 模式:
	buffer pool的数据写磁盘的时候,需要先经历os cache 然后再写到磁盘
	redo buffer的数据写磁盘的时候,需要先经历os cache,然后在写到磁盘

O_DSYNC:
	buffer pool的数据写磁盘的时候,需要先经历os cache 然后再写到磁盘
	redo buffer的数据写磁盘的时候,跨过os cache,直接写到磁盘

O_DIRECT:
	buffer pool的数据写磁盘的时候,跨过os cache,直接写到磁盘
	redo buffer的数据写磁盘的时候,需要先经历os cache 然后再写到磁盘
	
生产建议使用O_DIRECT,最好配合固态盘使用	

图文详解:

在fsync模式下,会用到OS CACHE,当内存中的数据(数据页或者日志页)去落盘时,会申请OS CAHCE(额外使用的内存结构),如果数据刷新比较频繁的话,OS CACHE的占用量就会比较大,对系统的占用压力就会比较大。索引不建议mysql所使用的内存空间设置过大(比如 innodb_buffer_pool_size = 80% * Total,设置过大),设置过大会出现OOM(内存溢出)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

使用建议:

最高安全模式
innodb_flush_log_at_trx_commit=1
Innodb_flush_method=O_DIRECT
最高性能:
innodb_flush_log_at_trx_commit=0
Innodb_flush_method=fsync

官网连接: https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_flush_method

3.1.3 innodb_buffer_pool_size

作用: 数据缓冲区的总大小。缓冲数据页和索引页。是MySQL最大的内存区域
默认:128M
官方建议:80~90% 物理内存
生产建议: 75%以下,按需调配

# 全局设置innodb_buffer_pool_size的大小。永久生效在配置文件中修改
SET GLOBAL innodb_buffer_pool_size=402653184;

# 主要看innodb引擎状态的,包括锁和线程方面的,可以监控innodb_buffer_pool_size的使用情况,来进行调整内存大小
mysql> show engine innodb status \G
# 这个指标比较重要
mysql> melect @@Innodb_buffer_pool_size;
+---------------------------+
| @@Innodb_buffer_pool_size |
+---------------------------+
|                 134217728 |
+---------------------------+

mysql> show engine innodb status \G  # 主要看innodb引擎状态的,包括锁和线程方面的,可以监控innodb_buffer_pool_size的使用情况,来进行调整内存大小
# 查询结果
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 137428992
Dictionary memory allocated 116177
Buffer pool size   8191   # 数据页的总个数 8191*16KB*1024=134217728
Free buffers       6535   # 未使用的数据页
Database pages     1656   # 使用的数据页的个数

# 查询结果,这个也比较重要日志的SN号
LOG
---
Log sequence number 84108148
Log flushed up to   84108148
Pages flushed up to 84108148
Last checkpoint at  84108139

扩展(redo日志相关参数):

innodb_log_buffer_size=16777216
innodb_log_file_size=50331648
innodb_log_files_in_group = 3

4. 错误日志

4.1 作用

记录MySQL从启动以来,所有的状态,警告,错误。
为我们定位数据库的问题,提供帮助

4.2 配置方法

默认:开启状态
默认路径: /datadir/hostname.err

mysql> select @@datadir;
+-------------+
| @@datadir   |
+-------------+
| /data/3306/ |
+-------------+
[root@db01 3306]# hostname
db01
[root@db01 3306]# ll /data/3306/db01.err 
-rw-r----- 1 mysql mysql 51976 12月  4 19:34 /data/3306/db01.err

定制错误日志路径:

[root@db01 3306]# vim /etc/my.cnf
# 日志目录必须得提前有,并且mysql有权限写入
log_error=/tmp/mysql.log
# 重启生效
[root@db01 3306]# /etc/init.d/mysqld restart

4.3 错误日志查看

# (1) 模拟报错
[root@db01 3306]# chown -R root.root /data/3306/ibdata*

# (2) 重启数据库
# 这不是个报错日志,这是一个结果,这这两条是没有用的
[root@db01 3306]# /etc/init.d/mysqld restart 
Shutting down MySQL... SUCCESS! 
Starting MySQL...... ERROR! The server quit without updating PID file (/data/3306//db01.pid).

# (3) 看日志
[root@db01 3306]# vim /data/3306/db01.err
# 找出[ERROR]的行
2022-12-04T11:26:18.565927Z 0 [ERROR] InnoDB: The innodb_system data file 'ibdata1' must be writable
2022-12-04T11:26:18.565973Z 0 [ERROR] InnoDB: The innodb_system data file 'ibdata1' must be writable
2022-12-04T11:26:18.565982Z 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error
2022-12-04T11:26:19.171435Z 0 [ERROR] Plugin 'InnoDB' init function returned error.
2022-12-04T11:26:19.171511Z 0 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
2022-12-04T11:26:19.171528Z 0 [ERROR] Failed to initialize builtin plugins.
2022-12-04T11:26:19.171537Z 0 [ERROR] Aborting

# (4) 根据报错大致可以判断出来与权限有关,修改权限重新启动mysql
[root@db01 3306]# chown -R mysql.mysql /data/3306/*
[root@db01 3306]# /etc/init.d/mysqld start
Starting MySQL SUCCESS! 

小提示:
(1)如果日志文件有冲突,又启动不了,看不了日志,发现不了问题,这种情况可以直接用mysqld --default调用当前的配置文件 把所有的日志打印在屏幕上了

5. binlog二进制日志

5.1 binlog作用

主要记录数据库变化(DDL、DCL、DML)性质得日志,是逻辑层性质日志。
binlog应用:数据恢复、主从复制

5.2 binlog日志配置

默认: 8.0版本以前,没有开启。8.0以后binlog默认开启。我们建议生产开启。
配置方法:

[root@db01 3306]# vim /etc/my.cnf
server_id=6  # 主机编号。主从中使用,5.7以后开binlog要加此参数
log_bin=/data/binlog/mysql-bin # 日志存放目录+日志名前缀,例如:mysql-bin.000001 mysql-bin.000002。 注意这个目录/data/binlog/必须提前存在
sync_binlog=1 # binlog日志刷盘策略,双一中得第二个1。每次事务提交立即刷写binlog到磁盘。
binlog_format=row # binlog的记录格式为row模式

# 创建binlog日志存放目录。 建议:一定要和数据盘分开,例如:/dev/sdb --> /data/3306  /dev/sdc --> /data/binlog
[root@db01 3306]# mkdir -p /data/binlog/
[root@db01 3306]# chown -R mysql.mysql /data/*

# 重启生效
[root@db01 tmp]# /etc/init.d/mysqld restart 
Shutting down MySQL.. SUCCESS! 
Starting MySQL. SUCCESS! 
[root@db01 binlog]# ll /data/binlog/
-rw-r----- 1 mysql mysql 154 12月  5 00:11 mysql-bin.000001
-rw-r----- 1 mysql mysql  30 12月  5 00:11 mysql-bin.index

# 查看binlog是否开启。@@log_bin为1是开启状态
mysql> select @@log_bin; 
+-----------+
| @@log_bin |
+-----------+
|         1 |
+-----------+

小提示:
(1) binlog不记录select、show语句操作
(2)binlog属于逻辑层的日志,记录的是数据行的一些变化,或者语句本身,可以理解为sql层的日志。和innodb层也有一定的关系,大部分都是sql层的一些行为,可以理解为操作过的修改类的命令,
也有可能是修改过的数据行。如果有这个日志记录的话,可以把数据库恢复到任意的时间点,因为
所有的变化都在这里面
(3)Innodb的redo记录的是数据页的变化,属于物理层的
(4)server_id主从才会应用到的,但是在5.7以后的二进制日志的配置也要进行设置的,日志名前缀可以自己去定制,有意义的名字即可
(5)binlog最初也是在内存中生成的,最后才会刷新到我们的磁盘上(/data/binlog/mysql-bin.xxxx这个就是磁盘文件)

5.3 binlog记录内容详解

5.3.1 binlog介绍

binlog是SQL层的功能。记录的是变更SQL语句,不记录查询语句(select、show)。

5.3.2 记录SQL语句种类

DDL: 原封不动的记录当前DDL(statement语句方式)
DCL: 原封不动的记录当前DCL(statement语句方式)
DML: 只记录已经提交的事务DML(insert、update、delete)

小提示:DDL只记录语句本身,而DML又分三种记录方式

5.3.3 DML三种记录方式

binlog_format(binlog的记录格式)参数影响
(1)statement(5.6默认)SBR(statement based replication): 语句模式原封不动的记录当前DML。
(2)ROW(5.7默认值)RBR(ROW based replication): 记录数据行的变化(用户看不懂,需要工具分析)
(3) mixed(混合)MBR(mixed based replication)模式: 以上两种模式的混合(一般不使用这种模式)

5.3.4 面试题

SBR与RBR模式的对比
STATEMENT:可读性较高(人类可读),日志量少,但是不够严谨
ROW: 可读性很低(人类不可读),日志量大,足够严谨

# (1) 日志方面
# STATEMENT: 直接记录这一行语句,日志存储量小
# ROW: 记录的是行变化,要记录400多万行记录,日志存储量大
updata t1 set xxx=xxx where id>1000  ---> 一共500w行

# (2) 严谨方面(恢复数据)
# STATEMENT: 恢复第三列的时间有可能不太准确,因为statement只是记录的是一条语句,now()是当前的时间,这条数据本来是10点插入的,数据恢复时在11点进行的。导致不准确。
# ROW: 因为记录的是行变化,所以记录的时间准确
id		name	intime
insert into t1 values(1,'zs',now())
# 小提示: 建议使用row记录模式

5.4 event事件

5.4.1 event的简介

二进制日志的最小记录单元
对于DDL、DCL一个语句就是一个event(在5.7里面DDL DCL没有事务概念)
对于DML语句来讲:只记录已提交的事务。

例如以下栗子,就被分为了4个event
			 position
			 start	stop
begin;		 120   -  340
DML1;		 340   -  460
DML2;        460   -  550
commit;		 550   -  760
5.4.2 event的组成

三部分构成:
(1)事件的开始标识
(2)事件内容
(3)事件的结束标识

Position:
开始标识: at 194
结束标识: end_log_pos 254
194和254是某个事件在binlog中的相对位置号,为了方便我们截取事件。

event: 开始位置点,结束位置点,事件内容

5.5 binlog的查看

5.5.1 查看binlog开启情况
# (1) 查看binlog是否开启,1是开启
mysql> select @@log_bin;
+-----------+
| @@log_bin |
+-----------+
|         1 |
+-----------+
1 row in set (0.00 sec)

# (2) 查看bin_log日志存放的位置
mysql> select @@log_bin_basename;
+------------------------+
| @@log_bin_basename     |
+------------------------+
| /data/binlog/mysql-bin |
+------------------------+
1 row in set (0.11 sec)

# (3) 模糊查询变量
mysql> show variables like '%base%';
+------------------------+----------------------------------------------------+
| Variable_name          | Value                                              |
+------------------------+----------------------------------------------------+
| basedir                | /app/database/mysql-5.7.30-linux-glibc2.12-x86_64/ |
| character_set_database | latin1                                             |
| collation_database     | latin1_swedish_ci                                  |
| log_bin_basename       | /data/binlog/mysql-bin                             |
| relay_log_basename     | /data/3306/db01-relay-bin                          |
| skip_show_database     | OFF                                                |
+------------------------+----------------------------------------------------+
5.5.2 文件查看
# (1) binlog的存放位置
[root@db01 binlog]# ll /data/binlog/
-rw-r----- 1 mysql mysql 154 12月  5 00:11 mysql-bin.000001
-rw-r----- 1 mysql mysql  30 12月  5 00:11 mysql-bin.index

# (2) 查看mysql-bin.index内容
[root@db01 binlog]# cat mysql-bin.index 
/data/binlog/mysql-bin.000001

# (3) 查看mysql-bin.000001
[root@db01 binlog]# file mysql-bin.000001
mysql-bin.000001: MySQL replication log
5.5.3 二进制内置查看命令
# (1) 查看目前有几个日志文件
mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       154 |
+------------------+-----------+
1 row in set (0.00 sec)

# (2) 查看当前再用的binlog
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

# (3) 查看二进制日志事件
## 查看正在使用的二进制日志文件
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

##  查看正在是的二进制日志的事件
mysql> show binlog events in 'mysql-bin.000001';
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                  |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| mysql-bin.000001 |   4 | Format_desc    |         6 |         123 | Server ver: 5.7.30-log, Binlog ver: 4 |
| mysql-bin.000001 | 123 | Previous_gtids |         6 |         154 |                                       |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
2 rows in set (0.00 sec)

举个栗子:

# DDL语句
mysql> create database dongkun charset utf8mb4;
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      338 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
mysql> show binlog events in 'mysql-bin.000001';
+------------------+-----+----------------+-----------+-------------+-----------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                    |
+------------------+-----+----------------+-----------+-------------+-----------------------------------------+
| mysql-bin.000001 |   4 | Format_desc    |         6 |         123 | Server ver: 5.7.30-log, Binlog ver: 4   |
| mysql-bin.000001 | 123 | Previous_gtids |         6 |         154 |                                         |
| mysql-bin.000001 | 154 | Anonymous_Gtid |         6 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'    |
| mysql-bin.000001 | 219 | Query          |         6 |         338 | create database dongkun charset utf8mb4 |
+------------------+-----+----------------+-----------+-------------+-----------------------------------------+

# DCL语句
mysql> grant all on *.* to root@'10.0.0.%' identified by '123'
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      338 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
mysql> show binlog events in 'mysql-bin.000001';


# 提交一个事务(DML语句)
mysql> use world;
mysql> begin;
mysql> delete from city where id<10;
mysql> commit
# anonymous_gtid这个暂时可以忽略,学到GTID会涉及到。Table_map是表映射,每个DML语句都会涉及到表的映射过程(可以不关注)
mysql> show binlog events in 'mysql-bin.000001';
+------------------+-----+----------------+-----------+-------------+-----------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                    |
+------------------+-----+----------------+-----------+-------------+-----------------------------------------+
| mysql-bin.000001 |   4 | Format_desc    |         6 |         123 | Server ver: 5.7.30-log, Binlog ver: 4   |
| mysql-bin.000001 | 123 | Previous_gtids |         6 |         154 |                                         |
| mysql-bin.000001 | 154 | Anonymous_Gtid |         6 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'    |
| mysql-bin.000001 | 219 | Query          |         6 |         338 | create database dongkun charset utf8mb4 |
| mysql-bin.000001 | 338 | Anonymous_Gtid |         6 |         403 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'    |
| mysql-bin.000001 | 403 | Query          |         6 |         476 | BEGIN                                   |
| mysql-bin.000001 | 476 | Table_map      |         6 |         534 | table_id: 108 (world.city)              |
| mysql-bin.000001 | 534 | Delete_rows    |         6 |         854 | table_id: 108 flags: STMT_END_F         |
| mysql-bin.000001 | 854 | Xid            |         6 |         885 | COMMIT /* xid=40 */                     |
+------------------+-----+----------------+-----------+-------------+-----------------------------------------+

小提示:
(1) mysql-bin.index保存了当前正在使用的日志的位置点,mysql去读日志的时候,首先要读这个索引,看到当前日志的情况,进而在去读取文件的内容
(2) show binary logs; 默认只会应用最后一个文件(可以理解为喜新厌旧,有新的日志文件,就不用旧的了)
(3) 前两行是每个日志文件的起始位置点(前两行都一样)

mysql> show binlog events in 'mysql-bin.000001';
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                  |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| mysql-bin.000001 |   4 | Format_desc    |         6 |         123 | Server ver: 5.7.30-log, Binlog ver: 4 |
| mysql-bin.000001 | 123 | Previous_gtids |         6 |         154 |                                       |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+

(4)anonymous_gtid这个暂时可以忽略,学到GTID会涉及到。Table_map是表映射,每个DML语句都会涉及到表的映射过程(可以不关注)
(5) 没有提交的事务是看不到binlog日志,binlog只记录已经提交(commit)的事务
(6) 查看最新的日志内容,首先先进行show master status查看正在使用的日志文件,如下图:

在这里插入图片描述

6. slowlog慢日志

下一个笔记涉及

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 《MySQL 技术内幕 InnoDB 存储引擎》是一本探讨 MySQL 中 InnoDB 存储引擎的技术书籍,该书主要讲解了 InnoDB 存储引擎的原理、架构和实现细节。 InnoDB 是 MySQL 数据库的默认存储引擎,具有事务处理和行级锁定等特性,广泛应用于企业级数据库系统。因此,了解 InnoDB 存储引擎的内部工作原理和性能优化技巧对于 MySQL 数据库的使用和优化非常重要。 这本书首先介绍了数据库系统和存储引擎的基本概念,然后详细讲解了 InnoDB 存储引擎的体系结构和核心组件。读者可以了解到 InnoDB 存储引擎是如何将数据存储在磁盘上,以及如何通过索引加快查询速度。 在介绍完基础知识之后,书中继续深入讲解了 InnoDB 存储引擎的事务处理机制、并发控制和崩溃恢复等关键技术。读者可以学习到如何正确使用事务,并了解到 InnoDB 是如何通过行级锁定来实现并发访问的。 此外,书中还涵盖了 InnoDB 存储引擎的性能优化技巧和调试方法。读者可以学习到如何通过合理的配置和索引设计来提升查询性能,以及如何通过监控和分析工具来定位和解决性能问题。 总之,《MySQL 技术内幕 InnoDB 存储引擎》是一本深入剖析 InnoDB 存储引擎的权威技术书籍,对于想要深入理解和优化 MySQL 数据库的开发人员和数据库管理员来说是一本非常有价值的参考资料。 ### 回答2: 《MySQL技术内幕InnoDB存储引擎》是一本深入讲解MySQL InnoDB存储引擎的技术书籍。InnoDB是MySQL中的一种存储引擎,相比其他存储引擎,如MyISAM,它拥有更好的事务支持和并发控制能力,可以提供更高的数据一致性和可靠性。 这本书主要从架构、存储、索引、事务、锁定等方面对InnoDB存储引擎进行了详细的介绍和分析。首先,作者介绍了InnoDB的整体架构,包括缓冲池、日志系统、刷新机制等,帮助读者理解InnoDB的内部工作原理。 然后,书中详细解释了InnoDB的物理存储机制,包括页结构、数据页、索引页等。通过了解这些概念,读者可以更好地理解数据在磁盘上的存储方式,进而优化查询性能和空间利用。 接着,书中介绍了InnoDB的索引机制,包括B+树索引和自适应哈希索引。通过学习这些索引类型的原理和使用方法,读者可以更好地选择和创建适合自己业务需求的索引,提高查询效率。 此外,该书还详细说明了InnoDB的事务处理机制,包括事务的隔离级别、锁定机制、行锁和表锁等。通过学习这些内容,读者可以更好地理解和掌握InnoDB的并发控制技术,避免数据冲突和锁定问题。 总而言之,《MySQL技术内幕InnoDB存储引擎》通过深入讲解InnoDB的各个方面,帮助读者更好地理解和应用该存储引擎。无论是MySQL开发人员还是DBA,都可以从这本书中获得对InnoDB的深入了解,提高数据库性能和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值