运维开发宝典028-MySQL04数据库热备



大家好,我是云计算磊哥,从业20年的IT老鸟。运维培训15年,总结了一套从入门到精通的全运维开发宝典手册。准备用300天时间写一套博文,手把手从安装软件讲起,从行业到产品,从过去到未来,从理论到操作,从视频到文档工具,一站式。从零基础入门到20k运维开发工程师岗位诸多就业问题。多方位全方面的给你讲清楚云计算这个行业该如何做。关注我。后续AI大模型开发课程更精彩。


INDEX
1 索引简介

​ 索引在MySQL中也叫做"键",是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提高好几个数量级。索引相当于字典的音序表,如果要查某个字,如果不使用音序表,则需要从几百页中逐页去查。

2 索引的分类
  • 普通索引:加速查询,生成目录,占用空间,非where列不建议使用索引
  • 唯一索引:unique 唯一索引,可以为空
  • 全文索引:文章索引及其有效
  • 单列索引:同普通索引
  • 多列索引:单列的一种形式
  • 空间索引:适用于空间数据(略)
3 索引测试实验

准备素材

复制代码
mysql> create database school;

mysql> create table school.t2(id int,name varchar(30));
Query OK, 0 rows affected (1.33 sec)

通过存储过程,循环输入海量数据

复制代码
mysql> delimiter $$
mysql> use school

mysql> create procedure autoinsert1()
BEGIN
declare i int default 1;
while(i<20000)do
insert into school.t2 values(i,'ccc');
set i=i+1;
end     while;
END$$

mysql> delimiter ;

mysql> call autoinsert1();

未创建索引,测试查询过程

复制代码
mysql> explain select * from school.t2 where id=20000;
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | t2    | ALL  | NULL          | NULL | NULL    | NULL | 44848 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
1 row in set (0.00 sec)

创建索引

复制代码
create index index_id on school.t2(id);

已创建索引,测试查询过程

复制代码
 explain select * from school.t2 where id=20000;

创建索引后,实时查询。观察用时

复制代码
mysql>  select * from school.t2 where id=20000;
+-------+------+
| id    | name |
+-------+------+
| 20000 | ccc  |
+-------+------+
1 row in set (0.00 sec)
4 创建索引语法
复制代码
创建表时,同时创建索引
CREATE TABLE department10 (
	dept_id INT,
	dept_name VARCHAR(30) ,
	comment VARCHAR(50),
	INDEX index_dept_name (dept_name)
);
	index_dept_name 索引名称可以省略
CREATE TABLE department11 (
	dept_id INT,
	dept_name VARCHAR(30) ,
	comment VARCHAR(50),
	UNIQUE INDEX index_dept_name (dept_name)
);
CREATE TABLE department12 (
	dept_id INT,
	dept_name VARCHAR(30) ,
	comment VARCHAR(50),
	log text,
	FULLTEXT INDEX index_log (log)
);
CREATE TABLE department13 (
	dept_id INT,
	dept_name VARCHAR(30) ,
	comment VARCHAR(50),
	INDEX index_dept_name_comment (dept_name, comment)
);

CREATE在已存在的表上创建索引
CREATE INDEX  index_dept_name   ON   department    (dept_name);
CREATE UNIQUE INDEX index_dept_name ON department (dept_name);
CREATE FULLTEXT INDEX index_dept_name ON department (dept_name);
CREATE INDEX index_dept_name_ comment ON department (dept_name, comment);

ALTER TABLE在已存在的表上创建索引
ALTER TABLE    department   ADD INDEX   index_dept_name    (dept_name);
ALTER TABLE department ADD UNIQUE INDEX index_dept_name (dept_name);
ALTER TABLE department ADD FULLTEXT INDEX index_dept_name (dept_name);
ALTER TABLE department ADD INDEX index_dept_name_comment (dept_name,comment);
5 管理索引
复制代码
SHOW CRETAE TABLE 表名\G
EXPLAIN SELECT * FROM department WHERE dept_name='hr';请关注查询记录的数量
show create table employee6;
DROP INDEX 索引名 ON 表名;
安全机制
1 权限级别
  • Global level
  • Database level
  • Table level
  • Column level
  • procs level
  • proxies level
2 查看权限记录表

Global level

复制代码
select * from mysql.user\G; 

Database level

复制代码
select * from mysql.db\G;

Table level

