表迁移

Posted wxzhe

tags:

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

在做报表的时候,通常需要把额外几张服务器中的表导入到一个数据库中,这时候就需要表迁移!

  • 利用mysqldump方式导入表
  • 使用INNODB表空间的方式迁移表
  • 使用select ...into file的方式迁移表

mysqldump方式导入表

这种方式适合用于表数据不是太大时候,这是一种逻辑导入与导出,导出的文件时sql语句,然后把导出的sql语句在另一台服务器上执行即可!

1:先备份要导出的那个表

#备份出需要迁移的表 
mysqldump -utest -p123456 --single-transaction fi_repayplan fi_tdaymoney > `date +%F`.sql

[[email protected] ~]# ll -h 2018-12-04.sql #这个文件总共103M
-rw-r--r-- 1 root root 103M Dec  4 15:58 2018-12-04.sq

2:把备份文件考到另一台服务器上恢复

[[email protected] ~]# mysql -utest -p123456 mytest < 2018-12-04.sql

如果这里没有报错就可以恢复了,可以进入数据库中,查看一行表的行数,对比确认一下!

使用INNODB表空间的方式迁移表

这种方式的迁移数据,属于物理迁移,适合数据量比较大的表!

第一种:锁表迁移

首先创建一个表,插入一些数据!

