表迁移工具的选型-复制ibd的方法

1.1. 场景

有的时候开放人员自己的库需要帮忙导一些数据,但是表的数据量又很大。虽然说使用mysqldump或mysqlpump也可以导。但是这耗时需要比较久。

记得之前建议开放人员可以直接使用navicat去抽取测试库的数据。但是发现但遇到大表的时候,发现navicat会卡死。

1.2. 使用方法

使用拷贝*.ibd的方法。

注意:使用这种方法会锁表。因为是测试库,对服务器有一些影响还是可以接受的。

1.3. 先决条件

前提必须开启innodb_file_per_table选项,并且使用InnoDB存储引擎:

set global innodb_file_per_table = 1;

1.4. 制造大表

下面我们制造表数据,下面模拟的数据比较小,主要是为了节省时间:

USE test;
-- 创建表t1
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(
id BIGINT unsigned NOT NULL AUTO_INCREMENT,
x VARCHAR(500) NOT NULL,
y VARCHAR(500) NOT NULL,
PRIMARY KEY(id)
);

-- 创建添加数据存储过程
DROP PROCEDURE insert_batch;
DELIMITER //
CREATE PROCEDURE insert_batch()
begin
DECLARE num INT;
SET num=1;
WHILE num < 1000000 DO
IF (num%10000=0) THEN
COMMIT;
END IF;
INSERT INTO t1 VALUES(NULL, REPEAT(‘X‘, 500), REPEAT(‘Y‘, 500));
SET num=num+1;
END WHILE;
COMMIT;
END //

DELIMITER ;

-- 添加数据
CALL insert_batch();
DROP PROCEDURE insert_batch;

查看数据大小情况(磁盘上的数据大小)

ls -lh /u02/data/test/t1.*
-rw-r----- 1 mysql mysql 8.5K Mar 10 13:54 /u02/data/test/t1.frm
-rw-r----- 1 mysql mysql 1.2G Mar 10 14:20 /u02/data/test/t1.ibd

查看真实的大小情况

select count(*) from t1;
+----------+
| count(*) |
+----------+
| 999999 |
+----------+

SELECT table_name,
data_length/1024/1024 AS ‘data_length(MB)‘,
index_length/1024/1024 AS ‘index_length(MB)‘,
(data_length + index_length)/1024/1024 AS ‘total(MB)‘
FROM information_schema.tables
WHERE table_schema=‘test‘
AND table_name = ‘t1‘;
+------------+-----------------+------------------+---------------+
| table_name | data_length(MB) | index_length(MB) | total(MB) |
+------------+-----------------+------------------+---------------+
| t1 | 1048.00000000 | 0.00000000 | 1048.00000000 |
+------------+-----------------+------------------+---------------+

从上面可以看出在磁盘上的数据大小是1.2G,而实际的大小才1048MB(估计值),实际情况会比上面的数据大很多。

1.5. 将test.t1迁移到test2.t1中

1、test2库中创建和test.t1相同的表结构

CREATE DATABASE test2;
USE test2;
CREATE TABLE t1 LIKE test.t1;

2、废弃test2.t1表空间,等待新表空间导入

USE test2;
ALTER TABLE t1 DISCARD TABLESPACE;

   

3、锁表导出test.t1表元数据

USE test;
FLUSH TABLES t1 FOR EXPORT;

4、将test.t1表*.ibd和*.cfg文件拷贝到test2库中

cp t1.cfg /u02/data/test2/
cp t1.ibd /u02/data/test2/
ll -h /u02/data/test2/
-rw-r----- 1 root root 424 Mar 10 14:41 t1.cfg
-rw-r----- 1 mysql mysql 8.5K Mar 10 14:33 t1.frm
-rw-r----- 1 root root 1.2G Mar 10 14:41 t1.ibd

5、释放test.t1锁

USE test;
UNLOCK TABLES;

6、test2导入t1数据

chown -R mysql:mysql /u02/data/test2
USE test2;
ALTER TABLE t1 IMPORT TABLESPACE;

7、查看test2.t1数据

USE test2;
SELECT COUNT(*) FROM t1;
+----------+
| COUNT(*) |
+----------+
| 999999 |
+----------+

1.6. 总结

如果是数据量比较大,并且可以忍受对服务器有一点影响的,就可以考虑使用这种方法来处理。并且需要注意的是最好迁移的数据库版本是相同的。