复制代码
select * from mysql.tables_priv\G;

Column level

复制代码
select * from mysql.columns_priv\G;
3 mysql用户管理

3.1 创建用户

复制代码
GRANT ALL ON *.* TO 'user3'@'localhost' IDENTIFIED BY 'xulei@123456';
FLUSH PRIVILEGES;

3.2 删除用户

复制代码
DROP USER 'user1'@'localhost';

3.3 修改用户密码

复制代码
UPDATE mysql.user SET authentication_string=password('new_password')  WHERE user='root' AND host='localhost';
FLUSH PRIVILEGES;

3.4 登录和退出MySQL

复制代码
mysql -h192.168.100.10  -P 3306 -u root -p123 mysql -e 'show tables'
    -h	指定主机名                       【默认为localhost】
    -P	MySQL服务器端口              【默认3306】    大P
    -u	指定用户名                       【默认root】
    -p	指定登录密码                    【默认为空密码】
此处mysql为指定登录的数据库 
    -e	接SQL语句
4 MySQL权限原理

语法: grant 权限列表 on 库名.表名 to '用户名'@'客户端主机' identified by '密码' with option参数;

赋予权限

复制代码
grant all on *.* to admin1@'%' identified by 'xulei@13910604684';

回收权限

复制代码
    REVOKE DELETE ON *.*  FROM admin1@'%';			                            //回收部分权限
    REVOKE ALL PRIVILEGES  ON *.*  FROM admin2@'%';  		                    //回收所有权限
REVOKE ALL PRIVILEGES,GRANT OPTION  ON *.* FROM 'admin2'@'%'; 
物理备份
1 案例1 tar备份数据库

备份的过程

复制代码
1停止数据库
systemctl stop mysqld
mkdir /backup
2. tar备份数据
 tar -cf /backup/`date +%F`-mysql-all.tar /var/lib/mysql
3. 启动数据库
systemctl start mysqld

还原的过程

