10_MySQL笔记-日志-备份和还原

Posted mycpen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10_MySQL笔记-日志-备份和还原相关的知识,希望对你有一定的参考价值。

文章目录


个人博客
https://blog.csdn.net/cPen_web


OLTP和OLAP 在线事务处理和在线分析处理
https://my.oschina.net/u/2969788/blog/2875200

oltp和olap
	oltp和olap是两种常见的业务模式
	oltp(on line transcation processing) 在线事务处理 它具有以下特点,常见的系统如银行财务
	实时性要求高
	数据量相对较小
	要求绝对的事务完整性,增删改查操作一般都会涉及
	并发量高
	olap(on line analytical processing) 在线分析处理,这种业务一般是日志的分析和深度挖掘,常见如淘宝的交易记录,百度地图的人口迁徙记录 具有以下特点,olap的结果一般是为决策提供支持
	数据量通常非常大
	对事务要求不高 通常只有 添加和查询操作
	实时性要求不高通常只有汇总后的结果,而汇总分析过程通常可以执行很久

日志

日志 (log)

作用:
	1 .排错
	2 .了解mysql运行情况
类型:
	1 .二进制日志
	2 .错误日志
	3 .慢日志
	4 .查询日志

错误日志

错误日志:mysql本身就是开启的

错误日志:记录用户登录和服务启动出错相关的信息 --> 默认开启
在配置文件里指定错误日志的路径
[root@cPen mysql]# vim /etc/my.cnf
#log-error=/var/log/mysql/mysql.log
log-error=/data/mysql/mysql.log

默认存放的路径在数据目录下	(路径会存在/data目录下)
编译安装路径:/data/mysql/mysql_compile.err  命令格式:主机名.err

	记录用户登录和服务启动出错相关的信息 --> 默认开启的
	默认放到与数据目录所在的地方,主机名.err
什么时候会写数据到错误日志文件?
	1 .登录失败会记录到错误日志
	2 .配置文件出错也会记录 --> 没有看到效果,编译安装的MySQL --> 需要进一步测试
	3 .启动过程出问题也会记录
mysql_compile.pid	记录mysqld的pid号

如果指定错误日志的路径,注意目的地的目录需要给mysql用户写的权限
[root@cPen ~]# cd /data/mysql/
[root@cPen mysql]# ls |grep "err"
mysql_compile.err
#示例:指定错误日志
[root@cPen mysql]# vim /etc/my.cnf
[mysqld]
log-error=/var/log/mysql/mysql.log
#注:log-error和log_error都可以

[root@cPen mysql]# mkdir /var/log/mysql
[root@cPen mysql]# cd /var/log/
[root@cPen log]# chown mysql:mysql mysql/				#注:加权限,mysql用户要有写的权利

root@(none) mysql>show variables like "log_error";		#注:在MySQL里查看变量的值
#示例:删除pid文件mysql_compile.pid,mysql服务不能关闭,因为里面放了mysqld 的pid号
[root@cPen mysql]# cd /data/mysql/
[root@cPen mysql]# ls |grep mysql_compile.pid
mysql_compile.pid

慢日志

慢日志

默认是关闭的
作用:记录消耗时间比较长的SQL语句,为数据库性能提升提供了线索

存放在数据目录下,名字是主机名 + slow.log
#示例:慢日志默认是关闭的
root@(none) mysql>show variables like "%slow_query%";
| Variable_name       | Value                     |
| slow_query_log      | OFF                       |
| slow_query_log_file | /data/mysql/cPen-slow.log |
#示例:SQL定义的慢查询时间为 10毫秒
root@(none) mysql>show variables like "long_query_time";
| Variable_name   | Value     |
| long_query_time | 10.000000 |

#注:如果一条SQL的执行时间超过10毫秒,就算一条慢SQL,会产生慢日志
#示例:配置慢日志
[root@cPen ~]# vim /etc/my.cnf
[mysqld]
#slow query log
slow_query_log = 1
long_query_time = 0.001
slow_query_log_file = /data/mysql/cPen-slow.log