CREATE TABLE `tb1` (
  `id` int(10) DEFAULT NULL,
  `content` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

##写一个存储过程向表中插入数据
CREATE PROCEDURE insert_data(count int UNSIGNED)
BEGIN
declare s int UNSIGNED DEFAULT 1;
DECLARE c char(90) DEFAULT REPEAT("a",90);
START TRANSACTION;
WHILE s <= count DO
INSERT INTO tb1 SELECT s,c;
set s = s +1;
END WHILE;
COMMIT;
END;

##调用存储过程
call insert_data(10000000);

#表空间大小
[[email protected] mydb]# ll -h tb1.*
-rw-rw---- 1 mysql mysql  760 Dec  5 08:00 tb1.frm
-rw-rw---- 1 mysql mysql 884M Dec  5 08:01 tb1.ibd
[[email protected] mydb]#

我们把test3上的tb1表迁移到test2上面!

首先在test3上做如下操作:

MariaDB [mydb]> flush table tb1 for export;
Query OK, 0 rows affected (0.00 sec)
#这条语句会强制进行fsync操作,会把当前的表加上一个read lock!这时候表不能写入数据,只能读数据,在对应目录下面生成.cfg文件!
#需要注意当前的会话不能关闭,否则.cfg文件会自动消失!.cfg文件存储的是表的一些元信息

[[email protected] mydb]# ll tb1.*
-rw-rw---- 1 mysql mysql       417 Dec  5 08:05 tb1.cfg
-rw-rw---- 1 mysql mysql       760 Dec  5 08:00 tb1.frm
-rw-rw---- 1 mysql mysql 926941184 Dec  5 08:01 tb1.ibd
[[email protected] mydb]# strings tb1.cfg #.cfg文件的内容
test3
    mydb/tb1
content
DB_ROW_ID
DB_TRX_ID
DB_ROLL_PTR
GEN_CLUST_INDEX
DB_ROW_ID
DB_TRX_ID
DB_ROLL_PTR
content

在test2上操作:

第一步:把test3上tb1的建表语句在test2上面执行,【建表语句一定不要错,否则会报1808 schema 不匹配错误】
MariaDB [mytest]>  CREATE TABLE `tb1` (
 `id` int(10) DEFAULT NULL,
 `content` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.02 sec)

第二步:删除新建表tb1的表空间
MariaDB [mytest]> alter table tb1 discard tablespace;
Query OK, 0 rows affected (0.02 sec)

这条语句会删除表的ibd文件,慎重执行
第三:拷贝表数据文件
把test3上的tb1.ibd文化和tb1.cfg文件拷贝到test2的对应表文件目录下面
[[email protected] mydb]# scp tb1.cfg tb1.ibd 10.0.102.204:/data/mariadb/mytest
tb1.cfg                                                                                                                                                   100%  417   698.3KB/s   00:00    
tb1.ibd                                                                                                                                                   100%  884MB  50.6MB/s   00:17 
#第四步,修改文件属主和属组
[[email protected] mytest]# chown -R mysql:mysql tb1.*
#第五步:导入表空间文件
MariaDB [mytest]> alter table tb1 import tablespace;
Query OK, 0 rows affected (10.49 sec)

最后解除test3上对表tb1加的读锁!

MariaDB [mydb]> unlock tables;
Query OK, 0 rows affected (0.00 sec)

第二种:不锁表迁移

上面的方法我们对tb1加上了读锁,在线上环境中,对一整张表加上读锁的代价是有点大的,因此我们取巧,使用不锁表迁移!

我们知道innobackupex可以在线备份,因此我们可以先把要迁移的表,备份出来,然后再导入表结构文件和元数据文件!

首先备份要迁移的表:

[[email protected] ~]# innobackupex --user=test --password=123456 --include="mydb.tb1" --no-timestamp tb1.sql

#执行apply-log 操作
[[email protected] ~]# innobackupex --apply-log --export tb1.sql/         【这一步操作可以不执行的,直接拷贝对应表的ibd文件和frm文件也是可以的】
[[email protected] ~]# cd tb1.sql/mydb/
[[email protected] mydb]# ll                   #这里的文件多了两个,
total 905244
-rw-r--r-- 1 root root       428 Dec  5 08:25 tb1.cfg
-rw-r----- 1 root root     16384 Dec  5 08:25 tb1.exp
-rw-r----- 1 root root       760 Dec  5 08:25 tb1.frm
-rw-r----- 1 root root 926941184 Dec  5 08:25 tb1.ibd

在test2上执行tb1的建表语句,然后discard掉表空间文件:过程和上面的是一样的,我们直接执行拷贝文件这一步!

[[email protected] mydb]# pwd
/root/tb1.sql/mydb
[[email protected] mydb]# scp tb1.cfg tb1.ibd 10.0.102.204:/data/mariadb/mytest/
#若是在上面没有执行--apply-log哪一步,就不会出现.cfg文化和.exp文件;再拷贝时,可以直接拷贝tb1.frm文化和tb1.ibd文件,后面的操作是一样的!
#文件拷贝成功之后,修改属主,属组,然后导入表空间! MariaDB [mytest]> alter table tb1 import tablespace;
Query OK, 0 rows affected (10.57 sec) #这个时间是10.57秒

这两种方法的本质是一样的,只不过不锁表迁移,只是把要迁移的数据备份了出来,然后对备份的数据进行操作而已!

第三种:使用select ...into file的方式

这种方式属于逻辑迁移的方式,本质和第一种mydump是一样的,只是这样操作会相对于mydump会快点!

把数据导入到文件中:

MariaDB [mydb]> system mkdir /data/tb1;
MariaDB [mydb]> system chown -R mysql:mysql /data/tb1;
#文件的属主与属组需要改为mysql,否则没有写入权限
MariaDB [mydb]> select * from tb1 into outfile "/data/tb1/tb.txt";
Query OK, 6100000 rows affected (8.83 sec)

导入建表语句:

[[email protected] mydb]# mysqldump -utest -p123456 -d mydb tb1 | mysql -utest -p123456 -h10.0.102.204 mytest

-d: 只导出表结构不导表数据
#当数据量少的时候,我们可以直接使用这条命令完成表的迁移

然后拷贝上面导出的表文件,并且导入!

[[email protected] mydb]# scp /data/tb1/tb.txt 10.0.102.204:/data
tb.txt                                                                                                                                                    100%  573MB  40.8MB/s   00:14    
[[email protected] mydb]# 

#在test2上面导入表数据文件
MariaDB [mytest]> load data infile "/data/tb.txt" into table tb1;
Query OK, 6100000 rows affected (1 min 2.29 sec)              #这里的时候是62秒,物理迁移导入时10秒钟,时间相差6倍    
Records: 6100000  Deleted: 0  Skipped: 0  Warnings: 0

MariaDB [mytest]>

 




































以上是关于表迁移的主要内容,如果未能解决你的问题,请参考以下文章

discuz X3.1 关于分表 和 分表数据迁移

迁移到 AndroidX 后,findFragmentById 为片段返回 null

将数据从底部工作表对话框片段传递到片段

Android NavHostFragment(片段)膨胀失败,ViewBinding(使用导航组件)

从底部工作表对话框片段中获取价值

使用绑定从片段访问父活动的 UI 元素