DBA之路 9_MySQL_日志和备份恢复与迁移

上级回顾

1.上节遗留问题

RC模式:可以屏蔽脏读,但是会出现,不可重复度读和幻读
select @@tx_isolation;

2.重点参数

<1>innodb_flush_log_at_trx_commit
0:redobuffer -----每秒-----os buffer ----每秒-----磁盘
如果出现宕机,可能丢失一秒的事务
如果说你的业务对于数据丢失有一定的容忍度的时候可以使用
例如:监控系统
1: redobuffer-----每事务(commit)-----OS buffer------每事务(commit)----磁盘

2: redobuffer-----每事务(commit)-----OS buffer------每秒-----磁盘

<2>innodb_flush_method=O_DIRECT
控制redo buffer和data buffer刷写磁盘的策略,即刷写磁盘是否经过OS buffer
该模式下data buffer刷盘不经过os buffer
日志刷盘经过os buffer

<3>innodb_buffer_pool_size    50%-80%

今日预计内容

1.日志

1.1排错

错误日志

怎么配置?
配置方式:
vim /etc/my.cnf
log_error=/data/mysql/data/mysql.log
默认位置:在数据路径下DATADIR/hostname.err
使用方法:
查看[error]上下文
重启生效
show variables like 'log_error';
select @@log_error;

1.2数据恢复

binlog(二进制日志)

作用

(1)备份恢复必须依赖二进制日志
(2)主从环境必须依赖二进制日志

2.2 binlog配置 (5.7必须加server_id)

log_bin    
1.打开二进制日志功能
2.设定存放位置
server_id
1.5.6中单机不需要
2.5.7中必须要添加
注意1:日志要和数据分开存放
注意2:MySQL默认是没有开启二进制日志的。
基础参数查看:
开关:
[(none)]>select @@log_bin;
日志路径及名字
[(none)]>select @@log_bin_basename;
服务ID号:
[(none)]>select @@server_id;
二进制日志格式:
[(none)]>select @@binlog_format;
双一标准之二:
[(none)]>select @@sync_binlog;

2.2.1 创建日志目录

mkdir /data/binlog
chown -R mysql.mysql /data/binlog

2.2.2 修改配置文件

vim /etc/my.cnf
server_id=6                                    ----->5.6中,单机可以不需要此参数              
log_bin=/data/binlog/mysql-bin
binlog_format=row

2.2.3 重启数据库生效

[root@db01 mysql]# /etc/init.d/mysqld restart

2.2.4 参数说明

server_id=3306 
主要是在主从复制过程中必须要加的,但是在5.7版本中,要用以下参数(log_bin),开启binlog日志,即使是单机也是必加的
log_bin=/data/binlog/mysql-bin
(1)开启二进制日志功能
(2)设置二进制日志目录及名称前缀
binlog_format=row
binlog的记录格式??

2.3 binlog记录了什么?

2.3.1.大面上说明
记录了数据库中所有变更类的操作
DDL     DCL      DML
2.3.2详细说明
<1>
对于DDL和DCL语句,记录发生过的语句
<2>
对于DML(IUD)语句(insert update delete)
前提:已经提交的事务IUD
关于记录格式:
  *  ROW  :RBR   行记录模式
    记录的行的变化
    STATEMENT :  SBR  语句记录格式
    记录操作语句本身,数据恢复加入语句中有now函数,会造成数据时间不严谨
    MIXED  :MBR    混合记录模式
delect from city where id>1000;
RBR  逐行记录,日志量很大,可读性差,但是够严谨,不会出现记录错误
SBR  只记录语句本身,日志量很少,可读性较强,对于函数类操作,将来恢复时会造成错误

5.7版本:默认是RBR模式,也是企业建议模式
模式查看
mysql> select @@binlog_format;
+-----------------+
| @@binlog_format |
+-----------------+
| ROW             |
+-----------------+
1 row in set (0.00 sec)

1.2.5二进制日志事件(event)
事件简介
可记录的最小单元是event
二进制日志的最小记录单元
对于DDL,DCL,一个语句就是一个event
对于DML语句来讲:只记录已提交的事务。
例如以下列子,就被分为了4个event
             position(位置)号码
begin;      120  - 340
DML1        340  - 460
DML2        460  - 550
commit;     550  - 760
event构成
三部分构成
(1)事件的开始标志
(2)事件内容
(3)事件的结束标志
position
开始标志    at 194
结束标志    end_log_pos 254
184?254?
某个事件在binlog中的相对位置号
位置号的作用是什么?
为了方便我们截取事件
1.2.6 二进制日志的查看
查看二进制日志所在位置
mysql> show variables like '%log_bin%';

