Linux云计算 |【第四阶段】RDBMS1-DAY6

主要内容:

MySQL索引(索引分类、创建索引)、用户及授权(创建用户并授权、查看授权、撤销授权、授权库mysql)、root密码恢复、备份、使用mysqldump进行逻辑备份、Percona

一、MySQL索引

1、基本概念

MySQL 索引(Index),是用于加速数据库查询操作的重要工具。索引通过创建数据结构(如 B-Tree、Hash 等)来存储表中某一列或多列的值,从而提高查询效率。我们可以简单理解为:它是快速查找排好序的一种数据结构。(类似于书的目录,对表中字段值进行排序)

索引类型

B-Tree 索引:

  • 特点:B-Tree 索引是 MySQL 中最常用的索引类型,适用于范围查询、排序和分组操作。
  • 适用场景:适用于大多数查询场景,特别是需要范围查询和排序的场景。
  • 创建语法:CREATE INDEX index_name ON table_name(column_name);

Hash 索引:

  • 特点:Hash 索引适用于等值查询,查询速度非常快,但不支持范围查询和排序。
  • 适用场景:适用于等值查询场景,如 = 操作符。
  • 创建语法:CREATE INDEX index_name ON table_name(column_name) USING HASH;

全文索引:

  • 特点:全文索引用于全文搜索,适用于文本内容的搜索。
  • 适用场景:适用于需要对文本内容进行搜索的场景。
  • 创建语法:CREATE FULLTEXT INDEX index_name ON table_name(column_name);

空间索引:

  • 特点:空间索引用于地理空间数据的查询,如地理位置的搜索。
  • 适用场景:适用于地理空间数据的查询场景。
  • 创建语法:CREATE SPATIAL INDEX index_name ON table_name(column_name);

优点:

- 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性,可以大大提高MySQL的检索速度;

- 索引大大减小了服务器需要扫描的数据量;

- 索引可以帮助服务器避免排序和临时表;

- 索引可以将随机IO变成顺序IO;

缺点:

- 虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL的索引也要动态的调整,不仅要保存数据,还要保存索引文件,降低了数据的维护速度;

- 建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果在一个大表上创建了多种组合索引,索引文件会膨胀很快;

- 如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果;

- 对于非常小的表,大部分情况下简单的全表扫描更高效;

2、索引分类

① 普通索引

  • 不应用任何限制条件的索引,该索引可以在任何数据类型中创建。
  • 字段本身的约束条件可以判断其值是否为空或唯一。
  • 创建该类型索引后,用户在查询时,便可以通过索引进行查询。

② 唯一性索引

  • 使用UNIQUE参数可以设置唯一索引。
  • 创建该索引时,索引的值必须唯一,通过唯一索引,用户可以快速定位某条记录
  • 主键也是一种特殊的唯一索引。

链接:https://blog.csdn.net/qq_34793133/article/details/81712909

③ 全文索引

  • 使用FULLTEXT参数可以设置索引为全文索引。
  • 全文索引只能创建在CHAR、VARCHAR或者TEXT类型的字段上。查询数据量较大的字符串类型的字段时,使用全文索引可以提高查询速度。
  • 在默认情况下,应用全文搜索大小写不敏感。如果索引的列使用二进制排序后,可以执行大小写敏感的全文索引。

④ 单列索引

  • 顾名思义,单列索引即只对应一个字段的索引。
  • 应用该索引的条件只需要保证该索引值对应一个字段即可。
  • 可以包括普通、唯一、全文索引

 ⑤ 多列索引

  • 多列索引是在表的多个字段上创建一个索引。
  • 该索引指向创建时对应的多个字段,用户可以通过这几个字段进行查询。
  • 要想应用该索引,用户必须使用这些字段中的第一个字段。

3、普通索引index

使用规则:

① 一个表中可以有多个Index字段

② 字段的值允许重复,且可以赋Null值

③ 通常把它作为where查询条件的字段设置为Index字段(例如where “index字段”)

④ index索引字段的标志为 MUL

1)创建索引

方法1:创建表时创建索引

  • 语法格式:

CREATE TABLE 表名(

    字段列表,

    index(字段名),

    index(字段名),

);

方法2:在已有的表里创建索引

  • 语法格式:CREATE INDEX 索引名 ON 表名(字段名);

2)查看索引

  • 语法格式:

DESC 表名;     //注意观察Key这一列

SHOW INDEX FROM 表名 \G

3)删除索引

  • 语法格式:DROP INDEX 索引名 ON 库.表名;

例如:在已有的表里创建索引

mysql> create index index_birth on employees(birth_date);
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
 
mysql> desc employees;    // index索引字段的标志为MUL
+--------------+-------------+------+-----+---------+----------------+
| Field        | Type        | Null | Key | Default | Extra          |
+--------------+-------------+------+-----+---------+----------------+
| employee_id  | int(6)      | NO   | PRI | NULL    | auto_increment |
| name         | varchar(10) | YES  |     | NULL    |                |
| hire_date    | date        | YES  |     | NULL    |                |
| birth_date   | date        | YES  | MUL | NULL    |                |
| email        | varchar(25) | YES  |     | NULL    |                |
| phone_number | char(11)    | YES  |     | NULL    |                |
| dept_id      | int(4)      | YES  | MUL | NULL    |                |
+--------------+-------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

例如:查看数据表中已创建的索引

mysql> show index from employees\G
*************************** 1. row ***************************
        Table: employees
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: employee_id
    Collation: A
  Cardinality: 133
     Sub_part: NULL
       Packed: NULL
         Null:
   Index_type: BTREE
      Comment:
Index_comment:
*************************** 2. row ***************************
        Table: employees
   Non_unique: 1
     Key_name: dept_id_fk
 Seq_in_index: 1
  Column_name: dept_id
    Collation: A
  Cardinality: 8
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment:
Index_comment:
*************************** 3. row ***************************
        Table: employees
   Non_unique: 1
     Key_name: index_birth
 Seq_in_index: 1
  Column_name: birth_date
    Collation: A
  Cardinality: 132
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment:
Index_comment:
3 rows in set (0.00 sec)

二、用户及授权

1、创建用户并授权

  • 语法格式:GRANT 权限列表 ON 库名.表名 TO '用户名'@'客户端地址' IDENTIFIED BY '密码' [WITH GRANT OPTION];

解释说明:

- 权限列表:用户的操作权限,如`SELECT`,`INSERT`,`UPDATE`,`DELETE`等,如果要授予所有权限则使用【ALL】

- 表名:如果要授予该用户对所有数据库和表的相应操作权限则可用【*】表示,如【*.*】

- 用户名:将授予库.表的权限指定的用户,若用户不存在则自动创建;

- 客户端地址:如果是本机登录可写localhost,如果是任意地址登录可写【%】(不建议)

- WITH GRANT OPTION:赋予权限的用户还拥有授权权限;

 

2、客户端远程连接数据库

  • 语法格式:mysql -h服务器 -u用户名 -p密码     //需提前安装mysql/mariadb客户端

例如1:授予anj用户在本地登陆的权限

mysql> grant select,insert,update(phone_number,email) on nsd2021.employees 
    -> to anj@'localhost' identified by 'NSD2021@tedu.cn';
Query OK, 0 rows affected, 1 warning (0.00 sec)

# 登录另外一台主机访问数据库服务器(该主机使用Mariadb客户端)

[root@client ~]# mysql -uanj -pNSD2021@tedu.cn -h192.168.2.5  //授权地址是localhost
ERROR 1045 (28000): Access denied for user 'anj'@'gateway' (using password: YES)

