MySQL数据库备份和恢复

database

目录

  • MySQL数据库备份" title="数据库备份">数据库备份和恢复

    • 备份恢复概述

      • 为什么要备份
      • 备份注意要点
      • 还原要点
      • 备份类型:
      • 备份时需要考虑的因素
      • 备份什么
      • 备份工具
      • 冷备份 cp tar
      • mysqldump备份工具
      • 模拟数据库崩溃,最大限度还原数据
      • mysqldump的分库备份
      • mysqldump的MyISAM存储引擎相关的备份选项:
      • mysqldump的InnoDB存储引擎相关的备份选项:
      • 生产环境实战备份策略
      • 将误删除了的某个表进行还原

mysql数据库备份和恢复">
MySQL数据库备份和恢复

备份恢复概述

为什么要备份

灾难恢复:硬件故障、软件故障、自然灾害、黑客攻击、误操作测试等数据丢失场景

备份注意要点

能容忍最多丢失多少数据

恢复数据需要在多长时间内完成

需要恢复哪些数据

还原要点

做还原测试,用于测试备份的可用性

还原演练

备份类型:

* 完全备份,部分备份

完全备份:整个数据集

部分备份:只备份数据子集,如部分库或表

* 完全备份、增量备份、差异备份

增量备份:仅备份最近一次完全备份或增量备份(如果存在增量)以来变化的数据,备份较快,还原复杂

差异备份:仅备份最近一次完全备份以来变化的数据,备份较慢,还原简单

* 注意:二进制日志文件不应该与数据文件放在同一磁盘

* 冷、温、热备份

冷备:读、写操作均不可进行

温备:读操作可执行;但写操作不可执行

热备:读、写操作均可执行

MyISAM:温备,不支持热备

InnoDB:都支持

* 物理和逻辑备份

物理备份:直接复制数据文件进行备份,与存储引擎有关,占用较多的空间,速度快

逻辑备份:从数据库中“导出”数据另存而进行的备份,与存储引擎无关,占用空间少,速度慢,可能丢失精度

备份时需要考虑的因素

温备的持锁多久

备份产生的负载

备份过程的时长

恢复过程的时长

备份什么

数据

二进制日志、InnoDB的事务日志

程序代码(存储过程、函数、触发器、事件调度器)

服务器的配置文件

备份工具

cp, tar等复制归档工具:物理备份工具,适用所有存储引擎;只支持冷备;完全和部分备份

LVM的快照:先加锁,做快照后解锁,几乎热备;借助文件系统工具进行备份

mysqldump:逻辑备份工具,适用所有存储引擎,温备;支持完全或部分备份;对InnoDB存储引擎支持热备,结合binlog的增量备份

xtrabackup:由Percona提供支持对InnoDB做热备(物理备份)的工具,支持完全备份、增量备份

MariaDB Backup: 从MariaDB 10.1.26开始集成,基于Percona XtraBackup 2.3.8实现

mysqlbackup:热备份, MySQL Enterprise Edition组件

mysqlhotcopy:PERL 语言实现,几乎冷备,仅适用于MyISAM存储引擎,使用LOCK TABLES、

FLUSH TABLES和cp或scp来快速备份数据库

冷备份 cp tar

  1. 确定数据库是否关闭,没关闭,关闭掉。(适合于可以停止访问的公司类型)

[root@centos7 ~]#ss -ntl    # 确定3306端口关闭

State Recv-Q Send-Q Local Address:Port Peer Address:Port

LISTEN 0 128 *:111 *:*

LISTEN 0 128 *:6000 *:*

LISTEN 0 5 192.168.122.1:53 *:*

LISTEN 0 128 *:22 *:*

LISTEN 0 128 127.0.0.1:631 *:*

LISTEN 0 100 127.0.0.1:25 *:*

LISTEN 0 128 127.0.0.1:6010 *:*

LISTEN 0 128 127.0.0.1:6011 *:*

LISTEN 0 128 127.0.0.1:6012 *:*

LISTEN 0 128 :::111 :::*

LISTEN 0 128 :::6000 :::*

LISTEN 0 128 :::22 :::*

LISTEN 0 128 ::1:631 :::*

LISTEN 0 100 ::1:25 :::*

LISTEN 0 128 ::1:6010 :::*

LISTEN 0 128 ::1:6011 :::*

LISTEN 0 128 ::1:6012 :::*

# 没关闭使用这条命令关闭

[root@centos7 ~]#systemctl stop mariadb

MariaDB [(none)]> show databases; # 备份前建立一个数据库或表用以测试是否可以还原成功

+--------------------+

| Database |

+--------------------+

| db1 |

| information_schema |

| mysql |

| performance_schema |

+--------------------+

4 rows in set (0.00 sec)

  1. 打包并压缩mysql目录

[root@centos7 data]#tar -zcvf mysql-$(date +%Y%m%d-%H%M).tar.gz /data/mysql/*

[root@centos7 data]#ll # 打包成带时间格式

total 1324

drwxr-xr-x 4 mysql root 336 Nov 29 20:04 mysql

-rw-r--r-- 1 root root 1355106 Nov 29 20:10 mysql-20191130-1144.tar.gz

  1. 发送到另一台服务器(最好服务器上的数据库版本和以前的相同)

[root@centos7 data]#scp mysql-20191130-1144.tar.gz 192.168.39.57:/data/

The authenticity of host '192.168.39.57 (192.168.39.57)' can't be established.