[root@cPen ~]# service  mysqld restart
[root@cPen ~]# tail -f /data/mysql/cPen-slow.log 
……
最近数据库压力 (负载特别高),客户反映网站或者应用使用特别慢,领导要求你查明原因?
	1 .SQL语句需要优化,在数据库里启用慢日志,找出执行时间比较长的SQL
	2 .业务量太大了,硬件已经达到极限了,top、glances、dstat

通用查询日志

优点
	会记录所有的SQL操作 --> 审计
缺点
	消耗大量的磁盘空间
	消耗cpu、内存、磁盘资源
#示例:查看通用查询日志功能是否开启
root@TENNIS mysql>show variables like 'general_log%';
| Variable_name    | Value                |
| general_log      | ON                   |
| general_log_file | /data/mysql/cPen.log |
#注:通用查询日志默认不开启
#示例:开启通用查询日志 --> 临时开启
root@TENNIS mysql>set global general_log = 1;					#注:临时开启
#注:1是开启,0是关闭
root@TENNIS mysql>show variables like 'general_log';
| Variable_name | Value |
| general_log   | ON    |
#示例:开启通用查询日志 --> 配置文件里设置
[root@cPen ~]# vim /etc/my.cnf
[mysqld]
#general log
general_log
general_log_file=/data/mysql/cPen.log

[root@cPen ~]# tail -f /data/mysql/cPen.log 
……

二进制日志

二进制日志	binary log

二进制日志文件里存放的是二进制数据,不能使用tail、head、cat去查看
默认不开启

默认一个二进制文件的大小是1G
	root@(none) mysql>show variables like 'max_binlog_size';
	| max_binlog_size | 1073741824 |
作用
	记录了什么?
		DML语句、DDL、DCL等
		修改了数据的操作		#注:select语句不会产生二进制日志
	可以用来恢复数据
	主从复制					#注:主 master    从 slave
存放的位置
	数据目录下
		主机名-bin.00000*
		cPen-bin.000001
	以二进制的形式存放的日志,里面不是文本的格式,使用cat,vim不能查看里面的内容
一个二进制日志文件是否记录了整个mysql进程里所有的库的操作?
	答:是的,对所有库进行的操作都会记录到一个二进制文件里

如果需要记录到不同的日志文件里,可以采用多实例

mysql实例:正在运行的一个mysql进程,这个进程里有哪些库可以操作,二进制日志就记录哪些库的操作

多实例:
	多启动几个mysqld的进程,一个mysqld的进程对应一个库
	隔离应用,避免一个库使用特别频繁,影响其他的库
	多实例任然受到整个机器整体系统资源的限制
	经典的例子:一款游戏对应一个实例

多实例的替代方案:使用云服务器:一款游戏使用一台云服务器
#示例:查看二进制日志是否开启
root@(none) mysql>show variables like 'log_bin';
| Variable_name | Value |
| log_bin       | OFF   |
#示例:开启二进制日志
[root@cPen ~]# vim /etc/my.cnf
[mysqld]
#binary log
log_bin
server_id = 1						#注:为了后面的主从复制,主server_id为1

[root@cPen ~]# service mysqld restart

root@(none) mysql>show variables like 'log_bin%';
| Variable_name                   | Value                      |
| log_bin                         | ON                         |
| log_bin_basename                | /data/mysql/cPen-bin       |
| log_bin_index                   | /data/mysql/cPen-bin.index |	

#注:/data/mysql/cPen-bin.index	记录已经产生了多少个二进制文件
cPen-bin.index
	二进制日志文件的索引
	记录一共有多少个二进制日志文件
产生多个二进制文件 方法
	1 .刷新服务
	2 .flush logs