[root@client ~]# ssh 192.168.2.5    //远程访问192.168.2.5服务器方式,本地登录数据库
[root@localhost ~]# mysql -uanj -pNSD2021@tedu.cn
Welcome to the MySQL monitor.  Commands end with ; or \g.
mysql> exit

例如2:授予anj用户在任意地址登陆的权限

mysql> grant select,insert,update(phone_number,email) on nsd2021.employees 
    -> to anj@'%' identified by 'NSD2021@tedu.cn';
Query OK, 0 rows affected, 1 warning (0.00 sec)

# 登录另一台主机访问数据库服务器(该主机使用Mariadb客户端)

[root@client ~]# mysql -uanj -pNSD2021@tedu.cn -h192.168.2.5  //授权地址是%任意
Welcome to the MariaDB monitor.  Commands end with ; or \g.
MySQL [(none)]>

# 测试SELECT权限

MySQL [(none)]> use nsd2021;
MySQL [nsd2021]> show tables;   //仅授予SELECT查nsd2021库employess表的权限;
+-------------------+
| Tables_in_nsd2021 |
+-------------------+
| employees         |
+-------------------+
1 row in set (0.00 sec)
 
MySQL [nsd2021]> select * from departments where dept_id=1;    //无法查看其它表
ERROR 1142 (42000): SELECT command denied to user 'anj'@'192.168.2.6' for table 'departments'

MySQL [nsd2021]> select * from employees where employee_id=3;
+-------------+-----------+------------+------------+------------------+--------------+---------+
| employee_id | name      | hire_date  | birth_date | email            | phone_number | dept_id |
+-------------+-----------+------------+------------+------------------+--------------+---------+
|           3 | 李玉英    | 2012-01-19 | 1974-01-25 | liyuying@tedu.cn | 15628557234  |       1 |
+-------------+-----------+------------+------------+------------------+--------------+---------+
1 row in set (0.00 sec)

# 测试INSERT权限

MySQL [nsd2021]> insert into employees (name) values ('张三');   //可执行INSERT插入
Query OK, 1 row affected (0.00 sec)
MySQL [nsd2021]> select * from employees where name=”张三”;
+-------------+--------+-----------+------------+---------------+--------------+---------+
| employee_id | name   | hire_date | birth_date | email         | phone_number | dept_id |
+-------------+--------+-----------+------------+---------------+--------------+---------+
|         134 | 张三   | NULL      | NULL       | NULL      | NULL       |    NULL |
+-------------+--------+-----------+------------+---------------+--------------+---------+
1 row in set (0.00 sec)

# 测试UPDATE权限(仅允许更新phone_number和email字段)

MySQL [nsd2021]> update employees set phone_number=13912342234,email='test@tedu.com' where name='张三';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
MySQL [nsd2021]> select * from employees where name='张三';
+-------------+--------+-----------+------------+---------------+--------------+---------+
| employee_id | name   | hire_date | birth_date | email         | phone_number | dept_id |
+-------------+--------+-----------+------------+---------------+--------------+---------+
|         134 | 张三   | NULL      | NULL       | test@tedu.com | 13912342234  |    NULL |
+-------------+--------+-----------+------------+---------------+--------------+---------+
1 row in set (0.00 sec)

# 测试DELETE权限

MySQL [nsd2021]> delete from employees where name='张三';   //拒绝执行DELETE删除
ERROR 1142 (42000): DELETE command denied to user 'anj'@'192.168.2.6' for table 'employees'

3、相关查询权限指令

① 查看用户信息

  • 格式:SELECT USER();
mysql> select user();
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

② 显示当前登陆用户的权限

  • 格式:SHOW GRANTS;
mysql> show grants;
+---------------------------------------------------------------------+
| Grants for root@localhost                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION        |
+---------------------------------------------------------------------+
2 rows in set (0.00 sec)

③ 管理员查看指定用户的权限,用户不存在则报错

  • 格式:SHOW GRANTS FOR 用户名@'客户端地址';

注意:如果创建并授权同一个用户有两条权限记录,权限会叠加,不会覆盖;

mysql> show grants for anj@'%';
+------------------------------------------------------------------------------------------+
| Grants for anj@%                                                                         |
+------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'anj'@'%'                                                          |
| GRANT SELECT, INSERT, UPDATE (email, phone_number) ON `nsd2021`.`employees` TO 'anj'@'%' |
+------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
 
mysql> show grants for anj@'localhost';
+--------------------------------------------------------------------------------------------------+
| Grants for anj@localhost                                                                         |
+--------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'anj'@'localhost'                                                          |
| GRANT SELECT, INSERT, UPDATE (email, phone_number) ON `nsd2021`.`employees` TO 'anj'@'localhost' |
+--------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

④ 修改用户自己的密码

  • 格式:SET PASSWORD=PASSWORD('密码');

- 补充:password(),即函数

- 补充:按向上箭头无法显示修改密码的历史记录(敏感数据)

mysql> set password=password('NSD2021@tedu.cn');
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> select password('NSD2021@tedu.cn');
+-------------------------------------------+
| password('NSD2021@tedu.cn')               |
+-------------------------------------------+
| *2EE7382F92B1F44D0DA9DBE20FE0078A1D370C49 |
+-------------------------------------------+
1 row in set, 1 warning (0.00 sec)

⑤ 管理员修改指定用户密码

  • 格式:SET PASSWORD FOR 用户名@'客户端地址'=PASSWORD('密码');
mysql> set password for jerry@'%'=password('NSD2021@tedu.cn');
Query OK, 0 rows affected, 1 warning (0.00 sec)

⑥ 删除授权用户

  • 格式:DROP USER 用户名@'客户端地址';
mysql> drop user anj@'%';
Query OK, 0 rows affected (0.00 sec)
 
mysql> drop user anj@'localhost';
Query OK, 0 rows affected (0.00 sec)

4、授权库mysql

授权库mysql常用记录相关授权的表(内部数据库mysql)

- user:记录已有的授权用户及权限(主要字段:User、Host)

- db:记录已有授权用户对数据库的访问权限(主要字段:User、Host、Db)

- tables_priv:记录已有授权用户对表的访问权限

- columns_priv:记录已有授权用户对字段的访问权限


授权库查询访问权限步骤示例:

mysql> grant select,insert,update(phone_number,email) on nsd2021.employees 
    -> to anj@'localhost' identified by 'NSD2021@tedu.cn';
Query OK, 0 rows affected, 1 warning (0.00 sec)

① 查看已有的授权用户及权限

mysql> select host,user from mysql.user;
+-----------+-----------+
| host      | user      |
+-----------+-----------+
| %         | root      |
| localhost | anj       |
| localhost | mysql.sys |
| localhost | root      |
+-----------+-----------+
7 rows in set (0.00 sec)

 ② 查看已有授权用户对数据库的访问权限

mysql> select host,user,db from mysql.db where user='anj';
Empty set (0.00 sec)

 ③ 查看已有授权用户对表的访问权限

mysql> select * from tables_priv where User like '%anj%'\G
*************************** 1. row ***************************
       Host: localhost
         Db: nsd2021
       User: anj
 Table_name: employees
    Grantor: root@localhost
  Timestamp: 0000-00-00 00:00:00
 Table_priv: Select,Insert
Column_priv: Update
1 row in set (0.00 sec)

 ④ 查看已有授权用户对字段的访问权限

mysql> select * from columns_priv where User like '%anj%'\G
*************************** 1. row ***************************
       Host: localhost
         Db: nsd2021
       User: anj
 Table_name: employees
Column_name: email
  Timestamp: 0000-00-00 00:00:00
