备份

MySQL服务实例运行期间,意外的停电,硬盘损坏,还有一些误操作、服务器宕机等情况。这个时候如何确保数据库能够最大程度地恢复到'正确'的状态呢?

对于数据库管理人员来说,防止数据丢失最简单的方法就是:对原始数据定期进行备份,创建数据副本。但数据与预期发生不一致情况,然后使用备份的数据恢复数据。对于MySQL来说,创建数据副本的常用方法有三种

创建数据副本的方法

1、数据备份:

由MySQL日志系统前一篇博客我们知道数据库的全部数据都以文件的形式,存储在硬盘上,那我们就可以直接备份MySQL的所有数据目录下的文件就能够达到目的。因此在开启MySQL服务的时候要设计好各种数据文件以及日志文件的存放位置,以方便能够快速备份。另外备份的时候最好能够备份到其他的机器上。

2、使用二进制日志:

上面的【数据备份方法】属于物理备份,粒度较粗,不能实现更细粒度的数据恢复,特别是对于更新较为频繁的系统。二进制日志记录了数据库所有的更新操作,数据丢失时,可以通过完全备份进行二进制日志的重做,可以完成基于时间点或者操作点的恢复,继而实现数据库更细粒度的恢复。

3、数据库复制:

数据库的复制实际上是通过二进制日志预防数据丢失的,数据复制可以实现数据库的异地备份和恢复。

逻辑备份与物理备份

按照备份后产生的副本文件是否可以编辑,可以将MySQL的备份方法分为逻辑备份和物理备份

1、逻辑备份:

使用逻辑备份是,数据库管理员通常可以直接查看和编辑副本文件中的内容。逻辑备份中产生的副本通常哟两种情况。情形一:副本是SQL文件,该SQL文件中有crete table 和大量的inert 语句。情形二、副本是指定分隔符的文件,导入数据库的时候再以指定分隔符切割数据导入即可。

2、物理备份:

物理备份产生的数据副本都是二进制文件,常常不可编辑,例如数据库的二进制日志。

冷备份、温备份、热备份

数据备份期间,按照是否需要停止MySQL服务实例,可以将MySQL的数据恢复分为:冷备份、温备份、热备份。

1、冷备份:

冷备份是指停止MySQL服务的运行后在进行数据备份,这种备份方法非常简单,但是在服务繁忙的系统中,并不允许这样做。

2、温备份: 温备份介于热备份与冷备份之间,温备份允许MySQL服务实例继续运行,备份数据期间,温备份借助读锁机制保证备份期间,没有新的数据写入。

完全备份、增量备份

按照副本文件的缺失程度可以将数据备份分为完全备份以及增量备份。

1、完全备份:

完全备份是一个完整的数据备份,仅仅依靠该副本文件就可以将数据库恢复到某个正确的状态。如果不借助热备份工具,完全备份可能需要停止MySQL服务。此时MySQL将无法提供服务,在真实的业务场景中,很少真正使用完全备份。

2、增量备份:

增量备份是指在完全备份的基础上,对更新的数据进行备份,恢复时需要借助完全备份产生的副本文件,目前,MySQL还没有提供真正的增量备份工具。数据库管理人员可以使用热备份工具模拟实现增量备份,也可以通过重新执行二进制日志中的更新语句模拟实现增量备份。

3、热备份:

热备份是指不需要停止MySQL服务实例运行,备份数据的方法。如果数据库的更新操作较为频繁,在数据备份期间,备份过的数据可能早已发生变化,因此热备份的实现方式较为复杂。

 

一、备份常用操作基本命令。

1、备份命令mysqldump格式

   格式:mysqldump -h主机名  -P端口 -u用户名 -p密码 –database 数据库名 > 文件名.sql 

首先创建一个数据库和表

mysql> create database mood;
Query OK, 1 row affected (0.00 sec)

mysql> use mood
Database changed

mysql> create table info (id int not null primary key auto_increment,name char(10) not null);
Query OK, 0 rows affected (0.03 sec)

mysql> insert into info 
    -> (name)values('zhangsan'),('lisi');
