copy関数を使ってデータベースの移動を完了します.
15941 ワード
最近はこの移行ツールの移転方式で、ora 8からpostgresqlに移行しました.元の挿入移動速度は遅すぎます.社長はキャッシュを使って移動させると言いました.つまりpostgresqlのcopy関数を使うので、pg公式サイトに行って関連資料を調べました.私達が移動したいデータ量は約3000万本あります.30時間以内に必要です.この移転の第一歩は、まず関連するテーブル構造を過去に移転し、データの導入を開始します.以下は私がキャッシュ移行して書いたコードの一部です.コアは全部中にあります.
1 private boolean toPostgresql(int tableIndex) throws SQLException, IOException 2 { 3 int success_flag = 0; //
4
5 boolean isHasError = false; 6
7 TableConfig tableConfig = (TableConfig) tableConfigList.get(tableIndex); 8 ITable destTable = tableConfig.getDestTable(); //
9 ITable srITable = tableConfig.getDestTable(); 10 // srITable.
11 String dest_tablename = destTable.getName().toString(); 12 String dest_schema = destTable.getSchemaName(); 13
14 Statement stmt = null; 15 ResultSet rs = null; 16
17 Setfetchsize s1=new Setfetchsize(); 18 try
19 { 20 s1.getxml_setfetchsize(); 21 } catch (ParserConfigurationException e) 22 { 23 // TODO Auto-generated catch block
24 e.printStackTrace(); 25 } catch (SAXException e) 26 { 27 // TODO Auto-generated catch block
28 e.printStackTrace(); 29 } 30 int stmt_setfetchsize = s1.getSetfetchsize_num();// setfetchsize 31 //
32 stmt = srcConn.createStatement(); 33 stmt.setFetchSize(stmt_setfetchsize); 34 rs = getSrcResultSet(tableConfig, stmt); 35 ResultSetMetaData rsmd = rs.getMetaData();// 36 // System.out.println(" setfetchsize :"+stmt_setfetchsize);
37 int columnCount = rsmd.getColumnCount(); //
38 StringBuilder sbuild = new StringBuilder(); 39 //System.out.println("stmt_setfetchsize :"+stmt.getFetchSize());
40 /**
41 * , sbulid 42 */
43 KBCopyOutputStream kb_output = new KBCopyOutputStream((BaseConnection) destConn, "COPY " + dest_schema + "." + dest_tablename + " FROM STDIN"); 44
45 while (rs.next()) 46 { 47
48 row_totalnum += 1; //
49 for (int i = 1; i <= columnCount; i++) 50 { 51 String val = rs.getString(i); 52 int coltype = rsmd.getColumnType(i); 53 // ,
54 if (coltype == Types.CHAR || coltype == Types.VARCHAR || coltype == Types.NCHAR || coltype == Types.NVARCHAR || coltype == Types.LONGVARCHAR) 55 { 56 int valen = val.length(); 57 sbuild.ensureCapacity(valen + 4); 58 for (int j = 0; j < valen; j++) 59 { 60 char ch = val.charAt(j); 61 switch (ch) 62 { 63 case '\t' : 64 sbuild.append("\\t"); 65 break; 66 case '
' : 67 sbuild.append("\
"); 68 break; 69 case '\r' : 70 sbuild.append("\\r"); 71 break; 72 case '\\' : 73 sbuild.append("\\\\"); 74 break; 75 default : 76 sbuild.append(ch); 77 } 78 } 79 } else
80 sbuild.append(val); 81
82 if (i < columnCount) 83 sbuild.append('\t'); 84 } 85 sbuild.append('
'); 86
87 String s = sbuild.toString(); 88 byte[] bytes = s.getBytes("UTF-8"); 89 kb_output.write(bytes); 90 if (row_totalnum % 10 == 0) 91 { 92 successRowNum = 0; 93 addToSuccessNum(row_totalnum); 94 } 95 // System.out.print(s);
96 sbuild.setLength(0); 97 } 98 kb_output.close(); 99 success_flag = 1; 100 destConn.commit(); 101
102 if (success_flag == 1) 103 { 104 writeFinishResult(srITable.getFullName(), destTable.getFullName(), row_totalnum, row_totalnum, 0); 105 successRowNum = 0; 106 addToSuccessNum(row_totalnum); 107 } else
108 { 109 writeFinishResult(srITable.getFullName(), destTable.getFullName(), row_totalnum, 0, row_totalnum); 110 addToErrorNum(row_totalnum); // copyin
111 } 112 writeSteps(" "); 113 return !isHasError; 114 }
私達のsetfetsizeは自分で設定してもいいです.この目的はoracleを訪問してデータを取る費用を減らすことです.具体的な使い方は関連資料を見ることができます.主に訪問のデータ量が大きい時に使います.上のコードには小さな欠陥があります.つまり私は処理したデータを一つのstrigbuilderに入れました.データ量がメモリを超えると、走れなくなります.strigbuilderの中のデータの大きさを判断してもいいです.満足する時にcommtを降りたらいいです.このデータの移動は一つの仕事の中で行います.最後にcomitが提出されました.