ECDSA key fingerprint is SHA256:vYJfaHhadE2ci7V5WRkZJ6iDUkQFzoZPmny56D9qKfI.

ECDSA key fingerprint is MD5:22:72:17:9a:a8:93:1a:02:d8:09:17:f4:85:fe:b3:f5.

Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added '192.168.39.57' (ECDSA) to the list of known hosts.

root@192.168.39.57's password:

mysql-20191130-1144.tar.gz 100% 1323KB 100.2MB/s 00:00

[root@centos7 data]#ls # 查看一下

mysql-20191130-1144.tar.gz

[root@centos7 ~]# mkdir /backup

[root@centos7 ~]# tar zxvf /data/mysql-20191130-1227.tar.gz -C /backup

[root@centos7 backup]# tree # 查看一下文件是否拷贝过来了

.

└── data

└── mysql

├── aria_log.00000001

├── aria_log_control

├── db1

│ └── db.opt

├── ib_buffer_pool

├── ibdata1

├── ib_logfile0

├── ib_logfile1

├── multi-master.info

├── mysql

│ ├── columns_priv.frm

│ ├── columns_priv.MYD

│ ├── columns_priv.MYI

│ ├── column_stats.frm

│ ├── column_stats.MYD

│ ├── column_stats.MYI

│ ├── db.frm

│ ├── db.MYD

│ ├── db.MYI

│ ├── db.opt

│ ├── event.frm

│ ├── event.MYD

[root@centos7 mysql]# ll # 查看一下MySQL的目录

total 110668

-rw-rw---- 1 987 981 16384 Nov 30 11:44 aria_log.00000001

-rw-rw---- 1 987 981 52 Nov 30 11:44 aria_log_control

drwx------ 2 987 981 20 Nov 30 11:43 db1

-rw-rw---- 1 987 981 942 Nov 30 11:44 ib_buffer_pool

-rw-rw---- 1 987 981 12582912 Nov 30 11:44 ibdata1

-rw-rw---- 1 987 981 50331648 Nov 30 11:44 ib_logfile0

-rw-rw---- 1 987 981 50331648 Nov 19 16:41 ib_logfile1

-rw-rw---- 1 987 981 0 Nov 19 16:57 multi-master.info

drwx------ 2 987 981 4096 Nov 19 16:41 mysql

-rw-rw---- 1 987 981 29310 Nov 19 16:41 mysql-bin.000001

-rw-rw---- 1 987 981 1685 Nov 30 11:35 mysql-bin.000002

-rw-rw---- 1 987 981 492 Nov 30 11:44 mysql-bin.000003

-rw-rw---- 1 987 981 57 Nov 30 11:41 mysql-bin.index

-rw-rw---- 1 987 981 7 Nov 30 11:44 mysql-bin.state

drwx------ 2 987 981 20 Nov 19 16:41 performance_schema

[root@centos7 mysql]# mv * /var/lib/mysql/ # 移动到原有目录下

[root@centos7 mysql]# systemctl start mariadb.service # 启动服务

[root@centos7 mysql]# mysql # 登录数据库

MariaDB [(none)]> show databases; # 之前创建的数据库还在代表还原成功

+--------------------+

| Database |

+--------------------+

| information_schema |

| db1 |

| mysql |

| performance_schema |

| test |

+--------------------+

5 rows in set (0.00 sec)

mysqldump备份工具

  1. 逻辑备份工具:

    mysqldump, mydumper, phpMyAdmin

Schema和数据存储在一起、巨大的SQL语句、单个巨大的备份文件

mysqldump:是MySQL的客户端命令,通过mysql协议连接至mysql服务器进行备份

  1. 命令格式:

mysqldump [OPTIONS] database [tables]

mysqldump [OPTIONS] –B DB1 [DB2 DB3...]

mysqldump [OPTIONS] –A [OPTIONS]

  1. mysqldump参考:

    https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html

  2. mysqldump 常见通用选项:

-A, --all-databases #

-B, --databases db_name… #指定备份的数据库,包括create database语句

-E, --events:#备份相关的所有event scheduler

-R, --routines:#备份所有存储过程和自定义函数

--triggers:#备份表相关触发器,默认启用,用--skip-triggers,不备份触发器

--default-character-set=utf8 #指定字符集

--master-data[=#]: #此选项须启用二进制日志

#1:所备份的数据之前加一条记录为CHANGE MASTER TO语句,非注释,不指定#,默认为1

#2:记录为注释的CHANGE MASTER TO语句

#此选项会自动关闭--lock-tables功能,自动打开-x | --lock-all-tables功能(除非开启-- single-transaction)

-F, --flush-logs #备份前滚动日志,锁定表完成后,执行flush logs命令,生成新的二进制日志文 件,配合-A 或 -B

选项时,会导致刷新多次数据库。建议在同一时刻执行转储和日志刷新,可通过和-- single-transaction或-x,--master-data 一起使用实现,此时只刷新一次二进制日志

--compact #去掉注释,适合调试,生产不使用

-d, --no-data #只备份表结构

-t, --no-create-info #只备份数据,不备份create table

-n,--no-create-db #不备份create database,可被-A或-B覆盖

--flush-privileges #备份mysql或相关时需要使用

-f, --force #忽略SQL错误,继续执行

--hex-blob #使用十六进制符号转储二进制列,当有包括BINARY, VARBINARY,BLOB,BIT的数 据类型的列时使用,避免乱码

-q, --quick #不缓存查询,直接输出,加快备份速度

  1. mysqldump命令用法

[root@centos7 ~]# mysqldump --help  # 有三种格式

mysqldump Ver 10.14 Distrib 5.5.60-MariaDB, for Linux (x86_64)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Dumping structure and contents of MySQL databases and tables.

Usage: mysqldump [OPTIONS] database [tables]

OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]