查看正在使用的二进制日志
mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       154 |
+------------------+-----------+
1 row in set (0.00 sec)
log_name:目前MySQL存在的二进制日志名字
file_size:目前这个二进制日志用到哪个position号
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)

2.2.7查看二进制文件内容***********
查看二进制日志事件
image.png

一般配合使用

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    |         7 |         123 | Server ver: 5.7.26-log, Binlog ver: 4 |
| mysql-bin.000001 | 123 | Previous_gtids |         7 |         154 |                                       |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
2 rows in set (0.00 sec)

5.6 前120个
5.7版本前154个属于日志头信息格式。
注释:每行都是一个事件
列的信息:
Log_name    :  日志名
Pos               :事件开始的position
Event_type   :事件类型
Server_id      :发生在哪台机器上的(一般用在主从)
End_log_pos:事件结束的position
 Info              :事件内容
[root@db01 /data/binlog]# mysqlbinlog mysql-bin.000002 |grep -v "SET" >/tmp/aa.txt
^简易版查看
 mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000001
^详细版查看
image.png
1.2.8基于二进制日志数据恢复案例
如何按需截取日志
基于position号的截取*****
--start-position=***
--stop-position=***
截取二进制日志核心在于找起点和终点
[root@zyl666 /data/binlog]# mysqlbinlog --start-position=219 --stop-position=310 mysql-bin.000001 >/tmp/bin.sql
恢复数据之前执行
set sql_log_bin=0

2. 基于时间点的截取(了解)

--start-datetime
--stop-datetime
for example: 2004-12-25 11:25:56
案例恢复详解
#1. 模拟环境
create database binlog charset utf8mb4;

use binlog;
create table t1(id int);

insert into t1 values(1);
commit;
insert into t1 values(2);
commit;
insert into t1 values(3);
commit;

drop database binlog;

#2. 查看事件
mysql> show binlog events in 'mysql-bin.000002';

| mysql-bin.000002 |  980 | Query          |         6 |        1096 | create database binlog charset utf8mb4 |
| mysql-bin.000002 | 2098 | Query          |         6 |        2196 | drop database binlog

# 3. 截取日志
[root@db01 ~]# mysqlbinlog --start-position=980 --stop-position=2098 /data/binlog/mysql-bin.000002 >/tmp/bak.sql
# 4. 进行恢复
mysql> set sql_log_bin=0;
mysql> source /tmp/bak.sql

# 5. 验证数据
mysql> use binlog
Database changed
mysql> select * from t1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+

开启GTID功能的二进制日志管理
思考:如何分段截取,下面的如何恢复
create database binlog charset utf8mb4;

use binlog;
create table t1(id int);

insert into t1 values(1);
commit;
insert into t1 values(2);
commit;
truncate table t1;
insert into t1 values(3);
commit;

drop database binlog;
基于position号恢复需要多次截取,找起点和终点过程复杂

GTID介绍(全局事务变化)

5.6 版本新加的特性,5.7中做了加强
5.6 中不开启,没有这个功能.
5.7 中的GTID,即使不开也会有自动生成
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
2.8.2. GTID(Global Transaction ID)
是对于一个已提交事务的编号,并且是一个全局唯一的编号。
它的官方定义如下:

GTID = source_id :transaction_id
7E11FA47-31CA-19E1-9E56-C43AA21293967:29
说明:DDL,DCL一条语句(一个事件),就是一个事务,占一个GTID号
DML语句:一个完整的事务(begin---commit)就占一个GTID号
开启GTID
vim /etc/my.cnf
gtid-mode=on
enforce-gtid-consistency=true
#### 基于GTID截取二进制日志

[root@db01 ~]# mysqlbinlog --include-gtids='ee956c61-9653-11e9-8518-000c29099eb6:1-5' /data/binlog/mysql-bin.000003 >/tmp/gtid.sql
注意:以上截取的内容不能直接恢复,为啥
gtid的幂等性?
正确的截取方法:
--skip-gtids跳过检查
mysqlbinlog --skip-gtids --include-gtids='e0e94318-8de0-11e9-bbf7-000c29c19cf1:1-3' mysql-bin.000002 >/tmp/gtids.sql

###跳过某些gtid截取
mysqlbinlog --skip-gtids --include-gtids='e0e94318-8de0-11e9-bbf7-000c29c19cf1:1-3'  --exclude-gtids='e0e94318-8de0-11e9-bbf7-000c29c19cf1:2-3'mysql-bin.000002 >/tmp/gtids.sql

重要参数介绍

vim /etc/my.cnf
gtid-mode=on
enforce-gtid-consistency=true
systemctl restart mysqld

Master [(none)]>create database gtid charset utf8;
Query OK, 1 row affected (0.01 sec)

