1. 数据库的日志管理

1.1 日志管理分类

  • 通用日志: 记录登录数据库用户的操作行为日志 (审计日志)
  • 错误日志: 记录数据库服务运行情况信息 (排查故障)
  • 二进制日志: 记录数据库用户DML DDL DCL操作语句信息(不包含查询语句信息) (恢复数据 主从同步)
  • 慢查询日志: 记录数据库用户查询语句信息 (时间长 没有走索引的查询语句信息 -- 优化调整 -- select * from t1)
    消耗磁盘资源多 影响数据库并发业务 影响数据库主从数据一致性

1.2 通用日志管理

  • 创建生产日志
vim /etc/my.cnf 
general_log=ON
general_log_file=/data/3306/log/general.log
  • 查看日志信息
[root@db-01 ~ 11:05]# tail -f /data/3306/log/general.log 
2024-12-13T03:05:39.568135Z	    8 Connect	root@localhost on  using Socket
2024-12-13T03:05:39.568568Z	    8 Query	select @@version_comment limit 1
2024-12-13T03:06:13.463763Z	    8 Query	select @@version_comment
2024-12-13T03:06:45.285118Z	    8 Query	show databases
2024-12-13T03:07:02.174836Z	    8 Query	SELECT DATABASE()
2024-12-13T03:07:02.175060Z	    8 Init DB	mysql
2024-12-13T03:07:02.175909Z	    8 Query	show databases
2024-12-13T03:07:02.176637Z	    8 Query	show tables

1.3 错误日志管理

  • 创建生成日志
vi /etc/my.cnf 
log_error=/data/3306/log/error.log

touch /data/3306/log/error.log
chown mysql.mysql /data/3306/log/error.log

  • 查看日志信息
cat /data/3306/log/error.log 
2024-12-13T03:29:42.035930Z 0 [System] [MY-010116] [Server] /usr/local/mysql/bin/mysqld (mysqld 8.0.32) starting as process 2995
2024-12-13T03:29:42.043548Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2024-12-13T03:29:42.335614Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2024-12-13T03:29:42.536109Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2024-12-13T03:29:42.536155Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
2024-12-13T03:29:42.562485Z 0 [System] [MY-010931] [Server] /usr/local/mysql/bin/mysqld: ready for connections. Version: '8.0.32'  socket: '/tmp/mysql.sock'  port: 3306  MySQL Community Server - GPL.
2024-12-13T03:29:42.562455Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /tmp/mysqlx.sock

##1.4 二进制日志(binlog)管理配置应用

1.4.1 二进制日志配置参数

  • log_bin -- 开启二进制日志,并设置保存路径信息(新版数据库默认开启 旧版数据库默认关闭)
  • sql_log_bin -- 是否临时禁用二进制日志记录功能 (临时设置--会话级别设置) 1-- 表示记录日志 0 -- 表示关闭记录功能
  • sync_binlog -- 二进制日志记录方式(数据库双一配置)
    -- 参数信息配置0:表示由操作系统缓存自己决定,什么时候刷新日志到磁盘中; 性能考虑设置
    -- 参数信息配置1:表示每次事务提交,立即刷新日志到磁盘中;(此方式配置更安全) 安全考虑设置
    -- 参数信息配置N:表示每组事务提交,按照组的事务次数定义,确定刷新日志到磁盘中的频次;(可以有效减少IO性能损耗)
    -- 参数官方资料链接:https://dev.mysql.com/doc/refman/8.0/en/replication-options-binary-log.html
  • binlog_format -- 设置日志格式信息
    SBR -- 语句格式记录binlog信息 可以清楚看到DML相关语句操作信息 update insert delete 恢复数据会出现不易
    RBR -- 行格式记录binlog信息 不能清楚看到DML相关语句操作信息 将行的数据信息编码处理记录 恢复数据可以保证一致性

  • 查看日志信息
# ll /data/3306/log/bin-log.*
-rw-r----- 1 mysql mysql 157 Dec 13 12:15 /data/3306/log/bin-log.000001
-rw-r----- 1 mysql mysql  30 Dec 13 12:15 /data/3306/log/bin-log.index
  • 开启二进制日志
vi /etc/my.cnf 
log_bin=/data/3306/log/bin-log