#示例:刷新服务,会产生多个二进制文件
[root@cPen ~]# service mysqld restart
[root@cPen ~]# ls /data/mysql/ |grep cPen-bin*
cPen-bin.000001
cPen-bin.000002
cPen-bin.index
[root@cPen ~]# cat /data/mysql/cPen-bin.index 		#注:目前有2个二进制文件
./cPen-bin.000001
./cPen-bin.000002
#示例:flush logs 也会产生多个二进制文件
root@(none) mysql>flush logs;
#示例:reset master 删除所有的二进制日志
root@(none) mysql>reset master;
#示例:mysqlbinlog 查看二进制日志文件的工具
	-vv	显示信息更多,详细参数
[root@cPen ~]# cd /data/mysql/
[root@cPen mysql]# ls |grep cPen-bin.000001
cPen-bin.000001
[root@cPen mysql]# mysqlbinlog /data/mysql/cPen-bin.000001 
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
……略
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
格式解释:https://www.cnblogs.com/kevingrace/p/6065088.html
#示例:查看当前正在使用的二进制日志文件
root@(none) mysql>show master status;
| File            | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
| cPen-bin.000004 |      154 |              |                  |                   |

二进制日志格式

MySQL二进制日志 (binlog) 格式 (3个)
	Statement level
	Row level
	Mixed level
	
	https://www.cnblogs.com/martinzhang/p/3454358.html
	https://www.cnblogs.com/kevingrace/p/6065088.html	有大量的操作
	https://www.cnblogs.com/51yuki/p/mysql15.html
root@(none) mysql>show variables like 'binlog_format';
| Variable_name | Value |
| binlog_format | ROW   |					#注:默认行模式
A:Statement level
	说明:基于语句的,记录操作的SQL语句
	记录用户输入的SQL语句    mariadb-5.5.64
B:Row level
	说明:记录操作的每一行数据
	记录操作的每一行数据 --> 表里的哪些行的数据发生了变化    默认

Row level可以保证 数据一致性、更少的锁,特殊函数照样支持;而Statement level 无法保证 如now()函数,与时间相关

C:Mixed level
	说明:混合使用Row和Statement格式
问:Row比Statement好在哪里?
	答:Row格式 特殊函数照样支持,保证数据一致性,如now()函数 获得时间

数据恢复

二进制日志里会记录什么时间发生了什么事情
恢复数据的时候:
	1 .根据时间来恢复 time 时间点
	2 .根据位置来恢复 Position

备份和还原

备份和还原
	备份			backup
	恢复 (还原)	recovery
物理和逻辑的备份
	物理:备份数据库的文件或者磁盘 --> 在Linux系统里的文件系统上
		(例如:cp,scp,tar,rsync)
	逻辑:备份数据库里的表的结构和执行的语句 (insert、create) --> 进入到MySQL内部
		(例如:mysqldump)
MySQL备份工具的使用
	mysqldump mydumper xtrabackup使用(mysql的迁移与升级)
MySQL的数据目录在哪里?
	/var/lib/mysql	yum安装
	/data/mysql		编译安装 自定义目录
每个数据库对应一个目录,里面存放表的数据
	.frm		存放表结构的文件,表里的字段和字段的类型等信息
	.ibd		存放数据和索引的文件
[root@cPen ~]# cd /data/mysql/nongda/
[root@cPen nongda]# ls
db.opt  student.frm  student.ibd
备份方法
	全备		full backup
	增量备份	incremental
	差异备份


异地备份
https://www.cnblogs.com/yanjieli/articles/10722087.html

mysqldump
	mysqldump -h 192.168.0.218  -P 33060 -ubooksql -p'123456' --databases TENNIS  >tennis.sql
	mysqldump -h 192.168.0.83 -uyangst -p'yang123#'  sc123 >feng.sql

rsync --> 支持增量备份
scp --> 采用的是全备
配置ssh免密码登录
云存储 --> 百度、阿里、腾讯、七牛、ucloud、亚马逊

使用第3方工具备份和恢复