Master [(none)]>show master status ;
+------------------+----------+--------------+------------------+----------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                      |
+------------------+----------+--------------+------------------+----------------------------------------+
| mysql-bin.000004 |      326 |              |                  | dff98809-55c3-11e9-a58b-000c2928f5dd:1 |
+------------------+----------+--------------+------------------+----------------------------------------+
1 row in set (0.00 sec)

Master [(none)]>use gtid
Database changed
Master [gtid]>create table t1 (id int);
Query OK, 0 rows affected (0.01 sec)

Master [gtid]>show master status ;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000004 |      489 |              |                  | dff98809-55c3-11e9-a58b-000c2928f5dd:1-2 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

Master [gtid]>create table t2 (id int);
Query OK, 0 rows affected (0.01 sec)

Master [gtid]>create table t3 (id int);
Query OK, 0 rows affected (0.02 sec)

Master [gtid]>show master status ;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000004 |      815 |              |                  | dff98809-55c3-11e9-a58b-000c2928f5dd:1-4 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

Master [gtid]>begin;
Query OK, 0 rows affected (0.00 sec)

Master [gtid]>insert into t1 values(1);
Query OK, 1 row affected (0.00 sec)

Master [gtid]>commit;
Query OK, 0 rows affected (0.00 sec)

Master [gtid]>show master status ;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000004 |     1068 |              |                  | dff98809-55c3-11e9-a58b-000c2928f5dd:1-5 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

Master [gtid]>begin;
Query OK, 0 rows affected (0.00 sec)

Master [gtid]>insert into t2 values(1);
Query OK, 1 row affected (0.00 sec)

Master [gtid]>commit;
Query OK, 0 rows affected (0.01 sec)

Master [gtid]>show master status ;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000004 |     1321 |              |                  | dff98809-55c3-11e9-a58b-000c2928f5dd:1-6 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

1.2.10二进制日志的其他操作

临时关闭

set sql_log_bin=0     --->临时关闭二进制日志记录,退出MySQL窗口就会恢复
做数据恢复之前使用以上参数
自动清理
参数:mysql> select @@expire_logs_days;
+--------------------+
| @@expire_logs_days |
+--------------------+
|                  0 |
+--------------------+
1 row in set (0.00 sec)
设置依据?
至少是一个全备的周期。企业建议至少两个全备周期+1。
临时,重启生效
mysql> set global expire_logs_days=8;
永久设置则写配置文件就行
手动清理
PURGE BINARY LOGS BEFORE now() - INTERVAL 3 day;
PURGE BINARY LOGS TO 'mysql-bin.000010';
注意:不要手工 rm binlog文件
1. my.cnf binlog关闭掉,启动数据库
2.把数据库关闭,开启binlog,启动数据库
删除所有binlog,并从000001开始重新记录日志
删除所有binlog,从000001开始重新计数
日志滚动
flush logs;
mysqladmin -uroot -p flush-logs
mysql> show variables like '%max_binlog_size%'
    -> ;
+-----------------+------------+
| Variable_name   | Value      |
+-----------------+------------+
| max_binlog_size | 1073741824 |
+-----------------+------------+
1 row in set (0.00 sec)

1.3优化相关日志-slowlog

1.3.1作用

记录慢SQL语句的日志,定位低效SQL语句的工具日志

1.3.2开启慢日志(默认不开)

开关:
slow_query_log=1 
文件位置及名字 
slow_query_log_file=/data/mysql/slow.log
设定慢查询时间:
long_query_time=0.1
没走索引的语句也记录:
log_queries_not_using_indexes
vim /etc/my.cnf
slow_query_log=1 
slow_query_log_file=/data/mysql/slow.log
long_query_time=0.1
log_queries_not_using_indexes
systemctl restart mysqld


mysqldumpslow -s c -t 10 /data/mysql/data/slow.log

3.3 mysqldumpslow 分析慢日志
mysqldumpslow -s c -t 10 /data/mysql/slow.log

第三方工具(自己扩展)

https://www.percona.com/downloads/percona-toolkit/LATEST/
yum install perl-DBI perl-DBD-MySQL perl-Time-HiRes perl-IO-Socket-SSL perl-Digest-MD5
toolkit工具包中的命令:
./pt-query-diagest  /data/mysql/slow.log
Anemometer基于pt-query-digest将MySQL慢查询可视化

2.备份恢复与迁移***********

1.运维在数据库备份恢复方面的职责

1.1设计备份策略

全备
增量

时间
自动

1.2日常备份检查

备份存在性
备份空间够用否

1.3定期恢复演练(测试库)

一季度或者半年

1.4故障恢复

通过现有备份,能够将数据库恢复到故障之前的时间点

1.5迁移

1.停机时间
2.回退方案

2. 备份类型

2.1 热备

在数据库正常业务时,备份数据,并且能够一致性恢复(只能是innodb)
对业务影响非常小

