今天我们学习mysql数据库的恢复与备份
首先了解内连接查询的写法
创建两个表A和B
mysql> show tables;
+----------------+
| Tables_in_mydb |
+----------------+
| A |
| B |
| info |
+----------------+
3 rows in set (0.00 sec)mysql> select * from A-> ;
+-------+---------+
| name | school |
+-------+---------+
| tom | xiada |
| bob | fuda |
| gazi | beida |
| seven | qinghua |
+-------+---------+
4 rows in set (0.00 sec)mysql> select * from B;
+------+----------+
| name | job |
+------+----------+
| tom | fuwuyuan |
| bob | dianzi |
| hary | guitai |
| avy | zhujiao |
+------+----------+
4 rows in set (0.00 sec)
内连接查询两个表格中的同类项,用“,”的形式查询两张表并且用where指定需要进行满足条件的显示
mysql> select A.name as nameA, A.school, B.name as nameB, B.job from B,A where A.name=B.name;
+-------+--------+-------+----------+
| nameA | school | nameB | job |
+-------+--------+-------+----------+
| tom | xiada | tom | fuwuyuan |
| bob | fuda | bob | dianzi |
+-------+--------+-------+----------+
2 rows in set (0.00 sec)
当然也可以用A inner join B on 的形式
mysql> select A.name as nameA, A.school, B.name as nameB, B.job from A
inner join B on A.name=B.name;
+-------+--------+-------+----------+
| nameA | school | nameB | job |
+-------+--------+-------+----------+
| tom | xiada | tom | fuwuyuan |
| bob | fuda | bob | dianzi |
+-------+--------+-------+----------+
2 rows in set (0.00 sec)
外连接查询(分为左外连接和右外连接)
写左显左,写右显右
左外连接查询
mysql> select A.name as nameA, A.school, B.name as nameB, B.job from A
left join B on A.name=B.name;
+-------+---------+-------+----------+
| nameA | school | nameB | job |
+-------+---------+-------+----------+
| tom | xiada | tom | fuwuyuan |
| bob | fuda | bob | dianzi |
| gazi | beida | NULL | NULL |
| seven | qinghua | NULL | NULL |
+-------+---------+-------+----------+
4 rows in set (0.00 sec)
右外连接查询
mysql> select A.name as nameA, A.school, B.name as nameB, B.job from A
right join B on A.name=B.name;
+-------+--------+-------+----------+
| nameA | school | nameB | job |
+-------+--------+-------+----------+
| tom | xiada | tom | fuwuyuan |
| bob | fuda | bob | dianzi |
| NULL | NULL | hary | guitai |
| NULL | NULL | avy | zhujiao |
+-------+--------+-------+----------+
4 rows in set (0.00 sec)
mysql用户权限管理
MySQL数据库权限分类
在MySQL中,权限控制是通过Grant和Revoke命令来管理用户和角色的权限的。
- Alter:修改。允许用户修改数据库中的表结构。
- Alter routine:修改存储过程或函数。允许用户修改已创建的存储过程或函数。
- Create:创建。允许用户创建新的数据库对象,如表、视图、存储过程等。
- Create routine:创建存储过程或函数。允许用户创建新的存储过程或函数。
- Create temporary tables:创建临时表。允许用户创建临时表,这些表在会话结束时会自动删除。
- Create view:创建视图。允许用户创建新的视图。
- Create user:创建用户。允许用户创建新的数据库用户账户。
- Delete:删除。允许用户删除表中的数据。
- Drop:删除。允许用户删除数据库中的对象,如表、视图等。
- Event:事件。允许用户管理和修改事件调度器中的事件。
- Execute:执行。允许用户执行存储过程或函数。
- File:文件。允许用户访问数据库服务器的文件系统。
- Grant option:授予选项。允许用户将权限授予其他用户。
- Index:索引。允许用户在表上创建、修改或删除索引。
- Insert:插入。允许用户向表中插入数据。
- Lock tables:锁定表。允许用户锁定数据库中的表,以防止其他用户同时访问这些表。
- Process:进程。允许查看或杀死数据库服务器上的进程。
- Proxy:代理。允许用户作为代理登录,代表其他用户执行操作。
- References:引用。允许用户创建外键约束。
- Reload:重新加载。允许用户重新加载配置文件或刷新权限表。
- Replication client:复制客户端。允许用户从主服务器接收数据以进行复制。
- Replication slave:复制从机。允许用户作为数据复制的从服务器。
- Select:选择。允许用户查询表中的数据。
- Show databases:显示数据库。允许用户查看用的数据库列表。
- Show view:显示视图。允许用户查看数据库中的视图定义。
- Shutdown:关闭。允许用户关闭数据库服务器。
- Super:超级。允许用户所有的权限,并且可以不受限制地执行许多系统命令。
- Trigger:触发器。允许用户创建触发器,以在特定事件发生时自动执行代码。
- Create tablespace:创建表空间。允许用户创建新的表空间,用于存储数据库对象。
- Update:更新。允许用户更新表中的数据。
- Usage:使用。这个权限通常用于限制用户只能查看自己的权限,不能进行任何实际的数据库操作。
创建远程管理用户并查看其存储位置
mysql> create user mydb_user@'%' identified by '123.com';
Query OK, 0 rows affected (0.01 sec)mysql> select * from mysql.user\G;
查看用户权限
mysql> show grants for mydb_user@'%';
+---------------------------------------+
| Grants for mydb_user@% |
+---------------------------------------+
| GRANT USAGE ON *.* TO `mydb_user`@`%` |
+---------------------------------------+
1 row in set (0.01 sec)
给该用户赋权并刷新
mysql> grant all on mydb.* to mydb_user@'%';
Query OK, 0 rows affected (0.00 sec)mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
查看
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)
赋权后它既能删除自己也能创建
哪怕是赋权一个不存在的用户,赋权也能成功并且就能创建了。
mysql> drop database mydb;
Query OK, 3 rows affected (0.03 sec)
mysql> create database mydb;
Query OK, 1 row affected (0.01 sec)
mysql> grant all on mydb1.* to mydb_user@'%';
Query OK, 0 rows affected (0.01 sec)
mysql> create database mydb1;
Query OK, 1 row affected (0.00 sec)
删除用户权限
删除所有权限
mysql> revoke all on mydb1.* from mydb_user@'%';
Query OK, 0 rows affected (0.01 sec)
也可以单独移除某一权限例如:create,移除后mydb_user就没有创建权限了
mysql> revoke create on mydb.* from mydb_user@'%';
Query OK, 0 rows affected (0.00 sec)
删除账户
mysql> drop user mydb_user@'%';
Query OK, 0 rows affected (0.00 sec)
验证是否删除
mysql> select User from mysql.user\G;
*************************** 1. row ***************************
User: root
*************************** 2. row ***************************
User: mysql.infoschema
*************************** 3. row ***************************
User: mysql.session
*************************** 4. row ***************************
User: mysql.sys
*************************** 5. row ***************************
User: root
5 rows in set (0.00 sec)ERROR:
No query specified
mysql数据库备份
数据备份的重要性
备份的主要目的是灾难恢复。
在生产环境中,数据的安全性至关重要。
任何数据的丢失都可能产生严重的后果。
造成数据丢失的原因
程序错误
人为操作错误
运算错误
磁盘故障
灾难(如火灾、地震)和盗窃
例:mysqldump数据库自带的备份工具
备份需要考虑的问题
可以容忍丢失多长时间的数据;
恢复数据要在多长时间内完成;
恢复的时候是否需要持续提供服务;
恢复的对象,是整个库,多个表,还是单个库,单个表。
备份类型
1、根据是否需要数据库离线
冷备(cold backup):需要关mysql服务,读写请求均不允许状态下进行;
温备(warm backup):服务在线,但仅支持读请求,不允许写请求;
热备(hot backup):备份的同时,业务不受影响。
注意:
这种类型的备份,取决于业务的需求,而不是备份工具
MyISAM不支持热备,InnoDB支持热备,但是需要专门的工具
常用备份工具
商业工具
Navicat for MySQL(激活了才能用)
功能特点:它提供了直观的图形化界面,方便用户轻松地创建备份任务、设置备份计划以及恢复数据。支持多种备份类型,如完整备份、增量备份等,还能对备份文件进行加密和压缩,以确保数据的安全性和减小备份文件的大小。
适用场景:适用于各种规模的企业和开发团队,尤其是那些需要频繁进行数据库备份和恢复操作,且对操作的便捷性和可视化有较高要求的用户。
SQLyog Ultimate(不激活也能用)
功能特点:具有强大的备份和恢复功能,支持定时备份,可以按照设定的时间周期自动执行备份任务。同时,它还提供了数据同步功能,能够在不同的 MySQL 数据库之间进行数据同步,方便数据迁移和数据一致性维护。
适用场景:受 MySQL 开发者和数据库管理员的欢迎,常用于开发环境和生产环境中的数据库管理与备份工作,对于需要进行数据库版本控制和数据迁移的场景也非常实用。
暂时会用mysqldump和navicat就行了
2、根据要备份的数据集合的范围
完全备份:full backup,备份全部字符集(全部数据库),每次备份都会进行完全备份,会导致备份文件占用大量的磁盘空间,并且有大量的重复数据,只适合第一次备份,不常用。
差异备份: incremental backup,要先进行一次完全备份,每次差异备份都会备份上一次完全备份后的数据,可能会出现备份的重复数据,导致占用大量的磁盘空间;
增量备份:differential backup,要先执行一次完全备份,每一次增量备份的数据都是备份在上一次完全备份或者上一次增量备份后的数据,不会出现重复数据,也不会占用额外的磁盘空间
建议的恢复策略
完全+增量+二进制日志
3、根据备份数据或文件
物理备份:直接备份数据文件
优点:备份和恢复操作都比较简单,能够支持兼容的mysql版本;恢复速度快,属于文件系统级别的。
建议:不要假设备份一定可用,要测试 mysql>check tables;检测表是否可用。
逻辑备份: 备份表中的数据和代码
优点:恢复简单;备份的结果为ASCII文件,可以编辑;与存储引擎无关;可以通过网络备份和恢复;
缺点:备份或恢复都需要mysql服务器进程参与;备份结果占据更多的空间;浮点数可能会丢失精度;还原之后,缩影需要重建
常见的备份方法
1、物理冷备(完全备份)
备份时数据库处于关闭状态,直接打包数据库文件
备份速度快,恢复时也是最简单的
[root@localhost mydb]# tar zcvf mysql.tar.qz ./*
./info.ibd
[root@localhost mydb]# ls
info.ibd mysql.tar.qz
2、专用备份工具mysqldump(完全备份)或mysqlhotcopy (完全备份,逻辑备份)
mysqldump常用的逻辑备份工具 (导出为sql脚本)
mysqlhotcopy仅拥有备份MyISAM和ARCHIVE表
启用二进制日志进行增量备份 (增量备份)
进行增量备份,需要刷新二进制日志
3、第三方工具备份
免费的MySQL热备份软件Percona XtraBackup(阿里云的工具:dts,支持热迁移)
备份案例
mysqldump工具
1、完整备份
所有数据库的备份
备份
[root@localhost ~]# mysqldump -uroot -p --all-databases > all.sql
Enter password:
[root@localhost ~]# ls
all.sql anaconda-ks.cfg test.cap
查看这个文件会发现没创建一张表都要先lock锁住,锁完之后才往里插数据,数据插入完毕再解锁
[root@localhost ~]# vim all.sql
指定数据库的备份
备份
[root@localhost ~]# mysqldump -uroot -p --databases mydb > mydb.sql
Enter password:
[root@localhost ~]# ls
all.sql anaconda-ks.cfg mydb.sql test.cap
指定数据表的备份(最灵活)
备份
[root@localhost ~]# mysqldump -uroot -p mydb info > mydb-info.sql
Enter password:
[root@localhost ~]# ls
all.sql anaconda-ks.cfg mydb-info.sql mydb.sql test.cap
恢复
[root@localhost ~]# mysql -uroot -p < mydb.sql
2、增量备份
二进制备份
配置过程
既可以在/etc/my.cnf里面配置也可以在/etc/my.cnf.d/下的mysql-server.cnf文件里配置
[root@localhost mysql]# vim /etc/my.cnf
[root@localhost mysql]# cd /etc/my.cnf.d/
[root@localhost my.cnf.d]# ls
mysql-server.cnf
[root@localhost my.cnf.d]# vim mysql-server.cnf
在[mysqld]这个区块下加入以下数据,然后重启mysql
[mysqld]
log-bin=mysql-bin
binlog_format="statement"
查看日志文件内容
[root@localhost mysql]# mysqlbinlog mysql-bin.000001
二进制备份的恢复
模拟数据丢失流程
flush logs; ###刷新日志文件,产生新的日志文件
-- 创建数据表及插入数据
flush logs;
-- 执行删除操作
结合完全备份和二进制日志备份来实现数据恢复
数据恢复
基于位置
mysql> create table s(id int);
Query OK, 0 rows affected (0.03 sec)mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mydb1 |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)mysql> select * from s;
Empty set (0.00 sec)mysql> drop table s;
Query OK, 0 rows affected (0.00 sec)mysql> flush logs;
Query OK, 0 rows affected (0.02 sec)mysql> insert into infovalue(5);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '5)' at line 1
mysql> insert into info value(5);
Query OK, 1 row affected (0.00 sec)mysql> select * from info;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 5 |
+------+
4 rows in set (0.00 sec)mysql> delete from info;
Query OK, 4 rows affected (0.00 sec)mysql> select * from info;
Empty set (0.00 sec)mysql> exit
Bye
[root@localhost ~]# mysql -uroot -p mydb < mydb-info.sql
Enter password:
[root@localhost ~]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 8.0.43 Source distributionCopyright (c) 2000, 2025, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> select * from mydb.info;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
+------+
3 rows in set (0.00 sec)mysql> exit
Bye
[root@localhost ~]# mysqlbinlog --start-position=318 --stop-position=420 /var/lib/mysql/mysql-bin.000002
# The proper term is pseudo_replica_mode, but we use this compatibility alias
# to make the statement usable on server versions 8.0.24 and older.
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 157
#251012 1:33:18 server id 1 end_log_pos 126 CRC32 0xdead7c94 Start: binlog v 4, server v 8.0.43 created 251012 1:33:18
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
3pTqaA8BAAAAegAAAH4AAAABAAQAOC4wLjQzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEwANAAgAAAAABAAEAAAAYgAEGggAAAAICAgCAAAACgoKKioAEjQA
CigAAZR8rd4=
'/*!*/;
# at 318
#251012 1:34:06 server id 1 end_log_pos 420 CRC32 0x7e8ffd2d Query thread_id=10 exec_time=0 error_code=0
use `mydb`/*!*/;
SET TIMESTAMP=1760204046/*!*/;
SET @@session.pseudo_thread_id=10/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1168113696/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8mb4 *//*!*/;
SET @@session.character_set_client=255,@@session.collation_connection=255,@@session.collation_server=255/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
/*!80011 SET @@session.default_collation_for_utf8mb4=255*//*!*/;
insert into info value(5)
/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@localhost ~]# mysqlbinlog --start-position=318 --stop-position=420 /var/lib/mysql/mysql-bin.000002 | mysql -uroot -p
Enter password:
[root@localhost ~]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 8.0.43 Source distributionCopyright (c) 2000, 2025, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> select * from mydb.info;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 5 |
+------+
4 rows in set (0.00 sec)
需要查看删除后的日志文件,找到318和420两个位置日志
[root@localhost mysql]# mysqlbinlog mysql-bin.000002
还有一种是基于时间的数据备份,这里不做研究。