1.4.2 二进制日志查看方法


  1. 在数据库中查看
   mysql> show binary logs;                                   
   +----------------+-----------+-----------+
   | Log_name       | File_size | Encrypted |
   +----------------+-----------+-----------+
   | bin-log.000001 |       157 | No        |
   | bin-log.000002 |       202 | No        |
   | bin-log.000003 |       180 | No        |
   | bin-log.000004 |       157 | No        |
   +----------------+-----------+-----------+
   -- 查看生成binlog日志信息,会显示生成过的binlog名称和大小信息
   
   mysql> show master status;
   +----------------+----------+--------------+------------------+-------------------+
   | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
   +----------------+----------+--------------+------------------+-------------------+
   | bin-log.000004 |      157 |              |                  |                   |
   +----------------+----------+--------------+------------------+-------------------+
   -- 显示最新binlog,以及大小信息或者记录位置点信息
   -- Binlog_Do_DB  		若开启数据库binlog日志白名单功能,会显示哪个数据库的操作将记录到binlog
   -- Binlog_Ignore_DB      若开启数据库binlog日志黑名单功能,会将指定数据库的操作不会记录到binlog
   -- Executed_Gtid_Set     将每个数据库的操作行为设置一个唯一编号信息
      create database test01  --- 157 -  170  唯一编号  0004157170   bin-log.000004      0004157170 
      create database test02  --- 157 -  170  唯一编号  0005157170   bin-log.000005
      drop database test01 
      157 - 170   create database test01
	
   mysql> show binlog events in 'bin-log.000004';
   +----------------+------+----------------+-----------+-------------+-------------------------------------------------------------------------------+
   | Log_name       | Pos  | Event_type     | Server_id | End_log_pos | Info                                                                          |
   +----------------+------+----------------+-----------+-------------+-------------------------------------------------------------------------------+
   | bin-log.000004 |    4 | Format_desc    |         1 |         126 | Server ver: 8.0.32, Binlog ver: 4                                             |
   | bin-log.000004 |  126 | Previous_gtids |         1 |         157 |                                                                               |
   | bin-log.000004 |  157 | Anonymous_Gtid |         1 |         234 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                          |
   | bin-log.000004 |  234 | Query          |         1 |         344 | drop database test01 /* xid=9 */   	

  • DDL操作语句记录binlog:会记录时间编号信息(需要开启gtid) 以及DDL操作语句信息(可读)
  • DML操作语句记录binlog:会记录时间编号信息(需要开启gtid) 以及DML操作语句信息(不可读-ROW格式) 还会生成记录begin... commit信息
  • begin ... commit / begin .. rollback -- 是否将内存中的改动信息/创建信息/删除信息,写入到磁盘(内存信息落盘)
    -- 实现可以确认或反悔的机制称为数据库事务机制
  1. 在命令行中查看
   mysqlbinlog  bin-log.000004
   mysqlbinlog --base64-output=decode-rows -vvv  bin-log.000004

   ### INSERT INTO `test01`.`t1`                        INSERT INTO `test01`.`t1` set @1(第一列)=1(设置的信息)   
   ### SET
   ###   @1=1 /* INT meta=0 nullable=1 is_null=0 */

 
   ### INSERT INTO `test01`.`t2`                        INSERT INTO `test01`.`t2` SET @1=1  @2='xiaoA' @3=20               
   ### SET
   ###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
   ###   @2='xiaoA' /* STRING(40) meta=65064 nullable=1 is_null=0 */
   ###   @3=20 /* TINYINT meta=0 nullable=1 is_null=0 */
   
   ### INSERT INTO `test01`.`t2`                        INSERT INTO `test01`.`t2` SET @1=2  @2='xiaoB' @3=21 
   ### SET
   ###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
   ###   @2='xiaoB' /* STRING(40) meta=65064 nullable=1 is_null=0 */
   ###   @3=21 /* TINYINT meta=0 nullable=1 is_null=0 */
  1. sql_log_bin 临时关闭binlog功能
   sql_log_bin   -- 是否需要临时关闭binlog日志记录功能
   mysql> set sql_log_bin=0;
   Query OK, 0 rows affected (0.00 sec)
   mysql> create database test03;
   Query OK, 1 row affected (0.00 sec)
   mysql> create database test04;
   Query OK, 1 row affected (0.00 sec)
   mysql> set sql_log_bin=1;
   Query OK, 0 rows affected (0.00 sec)
   mysql> create database test05;
   Query OK, 1 row affected (0.01 sec)
   
  | bin-log.000004 | 1810 | Anonymous_Gtid |         1 |        1887 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                          |
  | bin-log.000004 | 1887 | Query          |         1 |        2001 | create database test02 /* xid=35 */                                           |
  | bin-log.000004 | 2001 | Anonymous_Gtid |         1 |        2078 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                          |
  | bin-log.000004 | 2078 | Query          |         1 |        2192 | create database test05 /* xid=42 */ 
  -- 在进行数据恢复时,恢复数据的语句就可以不用再记录到binlog了;
  1. binlog_format 加密与可读性
  • row (RBR) -- 加载恢复binlog日志可以保证数据一致性,但是阅读性差 (DML操作语句)
  • statement (SBR) -- 加载恢复binlog日志无法保证数据一致性,但是阅读性强 (DML操作语句)
  • mixed (MBR) -- 数据库服务自动选择识别binlog信息,自动显示dml信息 (明文信息 看不明白-编码信息)
