数据库学习日常案例20231203-Mysql高级 -- 日志管理篇

Mysql高级 -- 日志篇

*日志类型

1.mysql的6类日志:

2.日志的弊端

*慢查询日志(slow query log)

*通用查询日志(general query log)

1.作用:

2.问题场景:

3.查看当前状态 :

4.启动日志:

方式1:永久性方式

方式2:临时性方式

5.查看日志 :

6.停止日志

方式1:永久性方式

方式2:临时性方式

7.删除\刷新日志

*错误日志(error log)

1.启动日志

2.查看日志

3.删除\刷新日志

*二进制日志

1.binlog主要应用场景:|

2.查看默认情况

3.日志参数设置

方式1:永久性方式

4.查看日志

查看二进制日志文件列表及大小

将事件以伪SQL的形式表现出来

伪SQL命令,不显示binlog格式的语句

查看到position点信息事件:

binlog格式查看

binlog格式种类

5.使用日志恢复数据

细节:因为回放数据的操作也被记录,所以需要刷新logs

mysqlbinlog恢复数据的语法如下:

6.删除二进制日志

PURGE MASTER LOGS:删除指定日志文件

RESET MASTER:删除所有的二进制日志文件

7.其它场景

8.写入机制

9.binlog与redolog对比

两阶段提交方案:

redo log与binlog两份日志之间的逻辑不一致问题

*中继日志(relay log)

1.查看中继日志

2.恢复的典型错误

*日志类型

MySQL有不同类型的日志文件,用来存储不同类型的日志,分为 二进制日志 、 错误日志 、 通用查询日志 和 慢查询日志 ,这也是常用的4种。MySQL 8又新增两种支持的日志: 中继日志 和 数据定义语句日志 。使用这些日志文件,可以查看MySQL内部发生的事情。

1.mysql的6类日志:

  • **慢查询日志:**记录所有执行时间超过long_query_time的所有查询,方便我们对查询进行优化。
  • **通用查询日志:**记录所有连接的起始时间和终止时间,以及连接发送给数据库服务器的所有指令,对我们复原操作的实际场景、发现问题,甚至是对数据库操作的审计都有很大的帮助。
  • **错误日志:**记录MySQL服务的启动、运行或停止MySQL服务时出现的问题,方便我们了解服务器的状态,从而对服务器进行维护。
  • **二进制日志:**记录所有更改数据的语句,可以用于主从服务器之间的数据同步,以及服务器遇到故障时数据的无损失恢复。
  • **中继日志:**用于主从服务器架构中,从服务器用来存放主服务器二进制日志内容的一个中间文件。从服务器通过读取中继日志的内容,来同步主服务器上的操作。
  • **数据定义语句日志:**记录数据定义语句执行的元数据操作。

**注意:**除二进制日志外,其他日志都是 文本文件 。默认情况下,所有日志创建于 MySQL数据目录 中。

2.日志的弊端

  • 日志功能会降低MySQL数据库的性能
  • 日志会占用大量的磁盘空间

*慢查询日志(slow query log)

*通用查询日志(general query log)

1.作用:

通用查询日志用来记录用户的所有操作 ,包括启动和关闭MySQL服务、所有用户的连接开始时间和截止时间、发给 MySQL 数据库服务器的所有 SQL 指令等。当我们的数据发生异常时,查看通用查询日志,还原操作时的具体场景,可以帮助我们准确定位问题。

2.问题场景:

3.查看当前状态 :

mysql> SHOW VARIABLES LIKE '%general%';

4.启动日志:

方式1:永久性方式

修改my.cnf或者my.ini配置文件来设置。在[mysqld]组下加入log选项,并重启MySQL服务。格式如下:

[mysqld] 
general_log=ON 
general_log_file=[path[filename]] 
#日志文件所在目录路径,filename为日志文件名

如果不指定目录和文件名,通用查询日志将默认存储在MySQL数据目录中的hostname.log文件中,hostname表示主机名。

方式2:临时性方式

对应的,关闭操作SQL命令如下:

perl 复制代码
SET GLOBAL general_log=on; # 开启通用查询日志 
SET GLOBAL general_log_file='path/filename'; # 设置日志文件保存位置