使用第3方工具备份和恢复
	1 .SQLyog --> .sql的文本文件
	2 .csv文件:就是以逗号作为分割的文件
	3 .Excel xml
	4 .Xml
	5 .Html
使用SQLyog备份和还原 --> 热备

#注:备份
SQLyog --> 选择test01库 --> 备份/导出 --> 备份数据库,转储到SQL… --> export to 导出到桌面 test01.sql --> 导出

root@(none) mysql>drop database test;				#注:删库
#注:还原
SQLyog --> booksql@192.168.31.179 右键 执行SQL脚本 --> 文件执行:桌面 test.sql --> 执行

mysqldump

mysqldump 备份 (全备,热操作)

备份数据库里的表
shell> mysqldump --all-databases > dump.sql					#注:备份所有的库
shell> mysqldump --databases db1 db2 db3 > dump.sql			#注:备份多个指定的库

root@(none) mysql>grant all on *.* to 'yangst'@'%' identified by 'yang123#';

[root@cPen ~]# mkdir /backup
[root@cPen ~]# cd /backup/
#注:备份所有库
[root@cPen backup]# mysqldump -uyangst -p'yang123#' --all-databases >/backup/all.sql
#注:备份单个库
[root@cPen backup]# mysqldump -uyangst -p'yang123#' sanchuang >/backup/sanchuang.sql
#注:备份单个表
[root@cPen backup]# mysqldump -uyangst -p'yang123#' sanchuang stu1 >/backup/sanchuang_stu1.sql
[root@cPen backup]# ls |grep .*sql 
all.sql
sanchuang.sql
sanchuang_stu1.sql

root@(none) mysql>drop database sanchuang;					#注:删库
root@(none) mysql>create database sanchuang;				#注:建库
#注:恢复/写入
[root@cPen backup]# mysql -uyangst -p'yang123#' sanchuang < /backup/sanchuang.sql 

根据二进制日志恢复

备份方案:
	每天的早上16:50点做全备,刚好到了下午17点10分的时候,数据库被删除了,如何将数据恢复到17点10分的状态?

https://dev.mysql.com/doc/refman/5.7/en/point-in-time-recovery-positions.html

shell> mysqlbinlog --start-datetime="2020-05-27 12:59:00" --stop-datetime="2020-05-27 13:06:00" \\ --verbose /var/lib/mysql/bin.123456 | grep -C 12 "DROP TABLE"

shell> mysqlbinlog --start-position=1006 --stop-position=1868 /var/lib/mysql/bin.123456 \\ | mysql -u root -p
#示例:根据二进制日志 恢复
	恢复时,先做全备恢复,再根据二进制日志 时间点恢复
	先恢复全备 + 二进制日志恢复 (增量备份)

----------------------------------------------------------------------
root@(none) mysql>CREATE DATABASE sc;
root@(none) mysql>use sc;
root@sc mysql>create table student(id int primary key,name varchar(10),sex char(1));
root@sc mysql>insert into student(id,name,sex) values(1,'cali','M'),(2,'rose','F');

----------------------------------------------------------------------
#注:开启二进制日志
[root@cPen backup]# vim /etc/my.cnf
[mysqld]
log_bin

----------------------------------------------------------------------
#注:备份sc库 (全备)
[root@cPen backup]# mysqldump -uyangst -p'yang123#' sc >/backup/sc.sql

----------------------------------------------------------------------
#注:产生新的二进制日志
root@sc mysql>flush logs;

root@sc mysql>show master status;
| File            | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
| cPen-bin.000004 |      154 |              |                  |                   |

----------------------------------------------------------------------
root@sc mysql>insert into student(id,name,sex) values(3,'tom','M'),(4,'jay','F');
root@sc mysql>insert into student(id,name,sex) values(5,'jason','M'),(6,'jack','F');

root@sc mysql>delete from student;			#注:删表

----------------------------------------------------------------------
#注:根据二进制日志,基于时间点恢复