mysql> set global binlog_format='statement';   -- 临时全局设置(可以永久设置)
  1. 其他函数
  • sync_binlog -- 影响binlog日志写入到文件的过程方式
  • sync_binlog=0 -- binlog日志文件中具有信息记录,由系统决定
  • sync_binlog=1 -- 每操作一次commit,都会及时将事件信息同步到磁盘binlog文件
  • sync_binlog=3 -- 每操作三次commit,才会将对应事件信息同步到磁盘binlog文件

1.4.3 二进制日志过滤查看


  • 方式一:在数据库中利用语句功能过滤

    • pager less -- 开启binlog过滤功能
    • pager grep "drop database" -- 定义需要过滤显示的binlog内容信息
  • 方式二:在命令行中利用命令功能过滤 (grep sed awk)

    • mysqlbinlog bin-log.000004|grep/sed/awk

1.4.4 二进制日志恢复数据


数据库服务需要进行数据恢复:
情况一:数据库数据出现物理损坏情况 --- 数据库服务器宕机 磁盘故障 文件系统异常 数据库目录有文件损害 ....
如何恢复数据:使用备份文件 使用从数据库
情况二:数据库数据出现逻辑损坏情况 --- 误删除 误修改 误插入
如何恢复数据:使用备份文件 使用二进制文件

案例

0-01 9:00  创建一个新的数据库
create database test06;

10-01 10:00 创建一个新的数据表 
use test06; 
create table t1 (id int,name char(5));

10-01 11:00 在新的表中插入数据
insert into t1 values (1,'xiaoA');
insert into t1 values (2,'xiaoB');   00001   update 00002  delete 0003  insert 0004 ...  005 ...   0006
insert into t1 values (3,'xiaoC');

10-01 12:00 误将数据表信息清空了
delete from t1;

解决恢复方案

10-01 12:00+  恢复数据		
步骤一:确认需要恢复的数据信息
pager grep "t1" 
步骤二:获取恢复数据的位置信息
起始位置点:719
结束位置点:1484
步骤三:利用mysqlbinlog命令将需要的数据信息进行截取,并利用截取后的数据文件恢复数据
--start-position:719
--stop-position: 1484

mysqlbinlog --start-position=719 --stop-position=1484 bin-log.000005
mysqlbinlog --start-position=719 --stop-position=1484 bin-log.000005 >/tmp/t1.sql
mysql -uroot -p123456 </tmp/t1.sql

1.4.5 企业实际情况


企业恢复数据情况01:有些需要恢复数据的binlog文件被清理了
企业恢复数据情况02:需要恢复的数据信息分不在不同binlog文件中 备份数据恢复
企业恢复数据情况03:只是误操作影响了部分行的数据 1000w行 误操作影响4行数据,如何将误操作的数据修改
delete from t1 where name in ('李四','张三','王五')

1.4.6 二进制日志切割设置


  • 方式一:利用命令切割:(手工)
mysql> flush logs;
Query OK, 0 rows affected (0.01 sec)