查看设置后情况:

SHOW VARIABLES LIKE 'general_log%';

5.查看日志 :

通用查询日志是以 文本文件 的形式存储在文件系统中的,可以使用 文本编辑器 直接打开日志文件。每台MySQL服务器的通用查询日志内容是不同的。

  • 在Windows操作系统中,使用文本文件查看器;
  • 在Linux系统中,可以使用vi工具或者gedit工具查看;
  • 在Mac OSX系统中,可以使用文本文件查看器或者vi等工具查看。

SHOW VARIABLES LIKE 'general_log%'; 结果中可以看到通用查询日志的位置。

在通用查询日志里面,我们可以清楚地看到,什么时候开启了新的客户端登陆数据库,登录之后做了什么SQL操作,针对的是哪个数据表等信息。

6.停止日志

方式1:永久性方式

修改 my.cnf 或者 my.ini 文件,把[mysqld]组下的 general_log 值设置为 OFF 或者把general_log一项注释掉。修改保存后,再 重启MySQL服务 ,即可生效。

举例1:

[mysqld] 
general_log=OFF

举例2:

[mysqld] 
#general_log=ON

方式2:临时性方式

使用SET语句停止MySQL通用查询日志功能:

SET GLOBAL general_log=off;

查询通用日志功能:

SHOW VARIABLES LIKE 'general_log%';

7.删除\刷新日志

如果数据的使用非常频繁,那么通用查询日志会占用服务器非常大的磁盘空间。数据管理员可以删除很长时间之前的查询日志,以保证MySQL服务器上的硬盘空间。

手动删除文件:找到文件位置,rm 文件

SHOW VARIABLES LIKE 'general_log%';

使用如下命令重新生成查询日志文件,具体命令如下。刷新MySQL数据目录,发现创建了新的日志文件。前提一定要开启通用日志。

mysqladmin -uroot -p flush-logs; #刷新日志

*错误日志(error log)

1.启动日志

在MySQL数据库中,错误日志功能是 默认开启 的。而且,错误日志无法被禁止 。默认情况下,错误日志存储在MySQL数据库的数据文件夹下,名称默认为 mysqld.log (Linux系统)或hostname.err (mac系统)。如果需要制定文件名,则需要在my.cnf或者my.ini中做如下配置:

[mysqld] 
log-error=[path/[filename]] #path为日志文件所在的目录路径,filename为日志文件名

修改配置项后,需要重启MySQL服务以生效。

2.查看日志

MySQL错误日志是以文本文件形式存储的,可以使用文本编辑器直接查看。

查询错误日志的存储路径:

mysql> SHOW VARIABLES LIKE 'log_err%';

注意:docker容器中日志位置 /var/lib/docker/containers/容器ID/容器ID-json.log

3.删除\刷新日志

对于很久以前的错误日志,数据库管理员查看这些错误日志的可能性不大,可以将这些错误日志删除,以保证MySQL服务器上的硬盘空间 。MySQL的错误日志是以文本文件的形式存储在文件系统中的,可以直接删除

删除:

rm 文件路径

刷新:提示因为版本问题删除后刷新找不到文件

[root@atguigu01 log]# mysqladmin -uroot -p flush-logs
Enter password:
mysqladmin: refresh failed; error: 'Could not open file '/var/log/mysqld.log' for error logging.'

flush-logs指令操作:

  • MySQL 5.5.7以前的版本,flush-logs将错误日志文件重命名为filename.err_old,并创建新的日志文件。
  • 从MySQL 5.5.7开始,flush-logs只是重新打开日志文件,并不做日志备份和创建的操作。
  • 如果日志文件不存在,MySQL启动或者执行flush-logs时会自动创建新的日志文件。重新创建错误日志,大小为o字节

创建文件(补充操作):

install -omysql -gmysql -m0644 /dev/null /var/log/mysqld.log #

*二进制日志

binlog可以说是MySQL中比较 重要 的日志了,在日常开发及运维过程中,经常会遇到。

binlog即binary log,二进制日志文件,也叫作变更日志(update log)。它记录了数据库所有执行的DDL 和 DML 等数据库更新事件 的语句,但是不包含没有修改任何数据的语句(影响条数为0的语句)(如数据查询语句select、show等)。

