MySQL数据库 快速导出和导入 迁移

Posted 我的紫霞辣辣

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL数据库 快速导出和导入 迁移相关的知识,希望对你有一定的参考价值。

数据库快速导出和导入

在公司中,如果运营或者产品手里有几千万甚至几亿条数据,要求你将其导入数据中,请问如何做?
如果你依据运营或产品交给你的数据文件直接使用insert语句,一行一行地批量插入,那至少需要1-2天时间才能插入完毕,此时我们可以用load data infile语句。 load data infile语句可以从一个文本文件中,将数据以很高的速度读入一个表中。mysql官方文档也说明了,该方法比一次性插入一条数据性能快20倍。此外,mysql也支持快速导出语句select into outfile
使用MySQL的select into outfileload data infile快速导出导入数据,12G的数据导出用时3分钟左右,导入用时4分钟左右(执行时间根据机器的配置会有所不同,不具有参考价值)。

快速导出

语法:
select ... into outfile 导出文本文件

要想导出成功,需要设置安全目录才行
vim /etc/my.cnf
[mysqld]
secure-file-priv=/tmp			# 指定导出的目录

示例:

SELECT * FROM db1.t1
INTO OUTFILE '/tmp/db1_t1.txt'
FIELDS TERMINATED BY ',' 			-- 定义字段分隔符
OPTIONALLY ENCLOSED BY '"' 			-- 定义字符串使用什么符号括起来
LINES TERMINATED BY '\\n'; 			-- 定义换行符

快速导入

语法

load data infile 导入的文本文件路径

示例

mysql> delete from t1; 
mysql> create table new_t1(表结构与文件中数据保持一致); 
mysql> LOAD DATA INFILE '/tmp/db1_t1.txt'
  	   INTO TABLE new_db.new_t1
  	   FIELDS TERMINATED BY ','
  	   OPTIONALLY ENCLOSED BY '"'
  	   LINES TERMINATED BY '\\n';

其他导出
mysql 命令导出文本文件
示例

mysql -u root -p123 -e 'select * from db1.t1' > /tmp/db1_t1.txt 
mysql -u root -p123 --xml -e 'select * from db1.t1' > /tmp/db1_t1.xml 		-- xml文件跨平台性
mysql -u root -p123 --html -e 'select * from db1.t1' > /tmp/db1_t1.html

快速导入导出案例

创建表数据

create database db01;
use db01;

create table employee(
id int not null unique auto_increment,
name varchar(20) not null,
sex enum("male","female") not null default "male",  
age int(3) unsigned not null default 28,
hire_date date not null,
post varchar(50),
post_comment varchar(100),
salary double(15,2),    
office int, 
depart_id int
);

# 插入数据
insert into employee(name,sex,age,hire_date,post,salary,office,depart_id) values
("sun","male",18,"20170301","猥琐欲为",1000.22,401,1),   
("haha","male",78,"20150302","teacher",10000.31,401,1),
("xixi","male",81,"20130305","teacher",8300.31,401,1),
("dudu","male",72,"20150312","teacher",3100,401,1);

快速导出数据

# 修改配置文件,指定导出的目录
vim /etc/my.cnf
[mysqld]
secure-file-priv=/tmp

# 重启数据库
systemctl restart mysql

# 导出数据
mysql> SELECT * FROM db01.employee
    -> INTO OUTFILE '/tmp/employee.txt'
    -> FIELDS TERMINATED BY ','
    -> OPTIONALLY ENCLOSED BY '"'
    -> LINES TERMINATED BY '\\n';
    -> LINES TERMINATED BY '\\n';
Query OK, 4 rows affected (0.00 sec)

# 查看导出的数据
cat /tmp/employee.txt 
# 1,"sun","male",18,"2017-03-01","猥琐欲为",\\N,1000.22,401,1
# 2,"haha","male",78,"2015-03-02","teacher",\\N,10000.31,401,1
# 3,"xixi","male",81,"2013-03-05","teacher",\\N,8300.31,401,1
# 4,"dudu","male",72,"2015-03-12","teacher",\\N,3100.00,401,1

快速导入数据

#  创建表,表结构与数据保持一致
create table test(
id int not null unique auto_increment,
name varchar(20) not null,
sex enum("male","female") not null default "male",  
age int(3) unsigned not null default 28,
hire_date date not null,
post varchar(50),
post_comment varchar(100),
salary double(15,2),    
office int, 
depart_id int
);