时间: 2024-11-10 01:22:49

表迁移工具的选型-复制ibd的方法的相关文章

TP5项目中模板文件html的更新及php写入、删除与复制文件的方法

项目是thinkphp5的,后台有一个,上传html模板代码的功能. 因为模板里,除了html代码外,还有, {volist name="list" id="vo"}{/volist} {$title} php,js代码. 我是这样做的,先建一个template表. CREATE TABLE hk_template (     id INT(10) PRIMARY KEY NOT NULL,     name VARCHAR(30),     content TEX

Mysql最简单的复制环节部署方法

最简单的复制环境部署方法 这里环境如下: Master一直没有写操作 Master和Slave在一台虚拟机中,端口号分别为3306和3307 1.关闭Master数据库服务 mysqladmin -umysql -p -S /data/mysqldata/3306/mysql.sock shutdown 2.复制数据文件 cp -r /data/mysqldata/3306 /data/mysqldata/3307 3.编辑Master的参数文件 在[mysqld]区块中添加 server_id

关于异步文件上传和文件表单元素的复制、设置和清除

一.解决文件异步上传的方法有3种:1.使用iframe 2.使用FormData(html5新功能)  3.使用flash 1.使用iframe 原来我以为使用iframe是把整个表单复制到iframe里面,然后把iframe里面的表单提交给服务器,这样来实现表单的异步上传.最后我想错了,实现原理比我想的要简单的多.先看一下代码: 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 2 <

mysql数据库去重语句和不同表之间列的复制语句

1.去重语句:DELETE FROM `v_klg_item` WHERE id NOT IN (SELECT * FROM (SELECT MAX(id) FROM `v_klg_item` GROUP BY NAME) AS tmp); 2.数据库不同表之间列的复制语句:INSERT INTO crm_add (id,address,pid) SELECT id,NAME,parentId FROM labos_area;

[PHP]防止表单重复提交的几种方法

--------------------------------------------------------------------------------------------------- 1. 使用JS让按钮在点击一次后禁用(disable).=> 防止多次点击发生,实现方式较简单. 缺点:若客户端禁止JavaScript脚本,则失效. 2. 在提交成功后执行页面重定向(redirect).=> 转到提交成功信息页面. 特点:避免F5重复提交,消除浏览器前进和后退按导致的同样问题.

hibernate实现分表后获取insert自增ID方法。

#第一种基于原生的JDBC的方式实现 private Integer insert(POJO entity, String table) throws SQLException { String insertSQL = "INSERT INTO " + table + " (XXXX)VALUES(?,?,?,?,?,?,?,?)"; DataSource dataSource = SessionFactoryUtils.getDataSource(getHiber

MySQL快速复制数据库的方法

某些时候,例如为了搭建一个测试环境,或者克隆一个网站,需要复制一个已存在的mysql数据库.使用以下方法,可以非常简单地实现. 假设已经存在的数据库名字叫db1,想要复制一份,命名为newdb.步骤如下: 1. 首先创建新的数据库newdb #mysql  -u root -ppassword mysql>CREATE  DATABASE `newdb` DEFAULT CHARACTER SET UTF8 COLLATE UTF8_GENERAL_CI; 2. 使用mysqldump及mysq

SQLITE数据表主键设置Id自增方法

SQLITE数据表主键设置Id自增方法 标签: sqliteintegerinsertnulltableapi 2010-01-12 08:39 35135人阅读 评论(8) 收藏 举报  分类: SQL(11)  版权声明:本文为博主原创文章,未经博主允许不得转载. 搞定了一个困扰许久的问题,原来sqlite中的主键也是可以设置为自增的:)方法就是声明为 INTEGER PRIMARY KEY 的字段可以自动增加.    网上查到资料说,从 SQLite 的 2.3.4 版本开始,如果将一个表

Lua查找表元素过程(元表、__index方法是如何工作的)(转载)

文章来源于 Lua查找表元素过程(元表.__index方法是如何工作的) Lua的表本质其实是个类似HashMap的东西,其元素是很多的Key-Value对,如果尝试访问了一个表中并不存在的元素时,就会触发Lua的一套查找机制,也是凭借这个机制,才能够实现“面向对象”的. 举例说明: tempTable = {} print(tempTable.memberA) --这里试图打印tempTable并不存在的成员memberA 执行结果:nil输出为nil的原因很简单,tempTable中并没有m