OR mysqldump [OPTIONS] --all-databases [OPTIONS]

  • 第一种用法(对某一个数据库或者某个数据库的特定表做打印,之后在导入到文件里,只是打印到屏幕里所以要导出)

[root@centos7 ~]# mysqldump -uroo hellodb students  # 备份hellodb数据库的students表   (要指定用户和密码,没设置密码不用指定)不加表名就备份数据库。

-- MySQL dump 10.14 Distrib 5.5.60-MariaDB, for Linux (x86_64)

--

-- Host: localhost Database: hellodb

-- ------------------------------------------------------

-- Server version 5.5.60-MariaDB

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;

/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;

/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;

/*!40101 SET NAMES utf8 */;

/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;

/*!40103 SET TIME_ZONE='+00:00' */;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;

/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;

/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;

/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

mysqldump: Got error: 1044: "Access denied for user ''@'localhost' to database 'hellodb'" when selecting the database

  • 删除库做实验

[root@centos7 ~]# mysqldump hellodb > /data/hellodb.sql  # 先导出数据库

MariaDB [(none)]> drop database hellodb; # 删除库

Query OK, 7 rows affected (0.00 sec)

MariaDB [(none)]> show databases; # 查看已经删除掉了

+--------------------+

| Database |

+--------------------+

| information_schema |

| db1 |

| mysql |

| performance_schema |

| test |

+--------------------+

5 rows in set (0.00 sec)

MariaDB [(none)]> create database hello; # 创建一个数据库名字不一样都可以

Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> use hello # 进入创建的数据库

Database changed

MariaDB [hello]> source /data/hellodb.sql # 把sql脚本读入到这个库里

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

MariaDB [hello]> show tables; # 查看表,表都在。

+-----------------+

| Tables_in_hello |

+-----------------+

| classes |

| coc |

| courses |

| scores |

| students |

| teachers |

| toc |

+-----------------+

7 rows in set (0.00 sec)

这种方法可以恢复,但是数据库的格式和字符集都是默认的,这种方法不建议用。

  • 第二种方法(推荐使用方法)

    -B 挑选指定的数据库做备份

[root@centos7 ~]# mysqldump -B hellodb mysql > /data/hellodb_mysql.sql # 导出生成sql脚本,最好加上时间格式。

[root@centos7 ~]# vim /data/hellodb_mysql.sql # 查看一下这个文件

# 这个sql脚本里面有这一行是用来创建库和定义库的格式的,加上-B才会有这一行。

CREATE DATABASE /*!32312 IF NOT EXISTS*/ `hellodb` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `hellodb`;

MariaDB [(none)]> show create database hellodb; # 查看hellodb数据库的字符集和格式

+----------+------------------------------------------------------------------+

| Database | Create Database |

+----------+------------------------------------------------------------------+

| hellodb | CREATE DATABASE `hellodb` /*!40100 DEFAULT CHARACTER SET utf8 */ |

+----------+------------------------------------------------------------------+

1 row in set (0.00 sec)

  • 发送到远程主机做测试

[root@centos7 ~]# scp /data/hellodb_mysql.sql 192.168.39.27:/root

root@192.168.39.27's password:

hellodb_mysql.sql 100% 509KB 85.6MB/s 00:00

  • 导入sql脚本

MariaDB [(none)]> show databases;  # 远程主机的数据库

+--------------------+

| Database |

+--------------------+

| information_schema |

| db1 |

| mysql |

| performance_schema |

| test |

+--------------------+

5 rows in set (0.00 sec)

MariaDB [(none)]> source /root/hellodb_mysql.sql # 导入sql脚本

MariaDB [mysql]> show databases; # 查看数据库生成

+--------------------+

| Database |

+--------------------+

| information_schema |

| db1 |

| hellodb |

| mysql |

| performance_schema |

| test |

+--------------------+

6 rows in set (0.00 sec)

MariaDB [mysql]> show create database hellodb; # 查看hellodb字符集,是和原本一摸一样的。

+----------+------------------------------------------------------------------+

| Database | Create Database |

+----------+------------------------------------------------------------------+

| hellodb | CREATE DATABASE `hellodb` /*!40100 DEFAULT CHARACTER SET utf8 */ |

+----------+------------------------------------------------------------------+

1 row in set (0.00 sec)

  • 第三种方法 (所有的数据库做备份) (完全备份)

[root@centos7 ~]# mysqldump -A |gzip > /data/All.sql.gz # 备份连带压缩一起执行

[root@centos7 ~]# ll /data/

total 140

-rw-r--r-- 1 root root 140945 Nov 30 16:00 All.sql.gz

# 还原下面会做现在就解释一下。

模拟数据库崩溃,最大限度还原数据

[root@centos7 ~]# mysqldump -A --master-data=2 |gzip > /data/all_'date +%F'.sql.gz

mysqldump: Error: Binlogging on server not active

# 上面不成功是因为二进制日志没有启用

  • 启用二进制日志

# 事先创建好二进制日志存放的路径

[root@centos7 ~]# chown -R mysql:mysql /data/mysql/ # 创建完路径记得更改权限