1.binlog主要应用场景:|

  • 一是用于数据恢复,如果MysQL数据库意外停止,可以通过二进制日志文件来查看用户执行了哪些操作,对数据库服务器文件做了哪些修改,然后根据二进制日志文件中的记录来恢复数据库服务器。
  • 二是用于数据复制,由于日志的延续性和时效性,master把它的二进制日志传递给slaves来达到master-slave数据─致的目的。

可以说MysQL数据库的数据备份、主备、主主、主从都离不开binlog,需要依靠binlog来同步数据,保证数据一致性。

2.查看默认情况

查看记录二进制日志是否开启:在MySQL8中默认情况下,二进制文件是开启的。

show variables like '%log_bin%'; 

3.日志参数设置

方式1:永久性方式

修改MySQL的 my.cnf 或 my.ini 文件可以设置二进制日志的相关参数:

[mysqld] 
#启用二进制日志 
log-bin=atguigu-bin 
binlog_expire_logs_seconds=600 
max_binlog_size=100M

重新启动MySQL服务,查询二进制日志的信息.

设置带文件夹的bin-log日志存放目录

如果想改变日志文件的目录和名称,可以对my.cnf或my.ini中的log_bin参数修改如下:

[mysqld] 
log-bin="/var/lib/mysql/binlog/atguigu-bin"

注意:新建的文件夹需要使用mysql用户,使用下面的命令即可。

chown -R -v mysql:mysql binlog

方式2:临时性方式

如果不希望通过修改配置文件并重启的方式设置二进制日志的话,

还可以使用如下指令,需要注意的是在mysql8中只有 会话级别 的设置,没有了global级别的设置。

 # global 级别 
