本章首先讲述一下数据库的导入与导出,然后再通过相应的示例讲述一下MySQL数据库的备份。当前SQL版本为:

mysql> status;
--------------
mysql  Ver 14.14 Distrib 5.7.22, for Linux (x86_64) using  EditLine wrapper

1. 数据库的导入与导出

1.1 导出数据

1) 使用SELECT … INTO OUTFILE语句导出数据

以下示例中我们将数据表course导出到/tmp/course.txt文件中:

mysql> SELECT * FROM course INTO OUTFILE '/tmp/course.txt';
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
mysql> show variables like '%secure%';
+--------------------------+-----------------------+
| Variable_name            | Value                 |
+--------------------------+-----------------------+
| require_secure_transport | OFF                   |
| secure_auth              | ON                    |
| secure_file_priv         | /var/lib/mysql-files/ |
+--------------------------+-----------------------+
3 rows in set (0.01 sec)

mysql> SELECT * FROM course INTO OUTFILE '/var/lib/mysql-files/course.txt';
Query OK, 7 rows affected (0.01 sec)


# cat /var/lib/mysql-files/course.txt 
1       MySQL从入门到精通       1001
2       爱情与婚姻      1002
3       Java从入门到放弃        1003
4       商务礼仪        1004
5       表演的艺术      1005
6       民法    1006
7       民法    1001

也可以通过命令选项设置数据输出的指定格式,以下示例为导出CSV``格式:

mysql> SELECT * FROM course INTO OUTFILE '/var/lib/mysql-files/course.txt' FIELDS TERMINATED BY ',' 
 ENCLOSED BY '"' LINES TERMINATED BY "\r\n";
Query OK, 7 rows affected (0.00 sec)

# cat /var/lib/mysql-files/course.txt 
"1","MySQL从入门到精通","1001"
"2","爱情与婚姻","1002"
"3","Java从入门到放弃","1003"
"4","商务礼仪","1004"
"5","表演的艺术","1005"
"6","民法","1006"
"7","民法","1001"

下面的例子中,生成一个文件,各值用逗号隔开。这种格式可以被许多程序使用:

mysql> SELECT id-1, stuid, coursename FROM course INTO OUTFILE '/var/lib/mysql-files/course.txt' 
    ->  FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY "\n";

# cat /var/lib/mysql-files/course.txt 
"0","1001","MySQL从入门到精通"
"1","1002","爱情与婚姻"
"2","1003","Java从入门到放弃"
"3","1004","商务礼仪"
"4","1005","表演的艺术"
"5","1006","民法"
"6","1001","民法"

SELECT ... INTO OUTFILE语句有如下属性:

  • LOAD DATA INFILESELECT ... INTO OUTFILE的逆操作,为了将一个数据库的数据写入一个文件,使用SELECT ... INTO OUTFILE,为了将文件读回数据库,使用LOAD DATA INFILE

  • SELECT ... INTO OUTFILE可以把被选择的行写入到一个文件中。该文件被创建到服务器主机上,因此你必须要有目录的写权限;

  • 输出不能是一个已经存在的文件,防止文件数据被篡改;

  • 你需要有一个登录服务器的账号来检索文件,否则SELECT ... INTO OUTFILE不会起任何作用;

  • 在UNIX中,该文件被创建后是可读的,权限由MySQL服务器所拥有。这就意味着,你虽然可以读取该文件,但无法删除该文件(除非拥有超级权限)


2)导出表作为原始数据

mysqldump是mysql用于转存数据库的实用程序。它主要产生一个SQL脚本,其中包含从头重新创建数据库所必需的命令CREATE TABLEINSERT等。使用mysqldump导出数据时可以使用--tab选项来指定导出到哪个目录(注意该目录必须是可写的)。例如:

# mysqldump -uroot -ptestAa@123 --no-create-info --tab=/var/lib/mysql-files/ test course
mysqldump: [Warning] Using a password on the command line interface can be insecure.
# ls /var/lib/mysql-files/
course.sql  course.txt

# cat /var/lib/mysql-files/course.sql
# cat /var/lib/mysql-files/course.txt
1       MySQL从入门到精通       1001
2       爱情与婚姻      1002
3       Java从入门到放弃        1003
4       商务礼仪        1004
5       表演的艺术      1005
6       民法    1006
7       民法    1001

3) 导出SQL格式数据

# mysqldump -uroot -ptestAa@123 test course > /var/lib/mysql-files/course.txt
mysqldump: [Warning] Using a password on the command line interface can be insecure.