# 导人数据
mysql> LOAD DATA INFILE '/tmp/employee.txt'
    -> INTO TABLE db01.test
    -> FIELDS TERMINATED BY ','
    -> OPTIONALLY ENCLOSED BY '"'
    -> LINES TERMINATED BY '\\n';
Query OK, 4 rows affected (0.00 sec)
Records: 4  Deleted: 0  Skipped: 0  Warnings: 0

# 查看导入的新表数据
mysql> select * from db01.test;
+----+------+------+-----+------------+--------------+--------------+----------+--------+-----------+
| id | name | sex  | age | hire_date  | post         | post_comment | salary   | office | depart_id |
+----+------+------+-----+------------+--------------+--------------+----------+--------+-----------+
|  1 | sun  | male |  18 | 2017-03-01 | 猥琐欲为     | NULL         |  1000.22 |    401 |         1 |
|  2 | haha | male |  78 | 2015-03-02 | teacher      | NULL         | 10000.31 |    401 |         1 |
|  3 | xixi | male |  81 | 2013-03-05 | teacher      | NULL         |  8300.31 |    401 |         1 |
|  4 | dudu | male |  72 | 2015-03-12 | teacher      | NULL         |  3100.00 |    401 |         1 |
+----+------+------+-----+------------+--------------+--------------+----------+--------+-----------+
4 rows in set (0.00 sec)

以html格式导出数据案例

[root@db01 ~]# mysql -u root -p123 --html -e 'select * from db01.test' > /opt/db1_t1.html
Warning: Using a password on the command line interface can be insecure.
[root@db01 ~]# ls /opt
db1_t1.html

MySQL迁移数据库的方案

通常有三种方案

1、数据库直接导出,拷贝文件到新服务器,在新服务器上导入。
例如

  1. 基于mysqldump
    在源主机执行下述命令,需要目标主机开启远程账号权限
    mysqldump -h 迁移源IP -uroot -p123 --databases db01 | mysql -h 目标IP -uroot -p456

  2. 基于LOAD DATA INFILE

    优点:

    1. 会重建数据文件,减少数据文件的占用空间(释放undo段),兼容性最好,导出导入很少发生问题,需求灵活

    缺点:

    1. 导入导出都需要很长的时间,并且导出后的文件还要经过网络传输,也要占用一定的时间。

2、使用第三方迁移工具。
例如:使用【MySQL GUI Tools】中的 MySQLMigrationTool。

优点:

  1. 设置完成后传输无人值守,自动完成

缺点:

  1. 不够灵活,设置繁琐
  2. 传输时间长,
  3. 传输中网络出现异常,不能及时的被发现,并且会一直停留在数据传输的状态不能被停止,如不仔细观察不会被发现异常。
  4. 异常后很难从异常的位置继续传输。

3、数据文件和库表结构文件直接拷贝到新服务器,挂载到同样配置的MySQL服务下。
优点:

  1. 时间占用最短,文件可断点传输,操作步骤少。

缺点:

  1. 新旧服务器中MySQL版本及配置必须相同,可能引起未知问题。

假如数据库迁移是因为业务瓶颈或项目改造等需要变动数据表结构的(比如分区分表),我们便只能使用第一种方法了。

第三种方案的迁移步骤:

  1. 保证Mysql版本一致,安装配置基本一致(注意:这里的数据文件和库表结构文件都指定在同一目录 data下)

  2. 停止两边的Mysql服务(A服务器–迁移–>B服务器)

  3. 删除B服务器Mysql的data目录下所有文件

  4. 拷贝A服务器Mysql的data目录下除了ib_logfile和.err之外的文件到B服务器data下

  5. 启动B服务器的Mysql服务,检测是否发生异常

以上是关于MySQL数据库 快速导出和导入 迁移的主要内容,如果未能解决你的问题,请参考以下文章

mysql快速导出导入脚本,修改库名和所有者,实现快速迁移

mysql快速导出导入脚本,修改库名和所有者,实现快速迁移

如何导出和导入MYSQL数据(数据迁移

如何导出和导入mysql数据(数据迁移)

求助!请问mysql如何快速导入超大的sql文件?

mysql迁移之巨大数据量快速迁移方案