mysql> show binary logs;
+----------------+-----------+-----------+
| Log_name       | File_size | Encrypted |
+----------------+-----------+-----------+
| bin-log.000001 |       157 | No        |
| bin-log.000002 |       202 | No        |
| bin-log.000003 |       180 | No        |
| bin-log.000004 |      3520 | No        |
| bin-log.000005 |      3413 | No        |
| bin-log.000006 |       202 | No        |
| bin-log.000007 |       157 | No        |
+----------------+-----------+-----------+


#命令行
mysqladmin -uroot -p123456 flush-logs
  • 方式二:实现自动切割
编写切割脚本文件 -- 定时任务中
mysqladmin -uroot -p123456 flush-logs

实现根据日志量进行自动切割
select @@max_binlog_size;
set global max_binlog_size=1048576;  -- 设置为1M

1.4.7 二进制日志清理设置


  • 方式一:进行日志信息自动清理
    • binlog_expire_logs_seconds -- 按照秒为单位,进行历史切割日志的清理 (30天)
    • expire_logs_days -- 按照天为单位,进行历史切割日志的清理 (默认关闭)
    • set global -- 临时设置,进行配置项功能测试;
  • 方式二:进行日志信息手工清理
mysql> show binary logs;
+----------------+-----------+-----------+
| Log_name       | File_size | Encrypted |
+----------------+-----------+-----------+
| bin-log.000009 |    202442 | No        |
| bin-log.000010 |       202 | No        |
| bin-log.000011 |       202 | No        |
| bin-log.000012 |       202 | No        |
| bin-log.000013 |       202 | No        |
| bin-log.000014 |       157 | No        |
+----------------+-----------+-----------+
6 rows in set (0.00 sec)

mysql> purge binary logs to 'bin-log.000013';             -- 根据日志名称进行手工删除日志
Query OK, 0 rows affected (0.00 sec)

mysql> show binary logs;
+----------------+-----------+-----------+
| Log_name       | File_size | Encrypted |
+----------------+-----------+-----------+
| bin-log.000013 |       202 | No        |
| bin-log.000014 |       157 | No        |
+----------------+-----------+-----------+
2 rows in set (0.00 sec)

mysql> PURGE BINARY LOGS BEFORE '2019-04-02 22:46:26';   -- 根据日志切割后出现的时间进行删除日志

**注意:一定不能采用rm方式清理日志信息 **

1.4.8 二进制日志备份管理 (MHA数据库高可用软件 -- 加载日志备份服务器中备份日志信息)


  • 步骤一:需要创建生成日志备份服务器,并安装数据库程序(二进制包解压)
mysql -V
mysql  Ver 8.0.32 for Linux on x86_64 (MySQL Community Server - GPL)
  • 步骤二:创建不同数据库实例的数据目录
db01 - 3356 3357 3380    全网备份  web01 web02 web03  nfs ...   backup/10.0.0.51  backup/10.0.0.52
db02 - 3306 3307 3308
...

mkdir /backup/10.0.0.51_3306 -p
cd /backup/10.0.0.51_3306/
  • 步骤三:进行日志信息的备份 (实时备份)
cd /backup/10.0.0.51_3306/
mysqlbinlog -R --host=10.0.0.51 --user=root --password=123 --raw --stop-never bin-log.000017  &

[root@manager 10.0.0.51_3306 15:47]# ll
total 16
-rw-r----- 1 root root 202 Dec 16 15:44 bin-log.000017
-rw-r----- 1 root root 202 Dec 16 15:44 bin-log.000018
-rw-r----- 1 root root 202 Dec 16 15:44 bin-log.000019
-rw-r----- 1 root root 348 Dec 16 15:46 bin-log.000020

1.5 慢查询日志管理配置应用 (可以应用日志信息做数据库语句优化)


1.5.1 创建生成慢查询日志

  • slow_query_log --- 是否生成慢查询日志 0-默认禁用慢查询日志 1-激活慢查询日志功能

  • slow_query_log_file --- 指定慢查询日志存储路径以及名称信息

  • long_query_time --- 指定慢查询日志参考时间,超过设定时间完成的查询操作,都成为慢查询会保存到日志中
    (企业环境一般不超过5s~10s,超过5s语句可以考虑进行优化)

  • log_queries_not_using_indexes --- 将没有走索引的语句需要记录到慢查询日志

  • 永久开启