# cat /var/lib/mysql-files/course.txt 
-- MySQL dump 10.13  Distrib 5.7.22, for Linux (x86_64)
--
-- Host: localhost    Database: test
-- ------------------------------------------------------
-- Server version       5.7.22-log

/*!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 */;

--
-- Table structure for table `course`
--

DROP TABLE IF EXISTS `course`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `course` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `coursename` varchar(128) NOT NULL,
  `stuid` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `foreign_stuid` (`stuid`),
  CONSTRAINT `course_ibfk_1` FOREIGN KEY (`stuid`) REFERENCES `student` (`stuid`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `course`
--

LOCK TABLES `course` WRITE;
/*!40000 ALTER TABLE `course` DISABLE KEYS */;
INSERT INTO `course` VALUES (1,'MySQL从入门到精通',1001),(2,'爱情与婚姻',1002),(3,'Java从入门到放弃',1003),
(4,'商务礼仪',1004),(5,'表演的艺术',1005),(6,'民法',1006),(7,'民法',1001);
/*!40000 ALTER TABLE `course` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2018-10-24 19:57:59

如果你需要备份所有的数据库,可以使用如下的命令:

mysqldump -u root -ptestAa@123 --all-databases > database_dump.txt

4) 将数据表及数据库拷贝至其他主机

如果你需要将数据拷贝至其他的MySQL服务器上,你可以在mysqldump命令中指定数据库名及数据库表(如果完整备份数据库,则不用指定表名)。

在源主机上执行以下命令,将数据备份至dump.txt文件中:

# mysqldump -uroot -ptestAa@123 database_name table_name > /var/lib/mysql-files/dump.txt

此时,如果需要将备份的数据库导入到MysQL服务器中,可以使用以下命令,使用以下命令以前你需要确认数据库已经创建:

# mysqldump -uroot -ptestAa@123 database_name < dump.txt

1.2 MySQL导入数据

1) mysql命令导入

语法格式为:

# mysql -u用户名 -p密码 < dumpfile.txt

例如:

# mysql -uroot -ptestAa@123 < dump.txt

以上命令将备份的整个数据库dump.txt导入。

2) source命令导入

source命令导入数据库需要先登录到数据库终端:

mysql> create database aaa;
mysql> use aaa;
mysql> set names utf8;             //设置编码
mysql> source /tmp/abc.sql

3) 使用LOAD DATA导入数据

MySQL中提供了LOAD DATA INFILE语句来插入数据。以下实例中将从当前目录中读取文件dump.txt,将该文件中的数据插入到当前数据库的mytbl表中。

mysql> LOAD DATA LOCAL INFILE 'dump.txt' INTO TABLE mytbl;

如果指定LOCAL关键字,则表明从客户主机上按路径读取文件;如果没有指定,则文件在服务器上按路径读取文件。可以明确的指出在LOAD DATA语句中列的分隔符行尾标记(默认是tab\n)。例如:

mysql> LOAD DATA LOCAL INFILE 'dump.txt' INTO TABLE mytbl
  -> FIELDS TERMINATED BY ':'
  -> LINES TERMINATED BY '\r\n';

LOAD DATA默认情况下是按照数据文件中列的顺序插入数据的,如果数据文件中的列与插入表中的列不一致,则需要指定列的顺序。如在数据文件中列的顺序为a,b,c,但在插入表的列顺序为b,c,a,则数据导入语法如下:

mysql> LOAD DATA LOCAL INFILE 'dump.txt' 
    -> INTO TABLE mytbl (b, c, a);

4) mysqlimport导入数据

mysqlimport客户端提供了LOAD DATA INFILE这样的SQL语句的命令行接口。mysqlimport的大多数选项直接对应于LOAD DATA INFILE子句。从文件dump.txt中将数据导入到mytbl数据表中,可以使用如下命令(这里注意文件名必须与表名相同):

# mysqlimport -u root -ptestAa@123 --local database_name mytbl.txt

mysqlimport命令可以指定选项来设置相应的格式:

# mysqlimport -u root -ptestAa@123 --local --fields-terminated-by=":" \
   --lines-terminated-by="\r\n"  database_name mytbl.txt

mysqlimport语句中使用--columns选项来设置列的顺序:

# mysqlimport -u root -ptestAa@123 --local --columns=b,c,a \
    database_name mytbl.txt

下面列出mysqlimport常用的一些选项:

  • --delete-d: 新数据导入数据表中之前删除数据表中额所有信息;

  • --force-f: 不管是否遇到错误,mysqlimport将强制继续插入数据

  • --ignore-i: mysqlimport跳过或忽略那些有相同唯一关键字的行,导入文件中的数据将被忽略

  • --lock-tables-l: 数据被插入之前锁住表,这样就防止了你在更新数据库时由于用户的查询与更新产生干扰;

  • --replace-r: 这个选项与--ignore选项相反。此选项将替代表中有相同唯一关键字的记录;

  • --fields-enclosed-by=char: 指定文本文件中数据的记录以什么括起的,很多情况下数据以双引号括起。默认情况下数据是没有被字符括起的。

  • --fields-terminated-by=char: 指定各个数据的值之间的分隔符。默认的分隔符是tab键值

  • --line-terminated-by=str: 此选项指定文本文件中行与行之间的分割字符串。默认情况下,mysqlimport以\n作为行分隔符。

2. MySQL表锁以及FLUSH TABLES操作

1) 创建测试表

如下我们创建测试表t1t2:

use test;

DROP TABLE if EXISTS `t1`;

CREATE TABLE `t1` (
  `i` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`i`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO t1(i) VALUES(100);


DROP TABLE if EXISTS `t2`;
CREATE TABLE `t2` (
  `i` int(255) NOT NULL,
  PRIMARY KEY (`i`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO t2(i) VALUES(1000);

执行以下语句进行导入:

# mysql -uroot -ptestAa@123 < ./test.sql 
mysql: [Warning] Using a password on the command line interface can be insecure.

2) 测试读锁

Session 1:

mysql> lock table t1 read;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1 limit 1;
+-----+
| i   |
+-----+
| 100 |
+-----+
1 row in set (0.00 sec)


mysql> INSERT INTO t1(i) VALUES(101);
ERROR 1099 (HY000): Table 't1' was locked with a READ lock and can't be updated

mysql> UPDATE t1 SET i=101 where i=100;
ERROR 1099 (HY000): Table 't1' was locked with a READ lock and can't be updated

由上面可见,对于加了读锁的表,在执行加读锁的session中可进行读操作,但不能进行插入与更新,当然也不能进行删除。下面再对t2进行操作:

mysql> select * from t2 limit 1;
ERROR 1100 (HY000): Table 't2' was not locked with LOCK TABLES
mysql> INSERT INTO t2(i) VALUES(1001);
ERROR 1100 (HY000): Table 't2' was not locked with LOCK TABLES
mysql> UPDATE t2 SET i=1001 where i=1000;
ERROR 1100 (HY000): Table 't2' was not locked with LOCK TABLES

从上面可知,对于没有加锁的表,不能在执行加锁的session中对表进行访问(包括增删查改)。


Session 2:

mysql> SELECT * FROM t1 LIMIT 1;
+-----+
| i   |
+-----+
| 100 |
+-----+
1 row in set (0.00 sec)

mysql> SELECT * FROM t2 LIMIT 1;
+------+
| i    |
+------+
| 1000 |
+------+
1 row in set (0.00 sec)

mysql> INSERT INTO t2(i) VALUES(1001);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO t1(i) VALUES(101);
//卡死于此

由上面可见,加了读锁的表,在不同session中不可以进行插入操作(更新和删除同理)。但是可以对任一的表进行读取。


经实验验:

  • 如果我们执行exit退出session1,那么上面卡死在session2中插入就会马上被执行。

  • 我们在session1中执行unlock table,那么上面卡死在session2中的插入也会马上执行

3) 测试写锁

下面我们再来测试一下写锁(记得先在session1解锁刚刚被加锁的表).

Session 1:

mysql> lock table t1 write;
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO t1(i) VALUES(102);
Query OK, 1 row affected (0.01 sec)

mysql> SELECT * FROM t1 LIMIT 3;
+-----+
| i   |
+-----+
| 100 |
| 101 |
| 102 |
+-----+
3 rows in set (0.00 sec)

mysql> SELECT * FROM t2 LIMIT 3;
ERROR 1100 (HY000): Table 't2' was not locked with LOCK TABLES

mysql> UPDATE t1 SET i=103 WHERE i=102;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> DELETE FROM t1 WHERE i=103;
Query OK, 1 row affected (0.01 sec)

Session 2:

mysql> select * from t2 limit 3;
+------+
| i    |
+------+
| 1000 |
| 1001 |
+------+
2 rows in set (0.01 sec)

mysql> select * from t1 limit 3;
//卡死于此

从上面可知,若session中对表加了写锁,则同一session中对该表可以进行增删查改操作。但其他session中对该表的读取和修改都会被阻塞,直至表锁被释放。

4) 在未执行完的query上加锁

接下来,我们了解下加锁前表上有尚未执行完成的query时会怎样?

Session 1(记得先解锁刚刚被加锁的表):

mysql> select i,sleep(60) from t1 limit 1;
+-----+-----------+
| i   | sleep(60) |
+-----+-----------+
| 100 |         0 |
+-----+-----------+
1 row in set (1 min 7.08 sec)

Session 2:

mysql> lock table t1 read;
Query OK, 0 rows affected (0.00 sec)

mysql> unlock table;
Query OK, 0 rows affected (0.00 sec)

mysql> lock table t1 write;
Query OK, 0 rows affected (52.75 sec)

可见,表上有尚未完成的查询操作时可以加读锁,但加写锁会阻塞。


Session 1:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO t1(i) VALUES(105);
Query OK, 1 row affected (0.00 sec)

mysql> commit;							//等待session2执行获取读锁再提交
Query OK, 0 rows affected (0.00 sec)

Session 2:

mysql> lock table t1 read;
Query OK, 0 rows affected (23.39 sec)

上面我们看到,表上有尚未提交的事务,获取读锁会阻塞。

5) FLUSH TABLES与锁

接下来,来了解下FLUSH TABLES时表上有尚未执行完成的查询会怎样?

Session 1:

mysql> select i,sleep(60) from t1 limit 1;

Session 2:

mysql> flush tables t1;

可见,由于将要被flush的表上有查询尚未完成,因此flush tables操作被阻塞,直至所有表上的操作完成,flush tables操作才得以完成。

Session 3:

mysql> select * from t1 limit 1;

由于flush tables被阻塞,导致后续其他session中对该表的查询也会被阻塞。

Session 4:

mysql> use information_schema;
Database changed
mysql> select * from processlist where db='test';
+----+------+-----------+------+---------+------+-------------------------+------------------------------------+
| ID | USER | HOST      | DB   | COMMAND | TIME | STATE                   | INFO                               |
+----+------+-----------+------+---------+------+-------------------------+------------------------------------+
| 22 | root | localhost | test | Query   |   17 | Waiting for table flush | select * from t1 limit 1           |
| 14 | root | localhost | test | Query   |   21 | Waiting for table flush | flush tables t1                    |
| 19 | root | localhost | test | Query   |   24 | User sleep              | select i,sleep(60) from t1 limit 1 |
+----+------+-----------+------+---------+------+-------------------------+------------------------------------+
3 rows in set (0.01 sec)

在另外一个session中,通过执行上面的查询(或SHOW PROCESSLIST)我们可以看到线程的状态。直至ID为19的线程执行完了SQL查询之后,flush tables动作才得以完成。继而后续的select操作才顺利完成。


从上面Session 1/2/3/4可见,执行flush tables操作或者隐含包含flush tables的操作时要小心谨慎。在上面所有步骤都执行完成之后,我们看到:

mysql> select * from processlist where db='test';
+----+------+-----------+------+---------+------+-------+------+
| ID | USER | HOST      | DB   | COMMAND | TIME | STATE | INFO |
+----+------+-----------+------+---------+------+-------+------+
| 22 | root | localhost | test | Sleep   |  113 |       | NULL |
| 14 | root | localhost | test | Sleep   |  117 |       | NULL |
| 19 | root | localhost | test | Sleep   |  120 |       | NULL |
+----+------+-----------+------+---------+------+-------+------+

3. MySQL binlog基本配置与格式设定

我们在前面已经较为详细的介绍了MySQL binlog的三种格式:statement-based logrow-based log以及mix-based log。这里我们只讲述一下binlog的基本配置与格式设定。

3.1 基本配置

mysql binlog日志格式可以在mysql的配置文件my.cnf中通过相应的属性来进行设置:

[mysqld]
# binlog的日志格式
binlog_format=MIXED

# 指定binlog日志名(一般存放于/var/lib/mysql目录下)
log_bin=master-logbin

# binlog过期清理时间
expire_logs_days=7

# binlog每一个日志文件大小
max_binlog_size=100M

3.2 mysql binlog日志分析

当前我们MySQL的my.cnf配置如下:

[mysqld]
log-bin=master-logbin
server-id=1921681001

下面我们来简单看一下MySQL的binlog文件:

# cp /var/lib/mysql/master-logbin* ./

# mysqlbinlog ./master-logbin.000002 | more
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#181011 17:16:40 server id 1921681001  end_log_pos 123 CRC32 0x8fe8a193         Start: binlog v 4, server v 5.7.22-log created 181011 17:16:40 at startup
ROLLBACK/*!*/;
BINLOG '
+BS/Ww9phopydwAAAHsAAAAAAAQANS43LjIyLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAD4FL9bEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
AZOh6I8=
'/*!*/;
# at 123
#181011 17:16:40 server id 1921681001  end_log_pos 154 CRC32 0x975f89ab         Previous-GTIDs
# [empty]
# at 154
#181011 18:58:39 server id 1921681001  end_log_pos 219 CRC32 0x93411134         Anonymous_GTID  last_committed=0        sequence_number=1       rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 219
#181011 18:58:39 server id 1921681001  end_log_pos 399 CRC32 0x79ae24eb         Query   thread_id=2     exec_time=0     error_code=0
SET TIMESTAMP=1539255519/*!*/;
SET @@session.pseudo_thread_id=2/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1436549152/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
CREATE USER 'repl'@'%' IDENTIFIED WITH 'mysql_native_password' AS '*3FFD6E04483514E561849FD8D866C05A69EFA570'
/*!*/;
# at 399
#181011 18:58:51 server id 1921681001  end_log_pos 464 CRC32 0x8ef7b206         Anonymous_GTID  last_committed=1        sequence_number=2       rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 464
#181011 18:58:51 server id 1921681001  end_log_pos 595 CRC32 0xfc5ae713         Query   thread_id=2     exec_time=0     error_code=0
SET TIMESTAMP=1539255531/*!*/;
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'
/*!*/;
# at 595
#181011 18:59:09 server id 1921681001  end_log_pos 660 CRC32 0x2c95c9cb         Anonymous_GTID  last_committed=2        sequence_number=3       rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 660
#181011 18:59:09 server id 1921681001  end_log_pos 747 CRC32 0x7046e9a5         Query   thread_id=2     exec_time=0     error_code=0
SET TIMESTAMP=1539255549/*!*/;
SET @@session.time_zone='SYSTEM'/*!*/;
FLUSH PRIVILEGES

这里我们主要是需要注意一下server id以及end_log_pos这两个字段。

4. MySQL 数据备份实战

MySQL数据的备份类型根据自身的特性主要分为以下几组:

  • 完全备份: 是备份整个数据集(即整个数据库)

  • 部分备份: 备份部分数据集(例如,只备份一个表)。而部分备份又可以分为增量备份差异备份

增量备份: 备份自上一次备份以来(增量或完全)变化的数据。 优点是节约空间,但是还原较为麻烦

差异备份: 备份自上一次完全备份以来变化的数据。优点是还原比增量备份简单,缺点是浪费空间。

db-backup

4.1 MySQL备份数据的方式

在MySQL中我们备份数据一般有几种方式:

  • 热备份: 指的是当数据库进行备份时,数据库的读写操作均不受影响;

  • 温备份: 指的是当数据库进行备份时,数据库的读操作可以执行,但不能执行写操作;

  • 冷备份; 指的是当数据库进行备份时,数据库不能进行读、写操作,即数据库要下线;

MySQL中进行不同方式的备份还需要考虑存储引擎是否支持:

db-backup

我们在考虑数据备份时,除了数据库的运行状态之外,还需要考虑对于MySQL数据库中数据的备份方式:

  • 物理备份: 一般就是通过tarcp等命令直接打包复制数据库的数据文件以达到备份的效果;

  • 逻辑备份: 通过特定工具从数据库中导出数据并另存备份(逻辑备份会丢失数据精度)。

4.2 备份需要考虑的问题

定制备份策略前,我们还需要考虑一些问题:

我们要备份什么?

一般情况下,我们需要备份的数据分为以下几种:

  • 数据

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

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

  • 服务器配置文件


备份工具

这里我们例举出常用的几种备份工具:

mysqldump: 逻辑备份工具、适用于所有的存储引擎,支持温备份、完全备份、部分备份, 对于InnoDB存储存储引擎支持热备份;

cp、tar等归档复制工具: 物理备份工具,适用于所有的存储引擎,冷备份、完全备份、部分备份

lvm2 snapshot: 近乎热备,借助文件系统管理工具进行备份

mysqlhotcopy: 名不副实的一个工具,几乎冷备,仅支持MyISAM存储引擎

xtrabackup: 一款非常强大的InnoDB/XtraDB热备工具,支持完全备份、增量备份,由percona提供



[参看]:

  1. 学会用各种姿势备份MySQL数据库

  2. Mysql Binlog三种格式介绍及分析

  3. MySQL 表锁以及FLUSH TABLES操作

  4. SELinux and MySQL

  5. centOS 权限问题-selinux小结