[root@centos7 ~]# vim /etc/my.cnf # 修改配置文件

[mysqld]

log-bin=/data/mysql/bin_log # 指定二进制日志存放路径(最好和数据库是分开的) 最后的是指定日志的前缀。

[root@centos7 ~]# systemctl restart mariadb.service # 重启服务

  • 完全备份数据库

[root@centos7 ~]# mysqldump -A --master-data=2 |gzip > /data/all_`ate +%F`.sql.gz

[root@centos7 ~]# ll /data/

total 140

-rw-r--r-- 1 root root 141043 Nov 30 16:29 all_2019-11-30.sql.gz

  • 模拟添加一条记录,创建一个账号。

MariaDB [(none)]> use hellodb

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

Database changed

MariaDB [hellodb]> insert students (name,age,gender)value('a',20,'M');

Query OK, 1 row affected (0.00 sec)

MariaDB [hellodb]> select * from students;

+-------+---------------+-----+--------+---------+-----------+

| StuID | Name | Age | Gender | ClassID | TeacherID |

+-------+---------------+-----+--------+---------+-----------+

| 1 | Shi Zhongyu | 22 | M | 2 | 3 |

| 2 | Shi Potian | 22 | M | 1 | 7 |

| 3 | Xie Yanke | 53 | M | 2 | 16 |

| 4 | Ding Dian | 32 | M | 4 | 4 |

| 5 | Yu Yutong | 26 | M | 3 | 1 |

| 6 | Shi Qing | 46 | M | 5 | NULL |

| 7 | Xi Ren | 19 | F | 3 | NULL |

| 8 | Lin Daiyu | 17 | F | 7 | NULL |

| 9 | Ren Yingying | 20 | F | 6 | NULL |

| 10 | Yue Lingshan | 19 | F | 3 | NULL |

| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |

| 12 | Wen Qingqing | 19 | F | 1 | NULL |

| 13 | Tian Boguang | 33 | M | 2 | NULL |

| 14 | Lu Wushuang | 17 | F | 3 | NULL |

| 15 | Duan Yu | 19 | M | 4 | NULL |

| 16 | Xu Zhu | 21 | M | 1 | NULL |

| 17 | Lin Chong | 25 | M | 4 | NULL |

| 18 | Hua Rong | 23 | M | 7 | NULL |

| 19 | Xue Baochai | 18 | F | 6 | NULL |

| 20 | Diao Chan | 19 | F | 7 | NULL |

| 21 | Huang Yueying | 22 | F | 6 | NULL |

| 22 | Xiao Qiao | 20 | F | 1 | NULL |

| 23 | Ma Chao | 23 | M | 4 | NULL |

| 24 | Xu Xian | 27 | M | NULL | NULL |

| 25 | Sun Dasheng | 100 | M | NULL | NULL |

| 26 | a | 20 | M | NULL | NULL |

+-------+---------------+-----+--------+---------+-----------+

26 rows in set (0.00 sec)

MariaDB [hellodb]> grant all on hellodb.* to test@'192.168.39.%' identified by 'centos'; # 创建一个账号

Query OK, 0 rows affected (0.00 sec)

  • 假设数据库崩溃了(删之前确定二进制日志独立出来了)

[root@centos7 ~]# rm -rf /var/lib/mysql/* # 删除数据库

[root@centos7 ~]# mysql # 登录不上了

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

  • 查看数据库和二进制文件

[root@centos7 ~]# ll /var/lib/mysql/  # 数据库没有了

total 0

[root@centos7 ~]# ll /data/mysql/ # 二进制文件独立出来了

total 12

-rw-rw---- 1 mysql mysql 264 Nov 30 16:26 bin_log.000001

-rw-rw---- 1 mysql mysql 637 Nov 30 16:35 bin_log.000002

-rw-rw---- 1 mysql mysql 54 Nov 30 16:26 bin_log.index

  • 重新生成数据库

[root@centos7 ~]# systemctl restart mariadb.service  # 重启服务就可以

# 新版本在重新启用服务的时候不会重新启用数据库

[root@centos7 ~]# mysql_install_db --user=mysql # 使用这条命令在新版上面生成数据库

[root@centos7 ~]# mysql

Welcome to the MariaDB monitor. Commands end with ; or g.

Your MariaDB connection id is 2

Server version: 5.5.60-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

MariaDB [(none)]>

[root@centos7 ~]# ll /var/lib/mysql/ # 查看库是否生成

total 37852

-rw-rw---- 1 mysql mysql 16384 Nov 30 16:42 aria_log.00000001

-rw-rw---- 1 mysql mysql 52 Nov 30 16:42 aria_log_control

-rw-rw---- 1 mysql mysql 18874368 Nov 30 16:42 ibdata1

-rw-rw---- 1 mysql mysql 5242880 Nov 30 16:42 ib_logfile0

-rw-rw---- 1 mysql mysql 5242880 Nov 30 16:42 ib_logfile1

drwx------ 2 mysql mysql 4096 Nov 30 16:42 mysql

srwxrwxrwx 1 mysql mysql 0 Nov 30 16:42 mysql.sock

drwx------ 2 mysql mysql 4096 Nov 30 16:42 performance_schema

drwx------ 2 mysql mysql 6 Nov 30 16:42 test

  • 新的数据库里之前的哪些库和表是没有的

MariaDB [(none)]> show databases;

+--------------------+

| Database |

+--------------------+

| information_schema |

| mysql |

| performance_schema |

| test |

+--------------------+