vi /etc/my.cnf 
slow_query_log=ON
slow_query_log_file=/data/3306/log/slow.log
long_query_time=0.01
log_queries_not_using_indexes=1;

1.5.2 查看慢查询日志信息

Time                 Id Command    Argument
# Time: 2025-01-19T17:00:29.297572Z
# User@Host: root[root] @ localhost []  Id:     8
# Query_time: 0.025341  Lock_time: 0.000003 Rows_sent: 1  Rows_examined: 0
use world;
SET timestamp=1737306029;
select count(*) from city;

2. 数据库备份恢复管理

2.1 物理备份恢复

2.1.1 含义及特点

物理备份恢复:将数据目录中数据信息做整体备份
优势特点:在进行数据备份时,当数据量大的时候,备份效率快
缺陷说明:需要进行停止数据库服务备份/恢复 备份数据的灵活性不高(全备)
PS:可以使用第三方软件工具,实现物理备份的热备操作;

2.1.2 物理备份数据/恢复数据

  • 步骤一:需要停止数据库服务*
/etc/init.d/mysql.server stop
  • 步骤二:将数据库数据目录做备份
cp -a /data/3306/data/ /backup/
  • 步骤三:恢复数据库服务/以及恢复原有数据
rm -rf /data/3306/data/ 
ps -ef|grep mysql   -- 确认数据库服务关闭状态
cp -a /backup/data/  /data/3306/
  • 步骤四:恢复启动数据库服务
/etc/init.d/mysql.server start

2.2 逻辑备份恢复

2.2.1 含义及特点

逻辑备份恢复:将数据库服务的数据信息转换成SQL语句进行备份
优势特点:进行备份/恢复数据时,可以实现不停止数据库服务操作备份恢复 备份数据的灵活性较高(分库分表)
缺陷说明:在备份大量数据或恢复大量数据信息时,时间成本较高
PS:在企业环境中,如果备份的数据量超过50G,建议采用物理备份数据,若不超过50G,建议采用逻辑备份

2.2.2 逻辑备份数据/恢复数据: mysqldump

  • 方式一: 全备操作
· 备份数据 
mysqldump -uroot -p123456 -S /tmp/mysql.sock  -A  >/backup/all.sql  -- 本地全备
mysqldump -uroot -p123456 -h 10.0.0.51 -P3306 -A  >/backup/all.sql  -- 远程全备(云主机数据库服务做备份-RDS)

· 恢复数据 
mysql -uroot -p123456 -S /tmp/mysql.sock      </backup/all.sql  -- 本地恢复 
mysql -uroot -p-p123456 -h 10.0.0.51 -P3306   </backup/all.sql  -- 远程恢复 

mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)

source /backup/all.sql  -- 数据恢复

mysql> set sql_log_bin=1;
Query OK, 0 rows affected (0.00 sec)

  • 方式二: 分库备份
· 备份数据 
mysqldump -uroot -p123456 -S /tmp/mysql.sock  -B world oldboy  >/backup/world_oldboy.sql

· 恢复数据 
mysql -uroot -p123456 -S /tmp/mysql.sock      </backup/world_oldboy.sql  -- 本地恢复 
mysql -uroot -p-p123456 -h 10.0.0.51 -P3306   </backup/world_oldboy.sql  -- 远程恢复 

mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)

source /backup/world_oldboy.sql  -- 数据恢复

mysql> set sql_log_bin=1;
Query OK, 0 rows affected (0.00 sec)

PS:https://blog.csdn.net/shenql_/article/details/131968148 --如何利用脚本实现分库备份 (每天/每周)

  • 方式三: 分表备份
· 备份数据 
mysqldump -uroot -p123456 -S /tmp/mysql.sock world city >/backup/city.sql 
-- 分表备份文件中,不含有创建库的语句,以及切换数据库的语句

· 恢复数据
mysql -uroot -p123456 -S /tmp/mysql.sock    world  </backup/city.sql   -- 本地恢复 
mysql -uroot -p-p123456 -h 10.0.0.51 -P3306 world  </backup/city.sql   -- 远程恢复 

mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)

use world 
source /backup/city.sql   -- 数据恢复

mysql> set sql_log_bin=1;
Query OK, 0 rows affected (0.00 sec)