Column_priv: Update
*************************** 2. row ***************************
       Host: localhost
         Db: nsd2021
       User: anj
 Table_name: employees
Column_name: phone_number
  Timestamp: 0000-00-00 00:00:00
Column_priv: Update
2 rows in set (0.00 sec)

 ⑤ 查看指定用户的权限

mysql> show grants for anj@'localhost';
+--------------------------------------------------------------------------------------------------+
| Grants for anj@localhost                                                                         |
+--------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'anj'@'localhost'                                                          |
| GRANT SELECT, INSERT, UPDATE (email, phone_number) ON `nsd2021`.`employees` TO 'anj'@'localhost' |
+--------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
 
mysql> show grants for anj@'localhost'\G
*************************** 1. row ***************************
Grants for anj@localhost: GRANT USAGE ON *.* TO 'anj'@'localhost'
*************************** 2. row ***************************
Grants for anj@localhost: GRANT SELECT, INSERT, UPDATE (email, phone_number) ON `nsd2021`.`employees` TO 'anj'@'localhost'
2 rows in set (0.00 sec)

5、撤销用户权限(REVOKE)

  • 语法格式:REVOKE 权限列表 ON 库名.表名 FROM 用户名@'客户端地址';

① 撤回代理授权权限

  • 格式:REVOKE GRANT OPTION ON *.* FROM 用户名@'客户端地址';

② 撤回用户删除权限

  • 格式:REVOKE DELETE ON *.* FROM 用户名@'客户端地址';

③ 撤回所有权限

  • 格式:REVOKE ALL ON *.* FROM 用户名@'客户端地址';

例如1:撤回anj用户的insert权限

mysql> revoke insert on nsd2021.employees from anj@'localhost';
Query OK, 0 rows affected (0.00 sec)
mysql> show grants for anj@'localhost';
+------------------------------------------------------------------------------------------+
| Grants for anj@localhost                                                                 |
+------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'anj'@'localhost'                                                  |
| GRANT SELECT, UPDATE (email, phone_number) ON `nsd2021`.`employees` TO 'anj'@'localhost' |
+------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

例如2:创建tom用户并授予代理授权权限

mysql> grant all on *.* to tom@'%' identified by 'NSD2021@tedu.cn' with grant option;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show grants for tom@'%';
+------------------------------------------------------------+
| Grants for tom@%                                           |
+------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'tom'@'%' WITH GRANT OPTION |
+------------------------------------------------------------+
1 row in set (0.00 sec)

# 登录另一台主机,使用tom用户访问数据库,并创建授权jerry用户

[root@client ~]# mysql -utom -pNSD2021@tedu.cn -h192.168.2.5
MySQL [(none)]> grant select on nsd2021.* to jerry@'%' identified by 'NSD2021@tedu.cn';
Query OK, 0 rows affected, 1 warning (0.00 sec)

# 撤回tom用户的grant option代理授予权限

mysql> revoke grant option on *.* from tom@'%';
Query OK, 0 rows affected (0.00 sec)
mysql> show grants for tom@'%';
+------------------------------------------+
| Grants for tom@%                         |
+------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'tom'@'%' |
+------------------------------------------+
1 row in set (0.00 sec)

# 登录另一台主机,使用tom用户访问数据库,并测试创建授权jerry用户效果

MySQL [(none)]> grant select on nsd2021.* to jim@'%' identified by 'NSD2021@tedu.cn';
ERROR 1044 (42000): Access denied for user 'tom'@'%' to database 'nsd2021'

例如3:撤回tom用户的所有权限

mysql> revoke all on *.* from tom@'%';
Query OK, 0 rows affected (0.00 sec)
mysql> show grants for tom@'%';
+---------------------------------+
| Grants for tom@%                |
+---------------------------------+
| GRANT USAGE ON *.* TO 'tom'@'%' |
+---------------------------------+
1 row in set (0.00 sec)

6、root密码恢复

恢复密码步骤:

① 停止MySQL服务

② 跳过授权表,并启动MySQL服务程序

③ 修改数据库root密码(authentication_string认证字符串)

④ 以正常方式重启MySQL服务程序


root密码恢复示例:

步骤1:停止MySQL服务

[root@localhost ~]# systemctl stop mysqld   //关闭服务

步骤2:修改配置文件,并启动MySQL服务程序

[root@localhost ~]# vim /etc/my.cnf
[mysqld]
skip-grant-tables    //跳过授权表
[root@localhost ~]# systemctl start mysqld     //启动服务

步骤3:修改数据库root密码

[root@localhost ~]# mysql
mysql> select user,host,authentication_string from mysql.user; //查看认证字符串(加密密码)
+-----------+-----------+-------------------------------------------+
| user      | host      | authentication_string                     |
+-----------+-----------+-------------------------------------------+
| root      | localhost | *2EE7382F92B1F44D0DA9DBE20FE0078A1D370C49 |
| mysql.sys | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| tom       | %         | *2EE7382F92B1F44D0DA9DBE20FE0078A1D370C49 |
| root      | %         | *2EE7382F92B1F44D0DA9DBE20FE0078A1D370C49 |
| anj       | localhost | *2EE7382F92B1F44D0DA9DBE20FE0078A1D370C49 |
| jerry     | %         | *2EE7382F92B1F44D0DA9DBE20FE0078A1D370C49 |
+-----------+-----------+-------------------------------------------+
6 rows in set (0.00 sec)