2.2 温备

锁表备份,只能查询不能修改(myisam)
影响到写入操作

2.3 冷备

关闭数据库业务,数据库没有任何变更的情况下,进行备份数据.
业务停止

3. 备份方式及工具介绍

3.1 逻辑备份工具

基于SQL语句进行备份
mysqldump       *****
mysqlbinlog     *****

3.2 物理备份工具

基于磁盘数据文件备份
xtrabackup(XBK) :percona 第三方 支持热备  *****
MySQL Enterprise Backup(MEB)

4. 逻辑备份和物理备份的比较

4.1 mysqldump (MDP)

优点:
1.不需要下载安装
2.备份出来的是SQL,文本格式,可读性高,便于备份处理
3.压缩比较高,节省备份的磁盘空间

缺点:
4.依赖于数据库引擎,需要从磁盘把数据读出
然后转换成SQL进行转储,比较耗费资源,数据量大的话效率较低
建议:
100G以内的数据量级,可以使用mysqldump
超过TB以上,我们也可能选择的是mysqldump,配合分布式的系统
1EB  =1024 PB =1000000 TB

4.2 xtrabackup(XBK)

优点:
1.类似于直接cp数据文件,不需要管逻辑结构,相对来说性能较高
缺点:
2.可读性差
3.压缩比低,需要更多磁盘空间
建议:
>100G

5.备份策略

备份方式:
全备:全库备份,备份所有数据
增量:备份变化的数据
逻辑备份=mysqldump+mysqlbinlog
物理备份=xtrabackup_full+xtrabackup_incr+binlog或者xtrabackup_full+binlog
备份周期:
根据数据量设计备份周期
比如:周日全备,周1-周6增量

6.逻辑备份工具-mysqldump

6.1客户端通用命令,和链接有关的

-u
-p
-P
-S
-h
支持本地和远程备份
mysqldump -uroot -p123 -S /tmp/mysql.sock
mysqldump -uroot -p123 -h 10.0.0.51 -P3306 

6.2基本备份参数

-A 全库备份

例子1:
[root@db01 ~]# mkdir -p /data/backup
mysqldump -uroot -p -A >/data/backup/full.sql
Enter password: 

mysqldump: [Warning] Using a password on the command line interface can be insecure.
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events. 

# 补充:
# 1.常规备份是要加 --set-gtid-purged=OFF,解决备份时的警告
# [root@db01 ~]# mysqldump -uroot -p123 -A  --set-gtid-purged=OFF  >/backup/full.sql
# 2.构建主从时,做的备份,不需要加这个参数
# [root@db01 ~]# mysqldump -uroot -p123 -A    --set-gtid-purged=ON >/backup/full.sql


-B备份多个单库

说明:生产中需要备份,生产相关的库和MySQL库
例子2 :
[root@zyl666 ~]# mysqldump -uroot -p -S /data/3307/mysql.sock -B mysql oldboy --set-gtid-purged=OFF >/data/backup/b.sql 

备份单个或多个表

例子3 world数据库下的city,country表
mysqldump -uroot -p world city country >/backup/bak1.sql
以上备份恢复时:必须库事先存在,并且ues才能source恢复
注意:此种方法只会备份建表和插入语句,恢复前需要提前把库建好,并且use进去

6.3必须参数(1)**************

-R  备份时,同时备份存储过程和函数,如果没有则自动忽略,没有警告
-E  备份事件events,如果没有则自动忽略
--triggers 备份触发器,如果没有则自动忽略

6.4必加参数(2)

--master-data=2
记录备份开始时,position号,可以作为将来日志截取的起点
功能:1.记录备份时的position
2.自动锁表
3.配合--single-transaction,减少锁的(innodb引擎)
--single-transaction
功能:
对于InnoDB的表,实现快照备份,不需要锁表

6.5其他

-F 在备份开始时,刷新一个新binlog日志,你有多少库会刷多少个binlog。
--set-gtid-p  urged=auto 默认是自动,
auto ,on,off
     使用场景:
     1. --set-gtid-purged=OFF,可以使用在日常备份参数中.
mysqldump -uroot -p -A -R -E --triggers --master-data=2  --single-transaction --set-gtid-purged=OFF >/data/backup/full.sql
    2. auto , on:在构建主从复制环境时需要的参数配置
mysqldump -uroot -p -A -R -E --triggers --master-data=2  --single-transaction --set-gtid-purged=ON >/data/backup/full.sql
--max-allowed-packet=xxxxx
mysqldump -uroot -p -A -R -E --max-allowed-packet-128M --triggers --master-data=2  --single-transaction --set-gtid-purged=ON >/data/backup/full.sql

你可能感兴趣的:(DBA之路 9_MySQL_日志和备份恢复与迁移)