4 rows in set (0.00 sec)

  • 解压缩完全备份包

[root@centos7 data]# ls

all_2019-11-30.sql.gz mysql

[root@centos7 data]# gzip -d all_2019-11-30.sql.gz

[root@centos7 data]# ls

all_2019-11-30.sql mysql

  • 临时停用二进制日志(不停用的话会有生成一份一模一样的二进制所以最好关闭)

MariaDB [(none)]> set sql_log_bin=0;

Query OK, 0 rows affected (0.00 sec)

  • 还原数据库的完全备份,当前会话使用。(但是在完全备份到数据库崩溃这段时间的数据这样是还原不了的)

MariaDB [(none)]> source /data/all_2019-11-30.sql

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

.......(省略)

MariaDB [test]> show databases; # 完全备份之前建立的库是在的

+--------------------+

| Database |

+--------------------+

| information_schema |

| db1 |

| hello |

| hellodb |

| mysql |

| performance_schema |

| test |

+--------------------+

7 rows in set (0.00 sec)

MariaDB [test]> use hellodb;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

Database changed

MariaDB [hellodb]> select * from students; # 但是在这个表上添加的记录没有了

+-------+---------------+-----+--------+---------+-----------+

| StuID | Name | Age | Gender | ClassID | TeacherID |

+-------+---------------+-----+--------+---------+-----------+

| 1 | Shi Zhongyu | 22 | M | 2 | 3 |

| 2 | Shi Potian | 22 | M | 1 | 7 |

| 3 | Xie Yanke | 53 | M | 2 | 16 |

| 4 | Ding Dian | 32 | M | 4 | 4 |

| 5 | Yu Yutong | 26 | M | 3 | 1 |

| 6 | Shi Qing | 46 | M | 5 | NULL |

| 7 | Xi Ren | 19 | F | 3 | NULL |

| 8 | Lin Daiyu | 17 | F | 7 | NULL |

| 9 | Ren Yingying | 20 | F | 6 | NULL |

| 10 | Yue Lingshan | 19 | F | 3 | NULL |

| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |

| 12 | Wen Qingqing | 19 | F | 1 | NULL |

| 13 | Tian Boguang | 33 | M | 2 | NULL |

| 14 | Lu Wushuang | 17 | F | 3 | NULL |

| 15 | Duan Yu | 19 | M | 4 | NULL |

| 16 | Xu Zhu | 21 | M | 1 | NULL |

| 17 | Lin Chong | 25 | M | 4 | NULL |

| 18 | Hua Rong | 23 | M | 7 | NULL |

| 19 | Xue Baochai | 18 | F | 6 | NULL |

| 20 | Diao Chan | 19 | F | 7 | NULL |

| 21 | Huang Yueying | 22 | F | 6 | NULL |

| 22 | Xiao Qiao | 20 | F | 1 | NULL |

| 23 | Ma Chao | 23 | M | 4 | NULL |

| 24 | Xu Xian | 27 | M | NULL | NULL |

| 25 | Sun Dasheng | 100 | M | NULL | NULL |

+-------+---------------+-----+--------+---------+-----------+

25 rows in set (0.00 sec)

  • 查看sql脚本来确定丢失的二进制数据位置

[root@centos7 data]# grep '^-- CHANGE MASTER TO' /data/all_2019-11-30.sql  # 查找以这个开头的行

-- CHANGE MASTER TO MASTER_LOG_FILE='bin_log.000002', MASTER_LOG_POS=245; # 最后的数字确定丢失起点位置

  • 以二进制日志恢复丢失数据

[root@centos7 mysql]# ll

total 1064

-rw-rw---- 1 mysql mysql 264 Nov 30 16:26 bin_log.000001

-rw-rw---- 1 mysql mysql 656 Nov 30 16:42 bin_log.000002 # 要这个文件245之后的

-rw-rw---- 1 mysql mysql 30373 Nov 30 16:42 bin_log.000003 # 和这个文件全部内容

-rw-rw---- 1 mysql mysql 1038814 Nov 30 16:42 bin_log.000004

-rw-rw---- 1 mysql mysql 245 Nov 30 16:42 bin_log.000005

-rw-rw---- 1 mysql mysql 135 Nov 30 16:42 bin_log.index

[root@centos7 mysql]# mysqlbinlog bin_log.000002 --start-position=245 > inc.sql

[root@centos7 mysql]# mysqlbinlog bin_log.000003 >> inc.sql

# 顺序不要错了

[root@centos7 mysql]# mysql

Welcome to the MariaDB monitor. Commands end with ; or g.

Your MariaDB connection id is 4

Server version: 5.5.60-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

MariaDB [(none)]> use hellodb;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

Database changed

MariaDB [hellodb]> source /data/mysql/inc.sql # 导入二进制脚本

MariaDB [hellodb]> select * from students;

+-------+---------------+-----+--------+---------+-----------+

| StuID | Name | Age | Gender | ClassID | TeacherID |

+-------+---------------+-----+--------+---------+-----------+

| 1 | Shi Zhongyu | 22 | M | 2 | 3 |

| 2 | Shi Potian | 22 | M | 1 | 7 |

| 3 | Xie Yanke | 53 | M | 2 | 16 |

| 4 | Ding Dian | 32 | M | 4 | 4 |

| 5 | Yu Yutong | 26 | M | 3 | 1 |

| 6 | Shi Qing | 46 | M | 5 | NULL |

| 7 | Xi Ren | 19 | F | 3 | NULL |

