最近在该一个迁移工具的迁移方式,从ora8迁移到postgresql使用原来的插入迁移速度太慢了,老板说让使用缓存迁移,即使用postgresql的copy函数,因此去pg官网查阅了相关资料,我们需要迁移的数据量大约有3000万条,需要时间在半个小时之内,这个迁移第一步先把相关的表结构迁移过去,然后开始导入数据,下面是我缓存迁移写的一段代码,核心都在里面:

     private boolean toPostgresql(int tableIndex) throws SQLException, IOException
{
int success_flag = 0; // 设置成功标志 boolean isHasError = false; TableConfig tableConfig = (TableConfig) tableConfigList.get(tableIndex);
ITable destTable = tableConfig.getDestTable(); // 可以通过这个获得目的表的表名字
ITable srITable = tableConfig.getDestTable();
// srITable.
String dest_tablename = destTable.getName().toString();
String dest_schema = destTable.getSchemaName(); Statement stmt = null;
ResultSet rs = null; Setfetchsize s1=new Setfetchsize();
try
{
s1.getxml_setfetchsize();
} catch (ParserConfigurationException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
int stmt_setfetchsize = s1.getSetfetchsize_num();// 设置setfetchsize
// 取值大小
stmt = srcConn.createStatement();
stmt.setFetchSize(stmt_setfetchsize);
rs = getSrcResultSet(tableConfig, stmt);
ResultSetMetaData rsmd = rs.getMetaData();// 为了获得字段用的
// System.out.println("缓存setfetchsize设置为:"+stmt_setfetchsize);
int columnCount = rsmd.getColumnCount(); // 获得字段的个数
StringBuilder sbuild = new StringBuilder();
//System.out.println("stmt_setfetchsize实际取值为:"+stmt.getFetchSize());
/**
* 把结果集的数据拼接成字符串语句,保存到sbulid中 大小受缓存大小影响
*/
KBCopyOutputStream kb_output = new KBCopyOutputStream((BaseConnection) destConn, "COPY " + dest_schema + "." + dest_tablename + " FROM STDIN"); while (rs.next())
{ row_totalnum += 1; // 记录总数据的总行数
for (int i = 1; i <= columnCount; i++)
{
String val = rs.getString(i);
int coltype = rsmd.getColumnType(i);
// 对字符字段的转义字串进行处理,使其转义效果失效
if (coltype == Types.CHAR || coltype == Types.VARCHAR || coltype == Types.NCHAR || coltype == Types.NVARCHAR || coltype == Types.LONGVARCHAR)
{
int valen = val.length();
sbuild.ensureCapacity(valen + 4);
for (int j = 0; j < valen; j++)
{
char ch = val.charAt(j);
switch (ch)
{
case '\t' :
sbuild.append("\\t");
break;
case '\n' :
sbuild.append("\\n");
break;
case '\r' :
sbuild.append("\\r");
break;
case '\\' :
sbuild.append("\\\\");
break;
default :
sbuild.append(ch);
}
}
} else
sbuild.append(val); if (i < columnCount)
sbuild.append('\t');
}
sbuild.append('\n'); String s = sbuild.toString();
byte[] bytes = s.getBytes("UTF-8");
kb_output.write(bytes);
if (row_totalnum % 10 == 0)
{
successRowNum = 0;
addToSuccessNum(row_totalnum);
}
// System.out.print(s);
sbuild.setLength(0);
}
kb_output.close();
success_flag = 1;
destConn.commit(); if (success_flag == 1)
{
writeFinishResult(srITable.getFullName(), destTable.getFullName(), row_totalnum, row_totalnum, 0);
successRowNum = 0;
addToSuccessNum(row_totalnum);
} else
{
writeFinishResult(srITable.getFullName(), destTable.getFullName(), row_totalnum, 0, row_totalnum);
addToErrorNum(row_totalnum); // copyin执行失败返回错误数
}
writeSteps(" ");
return !isHasError;
}

我们的setfetchsize可以自己设置一下,这个目的是减少来回访问oracle拿取数据的开销,具体用法可以查看相关资料,主要是访问的数据量大的时候用的。上面的代码有个小缺陷,就是我把处理过的数据都放到一个stringbuilder里了,当数据量很大超过内存时候,估计就跑不动了,你可以对stringbuilder里的数据进行大小判断一下,当满足的时候commit一下啊就行,这个数据迁移是在一个事务中进行的,所以最后有个commit提交!

使用copy函数完成数据库迁移的更多相关文章

  1. 项目那几步走:先配置setting路径文件、创建数据库、执行数据库迁移命令、配置mysql数据库信息、注册app、注释中间件、pymysql替换mysqldb-配置urls路由-继续视图函数-然后HTML页面展示-HTML里面导入css文件、models配置数据库表、

    django使用mysql数据库: 首先cmd创建库 1.settings: """Django settings for day42 project. Generate ...

  2. Code First开发系列之数据库迁移

    返回<8天掌握EF的Code First开发>总目录 本篇目录 开启并运行迁移 使用迁移API 应用迁移 给已存在的数据库添加迁移 EF的其他功能 本章小结 自我测试 本系列的源码本人已托 ...

  3. Rman实现数据库迁移

    Rman实现数据库迁移(从库A迁移到库B)环境:服务器A:Oracle10g+AS3服务器B:Oracle10g+AS4准备工作: 1 在数据库B上建立与库A相同的目录结构(若由于磁盘空间等原因可以用 ...

  4. Entity Framework数据库迁移

    1.启用数据迁移: enable-Migrations2.增加一条数据库迁移指令:add-Migrations 必须带上一个版本名称,比如AddUsernamePassword完整的指令:add-Mi ...

  5. MySql 使用 EF Core 2.0 CodeFirst、DbFirst、数据库迁移(Migration)介绍及示例

    dotnet core 2.0 发布已经好几天了,期间也把原来 dotnet core 1.1 的 MVC 项目升级到了 2.0,升级过程还是比较顺利的,变动也不是太多.升级的过程中也少不了 Enti ...

  6. flask数据库迁移理解及命令

    前言: 使用数据库迁移,可以直接建表,而不用我们自己写sql语句用来建表.就是将关系型数据库的一张张表转化成了Python的一个个类. 在开发中经常会遇到需要修改原来的数据库模型,修改之后更新数据库, ...

  7. iOS SQLite 数据库迁移

    本文转载至 http://www.jianshu.com/p/c19dd08697bd 最近不得不考虑关于数据库迁移的问题,原先用了种很不好的处理方式(每次版本升级就删除本地数据库,太傻),于是开始考 ...

  8. Kettle实现数据库迁移

    Kettle实现数据库迁移 需求: 做数据仓库时,需要将业务系统CRM抽取到数据仓库的缓冲层,业务系统使用的是SqlServer数据库,数据仓库的缓冲层使用的是mysql数据库,为实现数据库的迁移,即 ...

  9. SQLSERVER数据库迁移的方法

    数据库迁移两种方案:https://www.cnblogs.com/mcgrady/p/7614491.html 方案一 1,先将源服务器上的数据库文件打包(包括mdf和ldf文件),并且复制到目标服 ...

随机推荐

  1. POJ 2752 Seek the Name, Seek the Fame(求所有既是前缀又是后缀的子串长度)

    题目链接:http://poj.org/problem?id=2752 题意:给你一个字符串,求出所有前缀后缀(既是前缀又是后缀的子串)的长度 思路:首先整个字符串肯定既是前缀又是后缀,为最大的前缀后 ...

  2. 使2个div 在一行上显示

    <!DOCTYPE html> <html> <head> <meta name="viewport" content="wid ...

  3. spoj 375 QTREE - Query on a tree 树链剖分

    题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...

  4. Java web 开发环境配置。

    一.配置 win8 64位 环境java 开发环境 1.  下载JDK,地址 http://www.oracle.com/technetwork/java/javase/downloads/index ...

  5. 打包mysql、tomcat、jdk为一个软件

    打包mysql.tomcat.jdk为一个软件 博客分类: 成长中的点滴  . 我们在本地开发web应用的时候,直接在IDE里面就可以完成jdk.容器.数据库的配置和集成. 但是如果当我们把应用程序交 ...

  6. java csv 文件 操作类

    一个CSV文件操作类,功能比较齐全: package tool; import java.io.BufferedReader; import java.io.BufferedWriter; impor ...

  7. 文本相似度算法——空间向量模型的余弦算法和TF-IDF

    1.信息检索中的重要发明TF-IDF TF-IDF是一种统计方法,TF-IDF的主要思想是,如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分 ...

  8. JS实现日历控件选择后自动填充

    最近在做人事档案的项目,在做项目的初期对B/S这块不是很熟悉,感觉信心不是很强,随着和师哥同组人员的交流后发现,调试程序越来越好了,现在信心是倍增,只要自己自己踏实的去研究.理解代码慢慢的效果就出来了 ...

  9. HTML5 总结-SVG-5

    HTML5 内联 SVG HTML5 支持内联 SVG. 什么是SVG? SVG 指可伸缩矢量图形 (Scalable Vector Graphics) SVG 用于定义用于网络的基于矢量的图形 SV ...

  10. Python学习之路——类

    类: 类是将抽象的实物进行的划分. 在现实世界中如果我们将: 人类包含:男人.女人.孩子.老人等动物类包含:小猫.小狗.小兔子等 在代码世界中我也可以分类,例如将相同功能的代码放到一起,这就是分类. ...