mysql> set global sql_log_bin=0; 
ERROR 1228 (HY000): Variable 'sql_log_bin' is a SESSION variable and can`t be used with SET GLOBAL 

# session级别 
mysql> SET sql_log_bin=0; 
Query OK, 0 rows affected (0.01 秒)

4.查看日志

当MySQL创建二进制日志文件时,先创建一个以"filename"为名称、以".index"为后缀的文件,再创建一个以"filename"为名称、以".000001"为后缀的文件。MySQL服务 重新启动一次 ,以".000001"为后缀的文件就会增加一个,并且后缀名按1递增。即日志文件的个数与MySQL服务启动的次数相同;如果日志长度超过了 max_binlog_size 的上限(默认是1GB),就会创建一个新的日志文件。

more mysqlbinlog.index文件则显示一溜mysqlbinlog的名称。

查看二进制日志文件列表及大小

mysql> SHOW BINARY LOGS;

将事件以伪SQL的形式表现出来

mysqlbinlog -v "/var/lib/mysql/binlog/atguigu-bin.000002"

伪SQL命令,不显示binlog格式的语句

mysqlbinlog -v --base64-output=DECODE-ROWS "/var/lib/mysql/binlog/atguigu-bin.000002"

关于mysqlbinlog工具的使用技巧还有很多,例如只解析对某个库的操作或者某个时间段内的操作等。简单分享几个常用的语句,更多操作可以参考官方文档。

# 可查看参数帮助 
mysqlbinlog --no-defaults --help 

# 查看最后100行 
mysqlbinlog --no-defaults --base64-output=decode-rows -vv atguigu-bin.000002 |tail -100 

# 根据position查找 
mysqlbinlog --no-defaults --base64-output=decode-rows -vv atguigu-bin.000002 |grep -A20 '4939002'

查看到position点信息事件:

mysql> show binlog events [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count];

binlog格式查看

mysql> show variables like 'binlog_format';

mysql --initialize

binlog格式种类

  • Statement 每一条会修改数据的sql都会记录在binlog中。优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。
  • Row 5.1.5版本的MySQL才开始支持row level 的复制 ,它不记录sql语句上下文相关信息,仅保存哪条记录被修改。优点:row level 的日志内容会非常清楚的记录下每一行数据修改的细节。而且不会出现某些特定情况下的存储过程,或function,以及trigger的调用和触发无法被正确复制的问题。
  • Mixed : 从5.1.8版本开始,MySQL提供了Mixed格式,实际上就是Statement与Row的结合。详细情况,下章讲解

5.使用日志恢复数据

细节:因为回放数据的操作也被记录,所以需要刷新logs

flush logs

mysqlbinlog恢复数据的语法如下:

mysqlbinlog [option] databasename filepath| mysql --uuser -ppass -v databasename

这个命令可以这样理解:使用mysqlbinlog命令来读取filename中的内容,然后使用mysql命令将这些内容恢复到数据库中。

  • filename :是日志文件名。
  • option :可选项,比较重要的两对option参数是--start-date、--stop-date 和 --start-position、--stop-position。
  • --start-date 和 --stop-date :可以指定恢复数据库的起始时间点和结束时间点。
  • --start-position和--stop-position :可以指定恢复数据的开始位置和结束位置。

注意: 使用mysqlbinlog命令进行恢复操作时,必须是编号小的先恢复,例如atguigu-bin.000001必须在atguigu-bin.000002之前恢复。

position示例:

mysqlbinlog --start-position=857 --stop-position=2092 --database=xc_course /var/lib/mysql/mysql-bin.000003
 | mysql -uroot -pxxx -v xc_course

时间示例:

mysqlbinlog --start-datetime="2022-07-29 04:39:08" --stop-datetime="2022-07-29 04:41:52" 
--database=xc_course /var/lib/mysql/mysql-bin.000001 
| mysql -uroot -phealth_parent -v xc_course

6.删除二进制日志

MySQL的二进制文件可以配置自动删除,同时MySQL也提供了安全的手动删除二进制文件的方法。PURGE MASTER LOGS 只删除指定部分的二进制日志文件, RESET MASTER 删除所有的二进制日志文件。具体如下:

PURGE MASTER LOGS:删除指定日志文件

PURGE MASTER LOGS语法如下:

PURGE {MASTER | BINARY} LOGS TO '指定日志文件名' 
PURGE {MASTER | BINARY} LOGS BEFORE '指定日期'

文件示例:

PURGE MASTER LOGS TO 'mysql-bin.000004' #删除在该日志之前创建的日志(不包括该日志)

日期:

PURGE MASTER LOGS BEFORE '20220729'

RESET MASTER:删除所有的二进制日志文件

示例:

RESET MASTER;

7.其它场景

二进制日志可以通过数据库的 全量备份 和二进制日志中保存的 增量信息 ,完成数据库的 无损失恢复 。但是,如果遇到数据量大、数据库和数据表很多(比如分库分表的应用)的场景,用二进制日志进行数据恢复,是很有挑战性的,因为起止位置不容易管理。在这种情况下,一个有效的解决办法是 配置主从数据库服务器 ,甚至是 一主多从 的架构,把二进制日志文件的内容通过中继日志同步到从数据库服务器中,这样就可以有效避免数据库故障导致的数据异常等问题。

8.写入机制

binlog的写入时机也非常简单,事务执行过程中,先把日志写到 binlog cache ,事务提交的时候,再把binlog cache写到binlog文件中。因为一个事务的binlog不能被拆开,无论这个事务多大,也要确保一次性写入,所以系统会给每个线程分配一个块内存作为binlog cache。

write和fsync的时机,可以由参数sync_binlog 控制,默认是0。表示每次提交事务都只write,由系统自行判断什么时候执行fsync。虽然性能得到提升,但是机器宕机,page cache里面的 binglog 会丢失。如下图:

由于没有即时刷盘导致缓存页丢失,为了安全起见,可以设置sync_binlog为1,表示每次提交事务都会执行fsync,就如同redo log刷盘流程一样。最后还有一种折中方式,可以设置为N(N>1),表示每次提交事务都write,但累积N个事务后才fsync(减少与磁盘的交互次数,降低性能消耗)

在出现io瓶颈的场景里,将sync_binlog设置成一个比较大的值,可以提升性能。同样的,如果机器宕机,会丢失最近N个事务的binlog日志。

9.binlog与redolog对比

  • oredo log它是物理日志,记录内容是"在某个数据页上做了什么修改",属于InnoDB存储引擎层产生的
  • binlog是逻辑日志,记录内容是语句的原始逻辑,类似于"给ID=2这一行的c字段加1",属于MySQLServer层

虽然它们都属于持久化的保证,但是则重点不同:

  • redo log 让InnoDB存储引擎拥有了崩溃恢复能力
  • binlog 保证了MySQL集群架构的数据一致性

两阶段提交方案:

在执行更新语句过程,会记录redo log与binlog两块日志,以基本的事务为单位redo log事务执行过程中可以不断写入 ,而binlog只有在提交事务时才写入 ,所以redo log与binlog的写入时机不一样

redo log与binlog两份日志之间的逻辑不一致问题

以update语句为例,假设id=2的记录,字段c值是0,把字段c值更新成1,sQL语句为update Tset c=1 whereid=2。假设执行过程中写完redo log日志后,binlog日志写期间发生了异常,会出现什么情况呢?

由于binlog没写完就异常,这时候binlog里面没有对应的修改记录。因此,之后用binlog日志恢复数据时,就会少这一次更新,恢复出来的这一行c值是o,而原库因为redo log日志恢复,这一行c值是1,最终数据不一致。

为了解决两份日志之间的逻辑一致问题,InnoDB存储引擎使用两阶段提交方案。原理很简单,将redo log的写入拆成了两个步骤prepare和commit ,这就是两阶段提交

使用两阶段提交后,写入binlog时发生异常也不会有影响,因为MysQL根据redo log日志恢复数据时,发现redolog还处于prepare阶段,并且没有对应binlog日志,就会回滚该事务。

当redolog设置commit发生异常时,并不会回滚事务,它会执行上图框住的逻辑,虽然redo log是处于prepare阶段,但是能通过事务id找到对应的binlog日志,所以MySQL认为是完整的,就会提交事务恢复数据。

*中继日志(relay log)

中继日志只在主从服务器架构的从服务器上存在 。从服务器为了与主服务器保持一致,要从主服务器读取二进制日志的内容,并且把读取到的信息写入本地的日志文件 中,这个从服务器本地的日志文件就叫中继日志。然后,从服务器读取中继日志,并根据中继日志的内容对从服务器的数据进行更新 ,完成主从服务器的数据同步

搭建好主从服务器之后,中继日志默认会保存在从服务器的数据目录下。

  • 文件名的格式是: 从服务器名 -relay-bin.序号
  • 中继日志还有一个索引文件:从服务器名 -relay-bin.index,用来定位当前正在使用的中继日志。

1.查看中继日志

中继日志与二进制日志的格式相同,可以用mysqlbinlog 工具进行查看。下面是中继日志的一个片段:

2.恢复的典型错误

如果从服务器宕机,有的时候为了系统恢复,要重装操作系统,这样就可能会导致你的服务器名称 与之前不对应。而中继日志里是包含从服务器名的。在这种情况下,就可能导致你恢复从服务器的时候,无法从宕机前的中继日志里读取数据,以为是日志文件损坏了,其实是名称不对了。

解决的方法也很简单,把从服务器的名称改回之前的名称。

相关推荐
烬奇小云2 小时前
认识一下Unicorn
android·python·安全·系统安全
qq_3089574712 小时前
adb 如何通过wifi连接手机
adb·智能手机·app自动化测试
顾北川_野14 小时前
Android 进入浏览器下载应用,下载的是bin文件无法安装,应为apk文件
android
CYRUS STUDIO14 小时前
Android 下内联汇编,Android Studio 汇编开发
android·汇编·arm开发·android studio·arm
右手吉他14 小时前
Android ANR分析总结
android
PenguinLetsGo16 小时前
关于 Android15 GKI2407R40 导致梆梆加固软件崩溃
android·linux
杨武博19 小时前
音频格式转换
android·音视频
音视频牛哥21 小时前
Android音视频直播低延迟探究之:WLAN低延迟模式
android·音视频·实时音视频·大牛直播sdk·rtsp播放器·rtmp播放器·android rtmp
ChangYan.21 小时前
CondaError: Run ‘conda init‘ before ‘conda activate‘解决办法
android·conda
二流小码农21 小时前
鸿蒙开发:ForEach中为什么键值生成函数很重要
android·ios·harmonyos