root@sc mysql>show master status;
| File            | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
| cPen-bin.000004 |     1013 |              |                  |                   |

----------------------------------------------------------------------
#注:恢复全备
[root@cPen backup]# pwd
/backup
[root@cPen backup]# mysql -uyangst -p'yang123#' sc < /backup/sc.sql 

----------------------------------------------------------------------
#注:查看二进制日志
[root@cPen backup]# cd /data/mysql/
[root@cPen mysql]# mysqlbinlog -vv cPen-bin.000004 
……

#210326 19:45:58		--> start	开始的时间点
#210326 19:47:26		--> end		结束的时间点

===========================================
根据时间点来恢复
	根据二进制日志增备
mysqlbinlog --start-datetime="2021-03-26 19:45:58" --stop-datetime="2021-03-26 19:47:26" /data/mysql/cPen-bin.000004 >/backup/20min.sql

mysqlbinlog --start-datetime="2021-03-26 19:45:58" --stop-datetime="2021-03-26 19:47:26" /data/mysql/cPen-bin.000004 |mysql -uyangst -p'yang123#'

shell> mysqlbinlog --start-datetime="2021-03-26 19:45:58" --stop-datetime="2021-03-26 19:47:26" /data/mysql/cPen-bin.000004 |mysql -uyangst -p'yang123#'

root@sc mysql>select * from student;
+----+-------+------+
| id | name  | sex  |
+----+-------+------+
|  1 | cali  | M    |
……
|  6 | jack  | F    |
+----+-------+------+
6 rows in set (0.00 sec)

===========================================
根据位置号来恢复
	mysqlbinlog --start-position=291 --stop-position=697 /data/mysql/sc-mysql-bin.000005 |mysql -uroot -p'Sanchuang123#'
难点是找到起始点和结束点
	https://dev.mysql.com/doc/refman/5.7/en/point-in-time-recovery-positions.html
	[root@zabbix-4-centos7 mysql]# mysqlbinlog -vv zabbix-4-centos7-bin.000003|grep -i -n -A 150  "create table student"
	配合grep语句,当时最后做的删除操作
	经验:COMMIT语句后的时间点

mysqldump可以异地备份

[root@cPen-bak ~]# mysqldump -h 192.168.31.179 -uyangst -p'yang123#' sc123 >/backup/feng.sql
[root@cPen-bak ~]# ls /backup |grep feng.sql
feng.sql
练习:
	0 .刷新下二进制日志,flush logs 产生一个新的二进制日志文件
	1 .自己创建一个库sc,然后去里面新建一个表student(id int primary key,name varchar(10),sex char(1))
	2 .往表里插入数据2~3条数据
	3 .对sc这个库做全备				shell> mysqldump -uyangst -p'yang123#' sc123 >/backup/sc123.sql
	4 .再次往student表里插入一些数据
	5 .执行删除操作,删除sc库student表
	6 .去恢复sc库student表,恢复到删除库之前的数据
	使用全备 + 二进制日志基于时间的恢复方式
		shell> mysql -uyangst -p'yang123#' sc123 </backup/sc123.sql					#注:使用全备
		shell> mysqlbinlog -vv cPen-bin.000004|grep -i -n -A 150 "create database"	#注:找时间点
	#注:根据时间点来恢复
		shell> mysqlbinlog --start-datetime="2021-03-26 19:45:58" --stop-datetime="2021-03-26 19:47:26" /data/mysql/cPen-bin.000004 |mysql -uyangst -p'yang123#'

	#注:根据位置号来恢复
		shell> mysqlbinlog --start-position=154 --stop-position=726 /data/mysql/cPen-bin.000004 |mysql -uyangst -p'yang123#'
操作mysql

	1 .-e选项
	[root@cPen ~]# mysql -uyangst -p'yang123#' -e 'show databases';
	[root@cPen ~]# mysql -uyangst -p'yang123#' -e "insert into sc123.student(id,name,sex) values(11,'yyq','M')";

	2 .here document
	[root@cPen ~]# mysql -uyangst -p'yang123#' <<EOF
	> insert into sc123.student(id,name,sex) values(12,'zhangh','M')
	> EOF