复制代码
systemctl stop mysqld
rm -rf /var/lib/mysql/*
tar -xf /backup/2016-12-07-mysql-all.tar -C /
systemctl start mysqld
2 案例2 Lvm快照实现物理备份 + binlog

将已运行mysql迁移到LVM卷

复制代码
1. 准备lvm及文件系统
lvcreate -n lv-mysql -L 2G datavg
mkfs.xfs /dev/datavg/lv-mysql
2. 将数据迁移到LVM
systemctl stop mysqld
mount /dev/datavg/lv-mysql /mnt/ 
cp -a /var/lib/mysql/* /mnt
umount /mnt/
chown -R mysql.mysql /var/lib/mysql
systemctl start mysqld

LVM快照备份流程

复制代码
mysql> flush tables with read lock;
lvcreate -L 500M -s -n lv-mysql-snap /dev/datavg/lv-mysql
mysql -p'xulei@123'  -e 'show master status' > /backup/`date +%F`_position.txt
mysql> unlock tables;
mount -o nouuid /dev/datavg/lv-mysql-snap /mnt/
cd /mnt/
tar -cf /backup/`date +%F`-mysql-all.tar ./*
cd; umount /mnt/
 lvremove -f   /dev/datavg/lv-mysql-snap

LVM快照恢复流程

复制代码
systemctl stop mysqld
rm -rf  /var/lib/mysql/* 
tar -xf /backup/2016-12-07-mysql-all.tar -C /var/lib/mysql/
chown -R  mysqlmysql  /var/lib/mysql/
systemctl start mysqld

总结操作思路

复制代码
1、flush table with read locak;全局读锁
2、create snapshot 创建快照,
3、show master status; show slave status; [可选]  查询二进制日志的位置,下次使用bin 作为依据。
4、unlock tables;然后释放锁。
5、Copy files from the snapshot   从快照卷,复制数据。
6、Unmount the snapshot.  卸载并删除快照。
7、Remove snapshot   
3 案例3:percona-xtrabackup 物理备份 + binlog

安装

复制代码
wget http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm 下载YUM源
yum -y install percona-release-0.1-3.noarch.rpm 安装yum源
yum -y install percona-xtrabackup-24.x86_64 安装percona
rpm -ql percona-xtrabackup-24  查询安装结果,安装文件

1-1 完全备份流程

复制代码
 mkdir /xtrabackup/full -p
	准备备份目录
innobackupex --user=root --password='xulei@123' /xtrabackup/full
	连接数据库,开始备份。
	请注意备份结果是否完成
		xtrabackup: Transaction log of lsn (74182721) to (74182730) was copied.
171127 15:04:12 completed OK!
ls /xtrabackup/full/
	查看备份目录。数据库,配置文件,日志文件
ls /xtrabackup/full/2017-08-01_00-00-02/
cat /xtrabackup/full/2017-08-01_00-00-18/xtrabackup_binlog_info 
	二进制日志位置

1-2 完全恢复流程

复制代码
systemctl stop mysqld
rm -rf /var/lib/mysql/*
rm -rf /var/log/mysqld.log 
rm -rf /var/log/mysql-slow/slow.log 
innobackupex --apply-log /xtrabackup/full/2017-08-01_00-00-18/
innobackupex --copy-back /xtrabackup/full/2017-08-01_00-00-18/
ls /var/lib/mysql
chown -R mysql.mysql /var/lib/mysql
systemctl start mysqld
mysql -uroot -p'xulei@123'

2-1 增量备份流程

复制代码
准备工作
mysql> create database testdb;
mysql> use testdb;
mysql> create table test(id int);
mysql> insert into test values (1);
mysql> select * from test;
mysql> select * from test;
+------+
| id   |
+------+
|    1 |
+------+
1 row in set (0.00 sec)
完整备份:周一
rm -rf /xtrabackup/*
date 09010000
innobackupex --user=root --password='xulei@123' /xtrabackup
ll /xtrabackup/
2017-09-01_00-00-04
增量备份:周二
date 09020000 更新时间
mysql -uroot -p'xulei@123' -e  'insert into testdb.test values (2)'
innobackupex --user=root --password='xulei@123' 
--incremental /xtrabackup/ 
--incremental-basedir=/xtrabackup/2017-09-01_00-00-04
basedir基于周一的备份。
会生成一个今天的。
ls  /xtrabackup/
2017-09-01_00-00-04  
2017-09-02_00-00-58
增量备份:周三
# date 09030000
# mysql -uroot -p'xulei@123' -e  'insert into testdb.test values (3)'
# innobackupex --user=root --password='xulei@123' 
--incremental /xtrabackup/ 
--incremental-basedir=/xtrabackup/2017-09-02_00-00-26
# ls  /xtrabackup/
2017-09-01_00-00-04  
2017-09-02_00-00-58
2017-09-03_00-00-36

2-2 增量恢复流程

复制代码
停止数据库
 	systemctl stop mysqld
清理环境
	rm -rf /var/lib/mysql/*
周一
	innobackupex --apply-log --redo-only /xtrabackup/2017-09-01_00-00-04
周二
	 innobackupex --apply-log --redo-only /xtrabackup/2017-09-01_00-00-04 
--incremental-dir=/xtrabackup/2017-09-02_00-00-26
周三
	 innobackupex --apply-log --redo-only /xtrabackup/2017-09-01_00-00-04  
--incremental-dir=/xtrabackup/2017-09-03_00-00-27
恢复
	innobackupex --copy-back /xtrabackup/2017-09-01_00-00-06  
	chown -R mysql.mysql /var/lib/mysql
	systemctl start mysqld
逻辑备份

mysqldump实现逻辑完全备份 + binlog

1 优势
  • 自动记录position位置。
  • 可用性,一致性
2 语法
复制代码
 mysqldump  -h 服务器  -u用户名  -p密码   数据库名  > 备份文件.sql

参数说明

复制代码
-A, --all-databases	所有库
school	数据库名
school stu_info t1	是指school数据库的表stu_info、t1
-B, --databases bbs test mysql	多个数据库
 --single-transaction                    #InnoDB 一致性 服务可用性
 --opt 		#同时启动各种高级选项
-R, --routines			 #备份存储过程和存储函数
 -F, --flush-logs		#备份之前刷新日志,截断日志。备份之后新binlog。
--triggers		#备份触发器
--master-data=1|2	#该选项将会记录binlog的日志位置与文件名并追加到文件中,或添加注释
3 备份实战
3.1 准备库1
复制代码
mysql> select * from testdb1.t1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3.2 执行备份
复制代码
[root@localhost ~]# mysqldump -p'xulei@123' \
--all-databases --single-transaction \
 --master-data=2 \
--flush-logs \
>  /backup/`date +%F-%H`-mysql-all.sql
3.3 观察备份细节
复制代码
vim /backup/2016-11-25-14-mysql-all.sql
观察各种锁机制,用来保证数据一致性
LOCK TABLES `user` WRITE;
二进制日志截断位置。第22行
22 CHANGE MASTER TO MASTER_LOG_FILE='localhost-bin.000004', MASTER_LOG_POS=154;
3.4 备份后的,数据变更行为
复制代码
在testdb2.t2 中插入数据1;
创testdb3库
切断二进制日志(重启数据库)
在testdb2.t2 中插入数据2;
删testdb3库
在testdb2.t2 中插入数据3;
4 恢复实战
4.1 备份日志文件
复制代码
cp /var/lib/mysql/*bin* ~
4.2. 停止数据库
复制代码
systemctl stop mysqld
4.3. 清理环境
复制代码
rm -rf /var/lib/mysql/*
4.4.启动数据库
复制代码
systemctl start mysqld
grep 'password' /var/log/mysqld.log
找密码,再改密码略。
4.5 .mysql恢复数据
复制代码
 mysql -p'xulei@1234' < /backup/2016-12-08-04-mysql-all.sql
 mysql -p'xulei@1234' -e 'flush privileges'

登陆并验证数据恢复结果。请思考恢复的数据库有几个?

答:1个,因为这是备份点之前的数据。而备份点到灾难点的数据如何恢复呢?

4.6 二进制日志恢复

观察二进制截取记录

复制代码
vim /backup/2016-11-25-14-mysql-all.sql
CHANGE MASTER TO MASTER_LOG_FILE='localhost-bin.0000010', MASTER_LOG_POS=154;

恢复

复制代码
mysqlbinlog localhost-bin.000002 localhost-bin.000003
 --start-position=154  | mysql -p'xulei@123'

注意后续有多少日志,要跟多少日志名字。

4.7.观察数据

数据恢复完成

5 记录的导出和导入

SELECT... INTO OUTFILE 导出文本文件

复制代码
mysql> SELECT * FROM testdb1.t1 INTO OUTFILE '/backup/testdb1.t1.txt';

mysql 命令导出文本文件

复制代码
mysql -uroot -p'xulei@123' -e 'select * from testdb1.t1' > /backup/testdb1.t2.txt
mysql -u root -p'xulei@123' --xml -e 'select * from testdb1.t1' > /backup/testdb1.t3.txt
mysql -u root -p'xulei@123' --html -e 'select * from testdb1.t1' > /backup/index.html

LOAD DATA INFILE 导入文本文件

复制代码
注意目录权限
vim /etc/my.cnf
secure-file-priv=/backup
	mysql不信任该目录
chown mysql.mysql /backup
	mysql用户没有权限


删除表的内容
表的导出和导入只备份表记录,不会备分表结构。因此需要通过mysqldump备份表结构,恢复时先恢复表结构,再导入数据。
DELETE FROM testdb1.t1;

读取记录备份文件
LOAD DATA INFILE '/backup/testdb1.t1.txt'
 INTO TABLE testdb1.t1;
 
 输入到表中。
  INTO TABLE testdb1.t1;
  select * from testdb1.t1;

mysql阶段

csdn配套视频 https://edu.csdn.net/course/detail/40864

相关推荐
五阿哥永琪2 小时前
正则表达式
数据库·mysql·正则表达式
LaughingZhu2 小时前
Product Hunt 每日热榜 | 2026-06-13
数据库·mysql
c238562 小时前
GDB 进程概念详解(下篇)—— 多进程与进阶调试能力
linux·服务器·数据库
charlee442 小时前
Unity在安卓端如何调试输出信息
android·unity·adb·游戏引擎·真机调试
tiancaijiben2 小时前
阿里云云备份(Cloud Backup)全量对接与使用指南
数据库·oracle
sulikey3 小时前
数据库中等值连接与自然连接的区别。为什么不建议使用自然连接?
数据库·sql·mysql·等值连接·自然连接
IT策士3 小时前
Redis 从入门到精通:分布式锁 —— 从 SETNX 到 Redlock
数据库·redis·分布式
云计算磊哥@3 小时前
运维开发宝典027-MySQL03数据库的增删改查
运维·数据库·运维开发
李白的天不白3 小时前
数据库的CEUD
数据库·sql·oracle