| 8 | Lin Daiyu | 17 | F | 7 | NULL |

| 9 | Ren Yingying | 20 | F | 6 | NULL |

| 10 | Yue Lingshan | 19 | F | 3 | NULL |

| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |

| 12 | Wen Qingqing | 19 | F | 1 | NULL |

| 13 | Tian Boguang | 33 | M | 2 | NULL |

| 14 | Lu Wushuang | 17 | F | 3 | NULL |

| 15 | Duan Yu | 19 | M | 4 | NULL |

| 16 | Xu Zhu | 21 | M | 1 | NULL |

| 17 | Lin Chong | 25 | M | 4 | NULL |

| 18 | Hua Rong | 23 | M | 7 | NULL |

| 19 | Xue Baochai | 18 | F | 6 | NULL |

| 20 | Diao Chan | 19 | F | 7 | NULL |

| 21 | Huang Yueying | 22 | F | 6 | NULL |

| 22 | Xiao Qiao | 20 | F | 1 | NULL |

| 23 | Ma Chao | 23 | M | 4 | NULL |

| 24 | Xu Xian | 27 | M | NULL | NULL |

| 25 | Sun Dasheng | 100 | M | NULL | NULL |

| 26 | a | 20 | M | NULL | NULL | # 添加的a记录回来了

+-------+---------------+-----+--------+---------+-----------+

26 rows in set (0.00 sec)

MariaDB [hellodb]> select user,host,password from mysql.user;

+------+---------------------+-------------------------------------------+

| user | host | password |

+------+---------------------+-------------------------------------------+

| root | localhost | |

| root | centos7.localdomain | |

| root | 127.0.0.1 | |

| root | ::1 | |

| | localhost | |

| | centos7.localdomain | |

| test | 192.168.39.% | *128977E278358FF80A246B5046F51043A2B1FCED | # 添加的账户也还原回来了

+------+---------------------+-------------------------------------------+

7 rows in set (0.00 sec)

  • 最后在启用二进制日志

MariaDB [hellodb]> set sql_log_bin=1;

Query OK, 0 rows affected (0.00 sec)

还原的时候,数据库必须是不能访问的状态,数据库的二进制日志就是备份。

mysqldump的分库备份

  1. 先查看库名

MariaDB [(none)]> show databases;

+--------------------+

| Database |

+--------------------+

| information_schema |

| db1 |

| hello |

| hellodb |

| mysql |

| performance_schema |

| test |

+--------------------+

7 rows in set (0.00 sec)

  1. 挑出数据库备份(用grep)

[root@centos7 ~]# mysql -uroot -e 'show databases'|grep -Ev '^(Database|information_schema|performance_schema)$'

db1

hello

hellodb

mysql

test

  1. 使用while循环来备份

[root@centos7 ~]# mysql -uroot -e 'show databases'|grep -Ev '^(Database|information_schema|performance_schema)$'|while read db;do mysqldump -B $db|gzip > /data/$db.sql.gz;done

[root@centos7 ~]# ll /data/

total 156

-rw-r--r-- 1 root root 516 Nov 30 17:31 db1.sql.gz

-rw-r--r-- 1 root root 1898 Nov 30 17:31 hellodb.sql.gz

-rw-r--r-- 1 root root 1892 Nov 30 17:31 hello.sql.gz

-rw-r--r-- 1 root root 139603 Nov 30 17:31 mysql.sql.gz

-rw-r--r-- 1 root root 516 Nov 30 17:31 test.sql.gz

  1. 使用for循环做备份

[root@centos7 ~]# for db in `mysql -uroot -e 'show databases'|grep -Ev '^(Database|information_schema|performance_schema)$'`;do mysqldump -B $db|gzip > /data/$db.sql.gz;done

[root@centos7 ~]# ll -t /data/

total 156

-rw-r--r-- 1 root root 516 Nov 30 17:34 test.sql.gz

-rw-r--r-- 1 root root 139603 Nov 30 17:34 mysql.sql.gz

-rw-r--r-- 1 root root 1898 Nov 30 17:34 hellodb.sql.gz

-rw-r--r-- 1 root root 1892 Nov 30 17:34 hello.sql.gz

-rw-r--r-- 1 root root 516 Nov 30 17:34 db1.sql.gz

  1. 使用sed来备份数据

[root@centos7 ~]# mysql -uroot -e 'show databases'|grep -Ev '^(Database|information_schema|performance_schema)$' | sed -rn 's#(.*)#mysqldump -B 1 |gzip > /data/1.sql.gz#p'|bash

[root@centos7 ~]# ll -t /data/

total 156

-rw-r--r-- 1 root root 517 Nov 30 17:37 test.sql.gz

-rw-r--r-- 1 root root 139603 Nov 30 17:37 mysql.sql.gz

-rw-r--r-- 1 root root 1898 Nov 30 17:37 hellodb.sql.gz

-rw-r--r-- 1 root root 1892 Nov 30 17:37 hello.sql.gz

-rw-r--r-- 1 root root 516 Nov 30 17:37 db1.sql.gz

  1. 用sed替换grep分库备份

[root@centos7 ~]# mysql -uroot -e 'show databases'|sed -rn '/^(Database|information_schema|performance_schema)$/!s#(.*)#mysqldump -B 1 |gzip > /data/1.sql.gz#p' |bash

[root@centos7 ~]# ll -t /data/

total 156

-rw-r--r-- 1 root root 516 Nov 30 17:43 test.sql.gz