编写脚本:
	1 .每天晚上3:30开始备份sc123这个库
	2 .备份文件存放到/backup目录下,要求备份的文件名里包含当天的日期(精确到天)
	3 .保留最近15天的备份文件
	4 .本地备份完成后,将备份文件上传到另外一台linux服务器的/backup_mysql目录下
		scp + 免密通道
-----------------------------------------------------------------------------------
#注:配置免密通道
[root@cPen ~]# ssh-keygen -t ecdsa
[root@cPen ~]# ssh-copy-id -i /root/.ssh/id_ecdsa.pub root@192.168.31.162

-----------------------------------------------------------------------------------
#注:编写脚本
[root@cPen-bak ~]# mkdir /backup

[root@cPen ~]# vim backup_db.sh
#!/bin/bash
ctime=$(date +%Y%m%d)
mkdir -p /backup

#备份sc123库
/usr/local/mysql/bin/mysqldump -uyangst -p'yang123#' sc123 >/backup/sc123_$ctime.sql

#上传备份文件到远程的服务器
scp /backup/sc123_$ctime.sql root@192.168.31.162:/backup

#只是保留最近15天的数据,本机上保留最近15天
find  /backup  -mtime +15 -type f -name "sc123*.sql" -exec rm -rf  \\;

#日志功能
now_time=$(date +%Y%m%d%H%M%S)
echo "$now_time sc123_$ctime.sql success " >>/var/log/backup_db.log

[root@cPen ~]# bash backup_db.sh 

[root@cPen-bak ~]# cd /backup
[root@cPen-bak backup]# ls|grep sc123_20210326.sql 
sc123_20210326.sql

-----------------------------------------------------------------------------------
#注:计划任务
[root@cPen ~]# crontab -e
30 3 * * * bash /root/backup_db.sh
[root@cPen ~]# crontab -l
30 3 * * * bash /root/backup_db.sh

搭建ftp服务器

搭建ftp服务器
	--> 进行异地备份

vsftpd 是服务器端的软件,提供ftp服务的
[root@cPen-bak ~]# yum install vsftpd -y
[root@cPen-bak ~]# service vsftpd restart
[root@cPen-bak ~]# lsof -i:21
……
[root@cPen-bak ~]# service firewalld stop
[root@cPen-bak ~]# vim /etc/vsftpd/vsftpd.conf 
# Allow anonymous FTP? (Beware - allowed by default if you comment this out).
anonymous_enable=YES							#注:允许匿名用户登陆 --> ftp,默认禁用
[root@cPen-bak ~]# service vsftpd restart

[root@cPen-bak ~]# useradd wanggh				#注:新建本地用户
[root@cPen-bak ~]# echo 123|passwd wanggh --stdin

ftp和lftp是登陆ftp服务器的客户端命令
[root@cPen ~]# yum install ftp lftp -y
#注:匿名用户登陆
[root@cPen ~]# lftp 192.168.31.162
lftp 192.168.31.162:~> ls
drwxr-xr-x    2 0        0               6 Apr 27  2020 pub

#注:本地用户登陆
[root@cPen ~]# ftp
ftp> open 192.168.31.162
Name (192.168.31.162:root): wanggh
Password:
ftp> cd /backup/						#注:远程切换
ftp> pwd								#注:远程所在目录
257 "/backup" is the current directory
ftp以上是关于10_MySQL笔记-日志-备份和还原的主要内容,如果未能解决你的问题,请参考以下文章

xtrabackup备份和还原

MySQL中基于mysqldump和二进制日志log-bin二进制日志进行逻辑备份以及基于时间点的还原

MySQL数据库的备份还原以及mysqldump的使用

mysql备份与还原

MySQL备份与还原

MySQL的备份还原(mysqldump)