Query OK, 2 rows affected (0.03 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select *from info;
+----+----------+
| id | name     |
+----+----------+
|  1 | zhangsan |
|  2 | lisi     |
+----+----------+
2 rows in set (0.00 sec)

使用tar命令备份

[root@localhost opt]# tar jvcf /opt/mysql-.tar.xz /usr/local/mysql/data/
[root@localhost opt]# ls
allback.sql  back1.sql  mood.sql  mysql-2018-09-02.tar.xz  mysql-5.7.17  rh

备份单个MySQL数据库到opt下。(后面出现的warning是因为我把密码写在了-P后面,如果不写则进行密码交互)。

[root@localhost ~]# mysqldump -uroot -pabc123 mood > /opt/mood.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.




备份服务器上所有数据库到opt下。

[root@localhost ~]# mysqldump -uroot -pabc123 --all-databases > /opt/allback.sql mysqldump: [Warning] Using a password on the command line interface can be insecure.

 

多个数据库同时备份(备份了mood和自带的mysql两个数据库)

 


[root@localhost opt]# mysqldump -uroot -pabc123 --databases mood mysql > /opt/mood-mysql.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.

备份数据库中的表

[root@localhost opt]# mysqldump -uroot -pabc123 mood info > /opt/info.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.

备份表结构

[root@localhost opt]# mysqldump -uroot -pabc123 -d mood info > /opt/info1.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.


恢复表数据的两种办法

1再数据库中执行

mysql> use mood
Database changed

mysql> drop table info;
Query OK, 0 rows affected (0.01 sec)

mysql> show tables;
Empty set (0.01 sec)

mysql> source /opt/info.sql;
Query OK, 0 rows affected (0.00 sec)

mysql> show tables;
+----------------+
| Tables_in_mood |
+----------------+
| info           |
+----------------+
1 row in set (0.00 sec)

2直接倒回表数据

[root@localhost opt]# mysql -uroot -pabc123 mood < /opt/info.sql 
mysql: [Warning] Using a password on the command line interface can be insecure.

不进入数据库使用-e直接查看数据表

[root@localhost opt]# mysql -uroot -pabc123 -e 'use mood;show tables;select *from info;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------------+
| Tables_in_mood |
+----------------+
| info           |
+----------------+
+----+----------+
| id | name     |
+----+----------+
|  1 | zhangsan |
|  2 | lisi     |
+----+----------+

 


 

MySQL 索引

MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。

打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车。

索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索引包含多个列。

创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。

实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。

上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。

建立索引会占用磁盘空间的索引文件。

普通索引

创建索引

这是最基本的索引,它没有任何限制。它有以下几种创建方式:


CREATE INDEX indexName ON mytable(username(length));

如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length。


修改表结构(添加索引)
ALTER table tableName ADD INDEX indexName(columnName)
创建表的时候直接指定
CREATE TABLE mytable(  
 
ID INT NOT NULL,   
 
username VARCHAR(16) NOT NULL,  
 
INDEX [indexName] (username(length))  
 
);
删除索引的语法
DROP INDEX [indexName] ON mytable;

唯一索引

它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:

创建索引
CREATE UNIQUE INDEX indexName ON mytable(username(length))
修改表结构
ALTER table mytable ADD UNIQUE [indexName] (username(length))
创建表的时候直接指定
CREATE TABLE mytable(  
 
ID INT NOT NULL,   
 
username VARCHAR(16) NOT NULL,  
 
UNIQUE [indexName] (username(length))  
 
);

使用ALTER 命令添加和删除索引

有四种方式来添加数据表的索引:

  • ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。

  • ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)。

  • ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出现多次。

  • ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):该语句指定了索引为 FULLTEXT ,用于全文索引。

以下实例为在表中添加索引。

mysql> ALTER TABLE testalter_tbl ADD INDEX (c);

你还可以在 ALTER 命令中使用 DROP 子句来删除索引。尝试以下实例删除索引:

mysql> ALTER TABLE testalter_tbl DROP INDEX c;

使用 ALTER 命令添加和删除主键

主键只能作用于一个列上,添加主键索引时,你需要确保该主键默认不为空(NOT NULL)。实例如下:

mysql> ALTER TABLE testalter_tbl MODIFY i INT NOT NULL;
mysql> ALTER TABLE testalter_tbl ADD PRIMARY KEY (i);

你也可以使用 ALTER 命令删除主键:

mysql> ALTER TABLE testalter_tbl DROP PRIMARY KEY;

删除主键时只需指定PRIMARY KEY,但在删除索引时,你必须知道索引名。

显示索引信息

你可以使用 SHOW INDEX 命令来列出表中的相关的索引信息。可以通过添加 \G 来格式化输出信息。

尝试以下实例:

mysql> SHOW INDEX FROM table_name; \G
........