-rw-r--r-- 1 root root 139600 Nov 30 17:43 mysql.sql.gz

-rw-r--r-- 1 root root 1898 Nov 30 17:43 hellodb.sql.gz

-rw-r--r-- 1 root root 1892 Nov 30 17:43 hello.sql.gz

-rw-r--r-- 1 root root 516 Nov 30 17:43 db1.sql.gz

分库备份可以编写成脚本,配合计划任务使用。(最好备份的包加上时间格式要不容易覆盖掉)

mysqldump的MyISAM存储引擎相关的备份选项:

MyISAM不支持事务,只能支持温备;不支持热备,所以必须先锁定要备份的库,而后启动备份操作

-x,--lock-all-tables #加全局读锁,锁定所有库的所有表,同时加--single-transaction或--

lock-tables选项会关闭此选项功能

#注意:数据量大时,可能会导致长时间无法并发访问数据库

-l,--lock-tables #对于需要备份的每个数据库,在启动备份之前分别锁定其所有表,默认为on,--

skip-lock-tables选项可禁用,对备份MyISAM的多个库,可能会造成数据不一致

#注:以上选项对InnoDB表一样生效,实现温备,但不推荐使用

mysqldump的InnoDB存储引擎相关的备份选项:

InnoDB 存储引擎支持事务,可以利用事务的相应的隔离级别,实现热备,也可以实现温备但不建议用

--single-transaction

#此选项Innodb中推荐使用,不适用MyISAM,此选项会开始备份前,先执行START TRANSACTION指令开启

事务

#此选项通过在单个事务中转储所有表来创建一致的快照。 仅适用于存储在支持多版本控制的存储引擎中的表

(目前只有InnoDB可以); 转储不保证与其他存储引擎保持一致。 在进行单事务转储时,要确保有效的转储

文件(正确的表内容和二进制日志位置),没有其他连接应该使用以下语句:ALTER TABLE,DROP

TABLE,RENAME TABLE,TRUNCATE TABLE,此选项和--lock-tables(此选项隐含提交挂起的事务)选

项是相互排斥,备份大型表时,建议将--single-transaction选项和--quick结合一起使用

生产环境实战备份策略

  1. InnoDB建议备份策略

mysqldump –uroot -p –A –F –E –R --single-transaction --master-data=1 --flushprivileges

--triggers --default-character-set=utf8 --hex-blob

>${BACKUP}/fullbak_${BACKUP_TIME}.sql

  1. MyISAM建议备份策略

mysqldump –uroot -p –A –F –E –R –x --master-data=1 --flush-privileges --

triggers --default-character-set=utf8 --hex-blob

>${BACKUP}/fullbak_${BACKUP_TIME}.sql

范例:完全备份和还原

#开启二进制日志