mysql> update mysql.user set authentication_string=password('123456')
-> where user='root' and host='localhost';   //不筛选条件则更新所有记录的密码
Query OK, 1 row affected, 1 warning (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 1

mysql> flush privileges;    //刷新权限
Query OK, 0 rows affected (0.00 sec)

步骤4:以正常方式重启MySQL服务程序

[root@localhost ~]# systemctl stop mysqld
[root@localhost ~]# vim /etc/my.cnf
# skip-grant-tables    //注释跳过授权表
[root@localhost ~]# systemctl start mysqld
[root@localhost ~]# mysql -uroot -p123456    //测试新密码登录访问数据库
mysql>

补充:当mysql 新设置用户或更改密码后需用flush privileges刷新MySQL的系统权限相关表,否则会出现拒绝访问;还有一种方法,就是重新启动mysql服务器,来使新设置生效。

三、数据库备份/还原

(物理备份、完全备份、差异备份、增量备份)

1、物理备份

备份方法:拷贝/var/lib/mysql数据库目录,存放到目标主机即可;

补充:若要还原新的数据库,可直接删除/var/lib/mysql数据库目录,再重启mysql服务

注意:无论备份还是恢复,都要验证用户权限!


物理备份步骤示例:

步骤1:准备两台虚拟机,并安装mysql服务(192.168.2.5和192.168.2.10)

[root@localhost ~]# scp /etc/yum.repos.d/mysql.repo 192.168.2.10:/etc/yum.repos.d/
[root@node10 ~]# yum -y install mysql-community*   //安装mysql服务,但不启动服务

步骤2:源主机192.168.2.5操作

① 停止数据库服务(服务需要停止,数据才不会继续更新)

[root@localhost ~]# systemctl stop mysqld

② 拷贝/var/lib/mysql数据库目录,到目标主机;拷贝完成后再启动服务

[root@localhost ~]# scp -r /var/lib/mysql root@192.168.2.10:/var/lib/mysql
[root@localhost ~]# systemctl start mysqld

步骤3:目标主机192.168.2.10操作

[root@node10 ~]# useradd mysql    //创建mysql用户
[root@node10 ~]# chown -R mysql:mysql /var/lib/mysql   //修改文件属主:属组权限
[root@node10 ~]# syscteml start mysqld   //启动数据库服务

步骤4:测试数据库连接

[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb               |
| mysql              |
| nsd2021            |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

1.1、使用mysqldump进行逻辑备份

- 备份所有数据:

① 完全备份:备份所有数据(单一或多个库、单一或多张表、整个数据库)

- 只备份更新数据:

② 差异备份:备份自完全备份后产生的数据(完全备份+差异备份)

③ 增量备份:备份自上次备份之后产生的数据(完全备份+增量备份)

  • 补充:使用差异备份适合存储容量充足的场景,首次备份都是先完全备份,后续再进行差异备份(自完全备份后产生的数据);若要还原数据,只需要还原最终备份的那一次;
  • 补充:使用增量备份适合存储容量小、数据小的场景,首次备份也是先完全备份,后续再进行增量备份(自上一次备份之后产生的数据);若要还原数据,需要还原每一次的备份;
  • 注意:无论备份还是恢复,都要验证用户权限!

2、完全备份

备份命令

  • 语法格式:mysqldump -u用户名 -p密码 > 路径/文件名.sql

恢复命令(导入数据库)

  • 语法格式:mysql -u用户名 -p密码 < 路径/备份文件名.sql

完全备份示例:

1)备份所有库

  • 格式:mysqldump -u用户 -p密码 –all-databases > 路径/文件名.sql
  • 格式:mysqldump -u用户 -p密码 -A > 路径/文件名.sql

步骤1:源数据库192.168.2.5操作

[root@localhost ~]# mkdir /root/dbbackup    //手动创建备份目录

方法1:

[root@localhost ~]# mysqldump -uroot -pNSD2021@tedu.cn --all-databases > dbbackup/alldb.sql

方法2:

[root@localhost ~]# mysqldump -uroot -pNSD2021@tedu.cn -A > dbbackup/alldb.sql

补充:备份的sql文件中有建库和删表、建表操作来完成完全备份,其中LOCK WRITE代表写锁,防止在同一时间去写入数据时发生冲突;先进行写操作的先写;

# 拷贝文件到目标服务器

[root@localhost ~]# scp -r /root/dbbackup root@192.168.2.10:/root/

步骤2:目标数据库192.168.2.10进行恢复操作

[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn < /root/dbbackup/alldb.sql
[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb               |
| mysql              |
| nsd2021            |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

2)备份某个库(包括库里的所有表)

  • 格式:mysqldump -u用户 -p密码 数据库 > 路径/文件名.sql

步骤1:源数据库192.168.2.5操作

[root@localhost ~]# mysqldump -uroot -pNSD2021@tedu.cn nsd2021 > dbbackup/tedu_db.sql

补充:备份的sql文件中有删表和建表操作来完成完全备份

# 拷贝文件到目标服务器

[root@localhost ~]# scp -r /root/dbbackup/ root@192.168.2.10:/root/

步骤2:目标数据库192.168.2.10进行恢复操作

mysql> drop database nsd2021;   //删除库,以便测试结果
mysql> create database nsd2021 default charset utf8mb4;    //创建数据库

[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn nsd2021 < /root/dbbackup/tedu_db.sql
[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb               |
| mysql              |
| nsd2021            |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

3)备份某一张表

  • 格式:mysqldump -u用户 -p密码 数据库 数据表 > 路径/文件名.sql

步骤1:源数据库192.168.2.5操作

[root@localhost ~]# mysqldump -uroot -pNSD2021@tedu.cn nsd2021 salary > dbbackup/nsd2021_salary.sql

补充:备份的sql文件中有删salary表和建salary表操作来完成完全备份

# 拷贝文件到目标服务器

[root@localhost ~]# scp -r dbbackup/ root@192.168.2.10:/root/

步骤2:目标数据库192.168.2.10进行恢复操作

mysql> truncate salary;    // 清空表,以便测试结果

[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn nsd2021 < /root/dbbackup/nsd2021_salary.sql
[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> select count(*) from nsd2021.salary;
+----------+
| count(*) |
+----------+
|     8055 |
+----------+
1 row in set (0.00 sec)

4)备份多个库

  • 格式:mysqldump -u用户 -p密码 -B 数据库1 数据库2 > 路径/文件名.sql

步骤1:源数据库192.168.2.5操作

[root@localhost ~]# mysqldump -uroot -pNSD2021@tedu.cn -B nsd2021 mysql > dbbackup/twodb.sql

补充:备份的sql文件中有建库和多个删表、建表操作来完成完全备份

# 拷贝文件到目标服务器

[root@localhost ~]# scp -r dbbackup/ root@192.168.2.10:/root/

步骤2:目标数据库192.168.2.10进行恢复操作

mysql> drop database nsd2021;    //删除库,以便测试结果
mysql> drop database mysql;

[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn < /root/dbbackup/twodb.sql
[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb               |
| mysql              |
| nsd2021            |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

5)备份多张表

  • 格式:mysqldump -u用户 -p密码 数据库 数据表1 数据表2 > 路径/文件名.sql

步骤1:源数据库192.168.2.5操作

[root@localhost ~]# mysqldump -uroot -pNSD2021@tedu.cn nsd2021 employees salary > dbbackup/nsd2021_employees_salary.sql

# 拷贝文件到目标服务器

[root@localhost ~]# scp -r dbbackup/ root@192.168.2.10:/root/

步骤2:目标数据库192.168.2.10进行恢复操作

mysql> truncate salary;      //清空表,以便测试结果
mysql> delete from employees;

[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn nsd2021 < /root/dbbackup/nsd2021_employees_salary.sql
mysql> select count(*) from nsd2021.employees;
+----------+
| count(*) |
+----------+
|      134 |
+----------+
1 row in set (0.00 sec)
mysql> select count(*) from nsd2021.salary;
+----------+
| count(*) |
+----------+
|     8055 |
+----------+
1 row in set (0.00 sec)

3、增量备份

binlog日志概述

- binlog日志(二进制日志),是MySQL服务日志文件的一种,默认没有启用;

- 记录除查询之外的所有SQL命令(对数据库造成影响的SQL命令);

- 可用于数据的备份和恢复(增量备份);(原理:即恢复数据时,执行日志文件记录的SQL语句)

- 它是MySQL主从同步的必要条件;

- 修改/etc/my.cnf主配置文件来启用binlog日志文件

配置项

用途

server_id=数字

指定服务器id值(1-255)

log-bin 或 log_bin=目录/文件名

启用binlog日志,不指定默认存放在/var/lib/mysql

max_binlog_size=数值m

日志文件容量,默认1GB

注意:无论备份还是恢复,都要验证用户权限! 


1)启用binlog日志示例:

mysql> show master status;   //列出binlog日志偏移点位(Position)信息
Empty set (0.00 sec)   //未开启日志为空

① 修改数据库主配置文件

[root@localhost ~]# vim /etc/my.cnf
[mysqld]
server_id = 5     //指定服务器id
log_bin     //启用binlog日志(不指定目录默认存放在/var/lib/mysql)
…
[root@localhost ~]# systemctl restart mysqld   //重启服务

② 测试

通过MySQL查看binlog日志偏移点位信息

[root@localhost ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| localhost-bin.000001 |      154 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

- 查看保存日志的目录(以主机名命名的-bin.000001日志文件和-bin..index文件)

[root@localhost ~]# ls /var/lib/mysql/localhost-bin.*
/var/lib/mysql/localhost-bin.000001  /var/lib/mysql/localhost-bin.index
[root@localhost ~]# cat /var/lib/mysql/localhost-bin.index
./localhost-bin.000001

补充:binlog日志文件名的命名默认会加编号(例如:文件-000001),当超过日志文件容量默认1GB时,自动创建第二个日志文件(例如:文件-000002)

补充:bin..index文件用来存放已存在的binlog日志文件;

2)手动创建binlog日志文件示例:

binlog文件默认存在/var/lib/mysql目录下,也可手动进行制定binlog日志存放目录和文件名;

① 创建用于保存日志文件的目录

[root@localhost ~]# mkdir /mybinlog
[root@localhost ~]# chown mysql:mysql /mybinlog/

② 修改数据库主配置文件

[root@localhost ~]# vim /etc/my.cnf
[mysqld]
server_id = 5
log_bin = /mybinlog/mylog   //指定存放日志的目录/文件名
…
[root@localhost ~]# systemctl restart mysqld    //重启服务

③ 测试

通过MySQL查看binlog日志偏移点位信息

[root@localhost ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> show master status;
+--------------+----------+--------------+------------------+-------------------+
| File         | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------+----------+--------------+------------------+-------------------+
| mylog.000001 |      154 |              |                  |                   |
+--------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

查看创建的保存日志目录

[root@localhost ~]# ls /mybinlog/
mylog.000001  mylog.index

3)新建binlog日志文件示例:

① 方法1:重启mysql服务

[root@localhost ~]# systemctl restart mysqld
[root@localhost ~]# ls /mybinlog/
mylog.000001  mylog.000002  mylog.index
[root@localhost ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> show master status;
+--------------+----------+--------------+------------------+-------------------+
| File         | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------+----------+--------------+------------------+-------------------+
| mylog.000002 |      154 |              |                  |                   |
+--------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

② 方法2:flush指令

mysql> flush logs;
Query OK, 0 rows affected (0.01 sec)
mysql> show master status;
+--------------+----------+--------------+------------------+-------------------+
| File         | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------+----------+--------------+------------------+-------------------+
| mylog.000003 |      154 |              |                  |                   |
+--------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
[root@localhost ~]# ls /mybinlog/
mylog.000001  mylog.000002  mylog.000003  mylog.index

③ 方法3:备份时刷新日志

[root@localhost ~]# mysqldump -uroot -pNSD2021@tedu.cn --flush-logs nsd2021 > dbbackup/nsd2021_full.sql
[root@localhost ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> show master status;
+--------------+----------+--------------+------------------+-------------------+
| File         | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------+----------+--------------+------------------+-------------------+
| mylog.000004 |      154 |              |                  |                   |
+--------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
[root@localhost ~]# ls /mybinlog/
mylog.000001  mylog.000002  mylog.000003  mylog.000004  mylog.index
[root@localhost ~]# cat /mybinlog/mylog.index
/mybinlog/mylog.000001
/mybinlog/mylog.000002
/mybinlog/mylog.000003
/mybinlog/mylog.000004

4)删除已有的binlog日志

① 删除指定编号之前的日志文件

  • 格式:purge master logs to "日志文件名.编号";

注意:删除指定日志文件编号之前的日志,不包含本身;

注意:尽量使用MySQL的purge命令去删除日志,rm删除无法删除数据库内部关系 

例如:删除mylog.000003(不包含)之前的日志

mysql> purge master logs to "mylog.000003";
Query OK, 0 rows affected (0.00 sec)
[root@localhost ~]# ls /mybinlog/    //查看目录下剩余的日志文件
mylog.000003  mylog.000004  mylog.index
[root@localhost ~]# cat /mybinlog/mylog.index
/mybinlog/mylog.000003
/mybinlog/mylog.000004

② 删除所有日志,并重新启用新日志

  • 格式:reset master     //立刻删除谨慎操作
mysql> reset master;
Query OK, 0 rows affected (0.01 sec)
mysql> show master status;
+--------------+----------+--------------+------------------+-------------------+
| File         | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------+----------+--------------+------------------+-------------------+
| mylog.000001 |      154 |              |                  |                   |
+--------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
[root@localhost ~]# ls /mybinlog/   //查看目录下剩余的日志文件
mylog.000001  mylog.index

5)通过binlog日志修改数据库示例:

通过mysqlbinlog命令,以明文的方式查看binlog日志内容;

  • 格式:mysqlbinlog /Binlog日志文件.编号 | mysql -uroot -p密码

步骤1:源服务器192.168.2.5进行插入操作

补充:需先开启binlog日志,且进行除select外的SQL语句操作才能被记录;

① 查看binlog日志的偏移点位信息

mysql> show master status;
+--------------+----------+--------------+------------------+-------------------+
| File         | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------+----------+--------------+------------------+-------------------+
| mylog.000001 |      154 |              |                  |                   |
+--------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

② 向departments表中插入数据

mysql> insert into departments(dept_name) values ('store1'),('store2'),('store3');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> select * from departments;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|      37 | store1    |
|      38 | store2    |
|      39 | store3    |
+---------+-----------+
35 rows in set (0.00 sec)

③ 再次查看binlog日志的偏移点位信息变化

mysql> show master status;
+--------------+----------+--------------+------------------+-------------------+
| File         | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------+----------+--------------+------------------+-------------------+
| mylog.000001 |      458 |              |                  |                   |
+--------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

④ 查看binlog日志内容

[root@localhost ~]# mysqlbinlog /mybinlog/mylog.000001

扩展:可通过echo 'BINLOG内容' | base64 –decode 简单查看base64格式里的内容

⑤ 将binlog日志拷贝到目标主机

[root@localhost ~]# scp -r /mybinlog/ 192.168.2.10:/root
root@192.168.2.10's password:
mylog.000001                100%  458   670.0KB/s   00:00
mylog.index                 100%   23    57.3KB/s   00:00

步骤2:在目标主机192.168.2.10上通过binlog同步源主机上的数据

[root@node10 ~]# ls /root/mybinlog/
mylog.000001  mylog.index
[root@node10 ~]# mysqlbinlog /root/mybinlog/mylog.000001 | mysql -uroot -pNSD2021@tedu.cn

验证:

[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> select * from nsd2021.departments;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|      37 | store1    |
|      38 | store2    |
|      39 | store3    |
+---------+-----------+
35 rows in set (0.00 sec)

补充:通过binlog同步源主机上的数据,原理:查看并执行binlog日志中记录的所有对数据库产生影响的SQL语句,来实现数据的还原操作;实现增量备份,则执行不同的binlog日志文件达到效果;

6)修改binlog记录格式示例:

 binlog日记记录方式

① row:行模式(默认模式),不记录SQL语句上下文相关信息,仅保存哪条记录被修改

② statement:陈述模式(易读),每一条会修改数据的SQL语句都会记录在Binlog中

③ mixed:混合模式(row+statement),以上两种的混合使用

  • 命令:show variables like 'binlog_format';    //通过MySQL查看binlog日记记录方式

步骤1:查看当前binlog日记记录方式

mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.00 sec)

步骤2:修改日志记录格式

[root@localhost ~]# vim /etc/my.cnf     //修改数据库主配置文件
[mysqld]
server_id = 5
log_bin = /mybinlog/mylog
binlog_format = 'mixed'        //修改日志记录格式为混合模式
[root@localhost ~]# systemctl restart mysqld     //重启服务

步骤3:查看binlog日志信息并修改数据

[root@localhost ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> show master status;    //因服务重启,binlog日志文件已更新
+--------------+----------+--------------+------------------+-------------------+
| File         | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------+----------+--------------+------------------+-------------------+
| mylog.000002 |      154 |              |                  |                   |
+--------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> use nsd2021;
mysql> insert into departments(dept_name) values('store4'),('store5');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

步骤4:查看日志

[root@localhost ~]# mysqlbinlog /mybinlog/mylog.000002

7)通过binlog日志指定范围内的数据进行恢复

  • 格式:mysqlbinlog --start-position=起始 --stop-position=结束 /Binlog日志文件.编号 | mysql -uroot -p密码

步骤1:源主机192.168.2.5进行删除操作(使binlog日志记录删除SQL语句)

[root@localhost ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> delete from nsd2021.departments where dept_name like 'store%';
Query OK, 5 rows affected (0.01 sec)

mysql> show master status;
+--------------+----------+--------------+------------------+-------------------+
| File         | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------+----------+--------------+------------------+-------------------+
| mylog.000002 |      791 |              |                  |                   |
+--------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

# 拷贝日志文件到目标服务器

[root@localhost ~]# scp -r /mybinlog/ root@192.168.2.10:/root

步骤2:在目标主机上查看日志,找到要恢复数据的起始和结束偏移量

首先读取binlog日志,找到插入store4日志上面的at偏移量作为起始值,找到插入store5日志下面的COMMIT之后的at偏移量作为结束值;

[root@node10 ~]# ls /root/mybinlog/
mylog.000001  mylog.000002  mylog.index
[root@node10 ~]# mysqlbinlog /root/mybinlog/mylog.000002
[root@node10 ~]# mysqlbinlog --start-position=328 --stop-position=493 /root/mybinlog/mylog.000002 | mysql -uroot -pNSD2021@tedu.cn

验证:将只有在源服务器插入的数据恢复到目标服务器上(store4、store5)

[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> select * from nsd2021.departments;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|      37 | store1    |
|      38 | store2    |
|      39 | store3    |
|      40 | store4    |
|      41 | store5    |
+---------+-----------+
37 rows in set (0.00 sec)

四、Percona概述

Percona 是一家专注于 MySQL 和 MariaDB 数据库技术的企业,提供了一系列高性能、高可用性和可扩展性的数据库解决方案。Percona 的产品和服务广泛应用于各种规模的企业,帮助它们优化数据库性能、提高数据可靠性并降低运营成本。

1、Percona XtraBackup:

是一个开源的 MySQL 备份工具,支持在线备份和增量备份。

  1. 支持热备份,无需锁定表。
  2. 提供增量备份和压缩功能。
  3. 支持多种存储引擎,包括 InnoDB 和 XtraDB。
  4. 适用于需要高可用性和数据保护的应用场景。

Percona解决的问题:

物理备份缺点:

  • ① 跨平台性差
  • ② 备份时间长、冗余备份、浪费存储空间

mysqldump备份缺点:

  • ① 效率较低、备份和还原速度慢、锁表
  • ② 备份过程中,数据插入和更新操作被阻塞

主要包含两个组件:

  • ① xtrabackup:C程序,支持InnoDB/XtraDB
  • ② innobackupex:以Perl脚本封装xtrabackup,还支持MyISAM引擎

2、安装Percona环境

可参考/lnmp_sort/4/.rpm: xtrabackup、libev依赖

步骤1:在yum服务器上生成yum源

[root@localhost ~]# cp percona-xtrabackup-24-2.4.7-1.el7.x86_64.rpm libev-4.15-1.el6.rf.x86_64.rpm /var/www/html/mysql
[root@localhost ~]# cd /var/www/html/mysql
[root@localhost mysql]# ls
percona-xtrabackup-24-2.4.7-1.el7.x86_64.rpm
libev-4.15-1.el6.rf.x86_64.rpm   repodata
[root@localhost mysql]# createrepo -v .   //-v输出详细信息

步骤2:在数据库服务器上安装percona

[root@localhost mysql]# yum -y install percona-xtrabackup-24-2.4.7-1.el7.x86_64.rpm
[root@localhost mysql]# rpm -ql precona-xtrabackup-24
/usr/bin/innobackupex   //备份innodb、xtrdb、myisam引擎的表
/usr/bin/xbcloud
/usr/bin/xbcloud_osenv50
/usr/bin/xbcrypt
/usr/bin/xbstream
/usr/bin/xtrabackup     //备份innodb、xtrdb引擎的表

查看命令帮助

# innobackupex --help    //常用选项
# man innobackupex       //详细帮助

3、Percona完全备份数据库

语法格式:

  • ① 备份语法

innobackupex -u用户名 -p密码 备份目录名 [--no-timestamp]

注意:备份目录名不用提前创建

  • ② 恢复语法

innobackupex --apply-log 备份目录名   //准备恢复数据

innobackupex --copy-back 备份目录名  //复制数据

补充:通过cat 备份目录名/xtrabackup_checkpoints,可查看备份目录状态

选项说明:

常用选项

含义

-u

用户名

-p

密码

--no-timestamp

不带时间戳命名文件存储的子目录名

--apply-log

准备恢复数据

--copy-back

复制数据

--databases

--databases="库名"         //1个库

--databases="库1 库2"    //多个库

--databases="库1.表"      //1张表

--incremental /目录名

新数据存放目录

--incremental-basedir=/目录名

备份新数据参考目录

--incremental-dir=/目录名

合并数据存放目录


完全备份数据库示例:

步骤1:源服务器192.168.2.5操作,进行完全备份数据到/pbackup/目录

① 方法1:在备份目录下生成带时间戳的子目录(备份目录不用提前创建)

[root@localhost ~]# innobackupex -uroot -pNSD2021@tedu.cn /pbackup/fullbackup   //默认带时间戳
210609 10:47:54 innobackupex: Starting the backup operation
…
[root@localhost ~]# ls /pbackup/fullbackup/    //带时间戳的子目录
2021-06-09_10-47-54
[root@localhost ~]# ls /pbackup/fullbackup/2021-06-09_10-47-54/    //备份/var/lib/mysql的所有数据
backup-my.cnf   ibdata1  mysql    performance_schema  xtrabackup_checkpoints  xtrabackup_logfile
ib_buffer_pool  mydb     nsd2021  sys                 xtrabackup_info

② 方法2:不生成带时间戳的子目录

[root@localhost ~]# innobackupex -uroot -pNSD2021@tedu.cn /pbackup/full20210609 --no-timestamp    //不带时间戳 
210609 10:50:17 innobackupex: Starting the backup operation
…
[root@localhost ~]# ls /pbackup/full20210609/   //备份/var/lib/mysql的所有数据
backup-my.cnf   ibdata1  mysql    performance_schema  xtrabackup_checkpoints  xtrabackup_logfile
ib_buffer_pool  mydb     nsd2021  sys                 xtrabackup_info

步骤2:目标服务器192.168.2.10恢复数据

① 通过YUM安装percona

[root@node10 ~]# yum -y install percona-xtrabackup-24.x86_64

② 将源服务器的完全备份目录拷贝到目标服务器

[root@localhost ~]# scp -r /pbackup/ root@192.168.2.10:/root

# 查看备份目录状态(非必须步骤)(../xtrabackup_checkpoints

[root@node10 ~]# cat /root/pbackup/
full20210609/ fullbackup/
[root@node10 ~]# cat /root/pbackup/full20210609/xtrabackup_checkpoints
backup_type = full-backuped    //备份类型为:已完全备份
from_lsn = 0          //起始日志序列号
to_lsn = 3738996      //结束日志序列号
last_lsn = 3739005
compact = 0
recover_binlog_info = 0

③ 准备恢复数据【--apply-log】

[root@node10 ~]# innobackupex --apply-log /root/pbackup/full20210609/

# 查看备份目录状态(非必须步骤)

[root@node10 ~]# cat /root/pbackup/full20210609/xtrabackup_checkpoints
backup_type = full-prepared    //备份类型为:已准备就绪
from_lsn = 0
to_lsn = 3738996
last_lsn = 3739005
compact = 0
recover_binlog_info = 0

④ 停止mysqld服务

[root@node10 ~]# systemctl stop mysqld

⑤ 恢复时要求mysql数据库目录为空

[root@node10 ~]# rm -rf /var/lib/mysql/*

⑥ 恢复数据(拷贝备份目录的数据,即/var/lib/mysql下数据【--copy-back】

[root@node10 ~]# innobackupex --copy-back /root/pbackup/full20210609/

⑦ 修改mysql数据库目录的属主、属组权限

[root@node10 ~]# ls -ll /var/lib/mysql
总用量 122916
-rw-r-----. 1 root root      533 6月   9 12:36 ib_buffer_pool
-rw-r-----. 1 root root 12582912 6月   9 12:36 ibdata1
-rw-r-----. 1 root root 50331648 6月   9 12:36 ib_logfile0
-rw-r-----. 1 root root 50331648 6月   9 12:36 ib_logfile1
-rw-r-----. 1 root root 12582912 6月   9 12:36 ibtmp1
drwxr-x---. 2 root root       66 6月   9 12:36 mydb
drwxr-x---. 2 root root     4096 6月   9 12:36 mysql
drwxr-x---. 2 root root      188 6月   9 12:36 nsd2021
drwxr-x---. 2 root root     8192 6月   9 12:36 performance_schema
drwxr-x---. 2 root root     8192 6月   9 12:36 sys
-rw-r-----. 1 root root      443 6月   9 12:36 xtrabackup_info

[root@node10 ~]# chown -R mysql:mysql /var/lib/mysql
[root@node10 ~]# ls -ll /var/lib/mysql
总用量 122916
-rw-r-----. 1 mysql mysql      533 6月   9 12:36 ib_buffer_pool
-rw-r-----. 1 mysql mysql 12582912 6月   9 12:36 ibdata1
-rw-r-----. 1 mysql mysql 50331648 6月   9 12:36 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648 6月   9 12:36 ib_logfile1
-rw-r-----. 1 mysql mysql 12582912 6月   9 12:36 ibtmp1
drwxr-x---. 2 mysql mysql       66 6月   9 12:36 mydb
drwxr-x---. 2 mysql mysql     4096 6月   9 12:36 mysql
drwxr-x---. 2 mysql mysql      188 6月   9 12:36 nsd2021
drwxr-x---. 2 mysql mysql     8192 6月   9 12:36 performance_schema
drwxr-x---. 2 mysql mysql     8192 6月   9 12:36 sys
-rw-r-----. 1 mysql mysql      443 6月   9 12:36 xtrabackup_info

⑧ 启动Mysql服务

[root@node10 ~]# systemctl start mysqld

4、Percona完全备份恢复单张表

表空间:

- 数据驻留在磁盘上的位置,称为数据目录,如/var/lib/mysql

- 从MySQL 5.6.6版开始,用户可以创建并指定他们想要存储数据的表空间,从而实现数据操作和恢复过程的吞吐量。

- InnoDB的表文件功能为每个表提供了单独的.ibd数据和索引文件,代表一个单独的通用表空间。这样数据库中的每个表都可以指向数据目录的不同位置。

补充:frm表结构、ibd表空间

  • MySQL中.frm文件:保存了每个表的元数据,包括表结构的定义等,该文件与数据库引擎无关。
  • MySQL中.ibd文件:InnoDB引擎开启了独立表空间(my.ini中配置innodb_file_per_table = 1)产生的存放该表的数据和索引的文件

— 恢复单表步骤:

① 删除待恢复表的表空间 (表名.ibd)

② 导出备份目录中的表信息(表名.cfg、表名.exp)

③ 拷贝表信息文件到数据库目录下(表名.cfg、表名.exp、表名.ibd)

④ 修改表信息文件的所有者及组用户为mysql

⑤ 导入拷贝的表空间

⑥ 删除数据库目录下的表信息文件

⑦ 验证:查看表记录

  • 格式:alter table 表名 discard tablespace;      //通过MySQLl删除表空间
  • 格式:alter table 表名 import tablespace;       //通过MySQL导入表空间

完全备份恢复单张表示例:

① 假设误操作删除表内容

[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> truncate nsd2021.salary;     //清空表记录
mysql> select * from salary;
Empty set (0.00 sec)

② 恢复准备:删除待恢复表的表空间 (salary.ibd)

[root@node10 ~]# ls /var/lib/mysql/nsd2021/    //删除表空间前,salary.ibd存在
db.opt  departments.frm  departments.ibd  employees.frm  employees.ibd  
salary.frm  salary.ibd  wage_grade.frm  wage_grade.ibd

mysql> alter table salary discard tablespace;    //通过mysql删除表空间
Query OK, 0 rows affected (0.00 sec)

[root@node10 ~]# ls /var/lib/mysql/nsd2021/    //删除表空间后,salary.ibd消失
db.opt  departments.frm  departments.ibd  employees.frm  employees.ibd  
salary.frm  wage_grade.frm  wage_grade.ibd

③ 在备份目录中,导出表信息(包括.exp和.cfg)【--apply-log --export】

[root@node10 ~]# innobackupex --apply-log --export /root/pbackup/fullbackup/2021-06-09_10-47-54/
[root@node10 ~]# ls /root/pbackup/fullbackup/2021-06-09_10-47-54/nsd2021/
db.opt           departments.frm  employees.exp  salary.cfg  salary.ibd      wage_grade.frm
departments.cfg  departments.ibd  employees.frm  salary.exp  wage_grade.cfg  wage_grade.ibd
departments.exp  employees.cfg    employees.ibd  salary.frm  wage_grade.exp

④ 拷贝表信息文件到数据库目录下(salary.{cfg,exp,ibd})

[root@node10 ~]# cp /root/pbackup/fullbackup/2021-06-09_10-47-54/nsd2021/salary.{cfg,exp,ibd} /var/lib/mysql/nsd2021/

⑤ 修改表信息文件的所有者及组用户为mysql

[root@node10 ~]# chown mysql:mysql /var/lib/mysql/nsd2021/salary.*
[root@node10 ~]# ls -ll /var/lib/mysql/nsd2021/
总用量 968
-rw-r-----. 1 mysql mysql     67 6月   9 12:36 db.opt
-rw-r-----. 1 mysql mysql   8606 6月   9 12:36 departments.frm
-rw-r-----. 1 mysql mysql  98304 6月   9 12:36 departments.ibd
-rw-r-----. 1 mysql mysql   8800 6月   9 12:36 employees.frm
-rw-r-----. 1 mysql mysql 131072 6月   9 12:36 employees.ibd
-rw-r--r--. 1 mysql mysql    671 6月   9 14:35 salary.cfg
-rw-r-----. 1 mysql mysql  16384 6月   9 14:35 salary.exp
-rw-r-----. 1 mysql mysql   8694 6月   9 12:36 salary.frm
-rw-r-----. 1 mysql mysql 589824 6月   9 14:35 salary.ibd
-rw-r-----. 1 mysql mysql   8646 6月   9 12:36 wage_grade.frm
-rw-r-----. 1 mysql mysql  98304 6月   9 12:36 wage_grade.ibd

⑥ 恢复数据:导入表空间

mysql> alter table salary import tablespace;
Query OK, 0 rows affected (0.01 sec)

⑦ 删除数据库目录下的表信息文件

[root@node10 ~]# rm -f /var/lib/mysql/nsd2021/salary.{cfg,exp}

⑧ 验证:查看表记录

[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> select count(*) from nsd2021.salary;
+----------+
| count(*) |
+----------+
|     8055 |
+----------+
1 row in set (0.00 sec)

5、Percona增量备份

增量备份基础:备份自上次备份以来的数据,一般来说需要有一个完全备份

  • 语法格式:

① 备份语法:innobackupex -u 用户名 -p 密码 [ --databases=”数据库名.列表” ] --incremental 增量备份目录 --incremental-basedir=备份目录名 [ --no-timestamp ]

注意:第一次增量备份以完全备份为基础,第二次增量备份以第一次增量备份为基础,以此类推

② 恢复语法:

# 准备恢复数据

innobackupex --apply-log --redo-only 首次备份目录名

# 合并数据

innobackupex --apply-log --redo-only 首次备份目录名 --incremental-dir=合并增量备份目录名

# 恢复数据

innobackupex --copy-back 首次备份目录名

注意:第一次增量恢复以【首次完全备份】为基础并进行与【增量备份】合并,再将合并后的【完全备份】进行恢复;第二次增量备份以【增量备份合并完全备份】为基础并再进行与【增量备份】合并,再次对合并后的【完全备份】进行恢复;


增量备份示例1:

步骤1:在源服务器上添加数据

[root@localhost ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> insert into nsd2021.departments(dept_name) values('market1'),('market2'),('market3');
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> select * from departments;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|      31 | market1   |
|      32 | market2   |
|      33 | market3   |
+---------+-----------+
29 rows in set (0.00 sec)

步骤2:在源服务器上进行增量备份

[root@localhost ~]# innobackupex -uroot -pNSD2021@tedu.cn --incremental /pbackup/incr20210609 --incremental-basedir=/pbackup/full20210609/ --no-timestamp
[root@localhost ~]# cat /pbackup/full20210609/xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0          //起始时间序列号
to_lsn = 3738996      //结束时间序列号
last_lsn = 3739005
compact = 0
recover_binlog_info = 0

[root@localhost ~]# cat /pbackup/incr20210609/xtrabackup_checkpoints
backup_type = incremental   //备份类型为增量
from_lsn = 3738996    //起始时间序号(是完全备份目录的结束时间序列号作为起始)
to_lsn = 3739306      //结束时间序号
last_lsn = 3739315
compact = 0
recover_binlog_info = 0

步骤3:在目标服务上进行恢复数据

① 在目标服务器上删除原有日志

[root@node10 ~]# rm -rf /root/pbackup/

② 将日志拷贝到目标服务器

[root@localhost ~]# scp -r /pbackup/ root@192.168.2.10:/root/
[root@node10 ~]# ls /root/pbackup/
full20210609  fullbackup  incr20210609

③ 准备恢复数据(完全备份目录)【--apply-log --redo-only 】

[root@node10 ~]# innobackupex --apply-log --redo-only /root/pbackup/full20210609/
[root@node10 ~]# cat /root/pbackup/full20210609/xtrabackup_checkpoints
backup_type = log-applied
from_lsn = 0
to_lsn = 3738996
last_lsn = 3739005
compact = 0
recover_binlog_info = 0

④ 合并日志(完全备份目录+增量备份目录)【--apply-log --redo-only --incremental-dir=】

[root@node10 ~]# innobackupex --apply-log --redo-only /root/pbackup/full20210609/ --incremental-dir=/root/pbackup/incr20210609/
[root@node10 ~]# cat /root/pbackup/full20210609/xtrabackup_checkpoints
backup_type = log-applied
from_lsn = 0
to_lsn = 3739306    //结束时间序号(是增量备份目录的结束时间序列号)
last_lsn = 3739315
compact = 0
recover_binlog_info = 0

⑤ 停止目标服务器mysqld服务

[root@node10 ~]# systemctl stop mysqld

⑥ 清空数据库目录下的所有文件

[root@node10 ~]# rm -rf /var/lib/mysql/*

⑦ 恢复数据【--copy-back】

[root@node10 ~]# innobackupex --copy-back /root/pbackup/full20210609/

⑧ 修改属主属组

[root@node10 ~]# chown -R mysql:mysql /var/lib/mysql

⑨ 启动目标服务器mysqld服务

[root@node10 ~]# systemctl start mysqld

验证,查看增量部分的数据

[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn
mysql> use nsd2021;
mysql> select * from departments;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|      31 | market1   |
|      32 | market2   |
|      33 | market3   |
+---------+-----------+
29 rows in set (0.00 sec)

增量备份示例2:重复增量备份

步骤1:源服务器再次增加数据

mysql> insert into departments(dept_name) values('sales1'),('sales2'),('sales3');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> select * from departments;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|      34 | sales1    |
|      35 | sales2    |
|      36 | sales3    |
+---------+-----------+
32 rows in set (0.00 sec)

步骤2:源服务器增量备份

--incremental-basedir—> incr20210609,以上一次备份为基础

[root@localhost ~]# innobackupex -uroot -pNSD2021@tedu.cn --incremental /pbackup/incr20210609-2 --incremental-basedir=/pbackup/incr20210609/ --no-timestamp

# 将日志拷贝到目标服务器

[root@localhost ~]# scp -r /pbackup/incr20210609-2/ root@192.168.2.10:/root/pbackup/

步骤3:在目标服务上进行恢复数据

[root@node10 ~]# ls /root/pbackup/
full20210609  fullbackup  incr20210609  incr20210609-2

① 准备恢复数据(上一次合并后的完全备份目录)【--apply-log --redo-only 】

[root@node10 ~]# innobackupex --apply-log --redo-only /root/pbackup/full20210609/
[root@node10 ~]# cat /root/pbackup/full20210609/xtrabackup_checkpoints
backup_type = log-applied
from_lsn = 0
to_lsn = 3739306    //结束时间序号(是第一次合并增量备份目录后的结束时间序列号)
last_lsn = 3739315
compact = 0
recover_binlog_info = 0

② 合并日志(【完全备份目录+增量备份目录】+增量备份目录)

[root@node10 ~]# innobackupex --apply-log --redo-only /root/pbackup/full20210609/ --incremental-dir=/root/pbackup/incr20210609-2/
[root@node10 ~]# cat /root/pbackup/full20210609/xtrabackup_checkpoints
backup_type = log-applied
from_lsn = 0
to_lsn = 3739597   //结束时间序号(是第二次合并增量备份目录后的结束时间序列号)
last_lsn = 3739606
compact = 0
recover_binlog_info = 0

③ 停止目标服务器mysqld服务

[root@node10 ~]# systemctl stop mysqld

④ 删除工作目录

[root@node10 ~]# rm -rf /var/lib/mysql/*

⑤ 恢复数据

[root@node10 ~]# innobackupex --copy-back /root/pbackup/full20210609/

⑥ 修改属主属组

[root@node10 ~]# chown -R mysql:mysql /var/lib/mysql

⑦ 启动目标服务器mysqld服务

[root@node10 ~]# systemctl start mysqld

验证,查看增量的数据

[root@node10 ~]# mysql -uroot -pNSD2021@tedu.cn
Mysql> use nsd2021;
mysql> select * from departments;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|      34 | sales1    |
|      35 | sales2    |
|      36 | sales3    |
+---------+-----------+
32 rows in set (0.00 sec)

思维导图1:

思维导图2:

小结:

本篇章节为【第四阶段】RDBMS1-DAY6 的学习笔记,这篇笔记可以初步了解到 MySQL索引(索引分类、创建索引)、用户及授权(创建用户并授权、查看授权、撤销授权、授权库mysql)、root密码恢复、备份、使用mysqldump进行逻辑备份、Percona。


Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小安运维日记

Hey~ 感谢您的充电支持!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值