[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf

[mysqld]

log-bin

#备份

[root@centos8 ~]#mysqldump -uroot -p -A -F --single-transaction --master-data=2

|gzip > /backup/all-`date +%F`.sql.gz

#还原

[root@centos8 backup]#dnf install mariadb-server

[root@centos8 backup]#gzip -d all-2019-11-27.sql.gz

[root@centos8 ~]#mysql

MariaDB [(none)]> set sql_log_bin=off;

MariaDB [(none)]> source /backup/all-2019-11-27.sql

MariaDB [(none)]> set sql_log_bin=on;

范例:mysqldump 和二进制日志结合实现增量备份

[root@centos8 ~]#mysqldump -uroot -p -A -F --single-transaction --master-data=2

|gzip > /backup/all-`date +%F`.sql.gz

#观察备份文件中的二进制文件和位置,将之后的二进制日志进行复制备份

[root@centos8 ~]#cp /var/lib/mysql/mariadb-bin.000003 /backup

[root@centos8 ~]#mysqlbinlog --start-position=389 /backup/mariadb-bin.000003 >

/backup/inc.sql

将误删除了的某个表进行还原

  1. 先完全备份一份

[root@centos7 ~]# mysqldump -A -F --single-transaction --master-data=2 |gzip > /backup/allbackup_`date +%F_%T`.sql.gz

[root@centos7 ~]# ll /backup/

total 140

-rw-r--r-- 1 root root 141141 Nov 30 18:03 allbackup_2019-11-30_18:03:08.sql.gz

  1. 在完全备份之后最一些记录变化

MariaDB [db1]> create table test ( id int unsigned auto_increment primary key,name varchar(10) not null,mobile char(11) not null );  # 创建一张表

Query OK, 0 rows affected (0.00 sec)

MariaDB [db1]> show tables; # 查看库里的所有表

+---------------+

| Tables_in_db1 |

+---------------+

| test |

+---------------+

1 row in set (0.00 sec)

MariaDB [db1]> insert test (name) values('rose'); # 添加记录

Query OK, 1 row affected, 1 warning (0.00 sec)

MariaDB [db1]> insert test (name) values('jack'); # 添加记录

Query OK, 1 row affected, 1 warning (0.00 sec)

MariaDB [db1]> select * from test; # 查看添加的记录

+----+------+--------+

| id | name | mobile |

+----+------+--------+

| 1 | rose | |

| 2 | jack | |

+----+------+--------+

2 rows in set (0.01 sec)

  1. 误删除表

MariaDB [db1]> drop table test;

Query OK, 0 rows affected (0.01 sec)

MariaDB [db1]> show tables;

Empty set (0.00 sec)

  1. 解压缩

[root@centos7 ~]# cd /backup/

[root@centos7 backup]# ll

total 140

-rw-r--r-- 1 root root 141141 Nov 30 18:03 allbackup_2019-11-30_18:03:08.sql.gz

[root@centos7 backup]# gzip -d allbackup_2019-11-30_18:03:08.sql.gz

[root@centos7 backup]# ll

total 520

-rw-r--r-- 1 root root 528632 Nov 30 18:03 allbackup_2019-11-30_18:03:08.sql

  1. 找到上次完全备份的结束位置

[root@centos7 backup]# grep '-- CHANGE MASTER TO' /backup/allbackup_2019-11-30_18:03:08.sql 

-- CHANGE MASTER TO MASTER_LOG_FILE='bin_log.000006', MASTER_LOG_POS=245;

[root@centos7 backup]#

  1. 导出245之后的所有二进制日志(增量备份)

[root@centos7 backup]# mysqlbinlog --start-position=245 /data/mysql/bin_log.000006 > /backup/inc.sql

[root@centos7 backup]# ll /backup/

total 524

-rw-r--r-- 1 root root 528632 Nov 30 18:03 allbackup_2019-11-30_18:03:08.sql

-rw-r--r-- 1 root root 2791 Nov 30 18:20 inc.sql

  1. 查看执行过的drop命令的时间和位置

[root@centos7 backup]# mysqlbinlog --start-position=245 /data/mysql/bin_log.000006|grep -i drop

DROP TABLE `test` /* generated by server */

[root@centos7 backup]# mysqlbinlog --start-position=245 /data/mysql/bin_log.000006|grep -C3 -i drop

# at 856 # 这个位置

#191130 18:07:32 server id 1 end_log_pos 961 Query thread_id=35 exec_time=error_code=0

SET TIMESTAMP=1575108452/*!*/;

DROP TABLE `test` /* generated by server */

/*!*/;

DELIMITER ;

# End of log file

  1. 然后打开导出来的文件删掉或注释掉误操作

[root@centos7 backup]# vim /backup/inc.sql 

# at 856

#191130 18:07:32 server id 1 end_log_pos 961 Query thread_id=35 exec_time=0 error_code=0

SET TIMESTAMP=1575108452/*!*/;

#DROP TABLE `test` /* generated by server */ # 这行注释掉其他的可以不用管

/*!*/;

DELIMITER ;

# End of log file

  1. 删除数据库(可以在一个新的主机上做这个实验也可以)

[root@centos7 backup]# rm -rf /var/lib/mysql/*  # 删除数据库

[root@centos7 backup]# systemctl restart mariadb.service # 重启服务生成数据库

[root@centos7 backup]# ll /var/lib/mysql/

total 37852

-rw-rw---- 1 mysql mysql 16384 Nov 30 18:33 aria_log.00000001

-rw-rw---- 1 mysql mysql 52 Nov 30 18:33 aria_log_control

-rw-rw---- 1 mysql mysql 18874368 Nov 30 18:33 ibdata1

-rw-rw---- 1 mysql mysql 5242880 Nov 30 18:33 ib_logfile0

-rw-rw---- 1 mysql mysql 5242880 Nov 30 18:33 ib_logfile1

drwx------ 2 mysql mysql 4096 Nov 30 18:33 mysql

srwxrwxrwx 1 mysql mysql 0 Nov 30 18:33 mysql.sock

drwx------ 2 mysql mysql 4096 Nov 30 18:33 performance_schema

drwx------ 2 mysql mysql 6 Nov 30 18:33 test

  1. 登录数据库关闭二进制日志

[root@centos7 backup]# mysql

Welcome to the MariaDB monitor. Commands end with ; or g.

Your MariaDB connection id is 2

Server version: 5.5.60-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

MariaDB [(none)]> set sql_log_bin=0;

Query OK, 0 rows affected (0.00 sec)

  1. 还原完全备份

MariaDB [(none)]> source /backup/allbackup_2019-11-30_18:03:08.sql

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

.....(省略)

MariaDB [test]> show databases; # 查看数据库是否还原

+--------------------+

| Database |

+--------------------+

| information_schema |

| db1 |

| hello |

| hellodb |

| mysql |

| performance_schema |

| test |

+--------------------+

7 rows in set (0.00 sec)

  1. 再还原增量备份(注意是修改过误操作的那个文件)

MariaDB [test]> source /backup/inc.sql

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Database changed

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Charset changed

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 1 row affected, 1 warning (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 1 row affected, 1 warning (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

ERROR at line 65 in file: '/backup/inc.sql': No query specified # 这里没有执行就是我注释掉的drop命令(报错不用管)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

  1. 开启二进制日志

MariaDB [db1]> set sql_log_bin=1; # 确保数据还原完毕再打开

Query OK, 0 rows affected (0.00 sec)

  1. 查看数据是否还原

MariaDB [db1]> show tables;  # 表没有被删掉

+---------------+

| Tables_in_db1 |

+---------------+

| test |

+---------------+

1 row in set (0.00 sec)

MariaDB [db1]> select * from test; # 添加的记录也在

+----+------+--------+

| id | name | mobile |

+----+------+--------+

| 1 | rose | |

| 2 | jack | |

+----+------+--------+

2 rows in set (0.00 sec)

做以上实验确保你的二进制日志独立于数据库之外。

以上是 MySQL数据库备份和恢复 的全部内容, 来源链接: utcz.com/z/531629.html

回到顶部