將表 從mysql 遷移到oracle
昨天接到一個任務,將一個表從mysql遷移到oracle,表總共有300多萬條記錄。
解決思路;先將資料從mysql匯出一個文字檔案,然後傳送的目標伺服器,進而用sqlldr將其載入至oracle
第一步: 匯出檔案
Mysql 匯出檔案
在此省去表結構
mysql> select * from justin into outfile '/data/mysqldata/justin.txt' fields terminated by ',' enclosed by '"';
第二步
將其傳輸到目標伺服器
[rkun@localhost mysqldata]$ scp justin.txt oracle@192.168.0.1:
oracle@192.168.0.1's password:
justin.txt
第三步
目標伺服器上建立control.ctl
load data
characterset UTF8
infile '/home/oracle/justin
new.txt'
append into table justin
fields terminated by ',' OPTIONALLY ENCLOSED BY '"'
(
"ID" sequence(MAX,1),
**********
**********
)
注:我們在此採用sqlldr直接路徑載入,必須在控制檔案指定載入字符集,使之與目標資料庫保持一致,否則會預設採用OS端的字符集,中文字元會產生亂碼
另外,mysql中id對應值全為0,而對應的oracle表該欄位為主鍵,為防止主鍵衝突,使用sqlldr的sequence功能生成主鍵,sequence(max,1)插入前找出表中id最大值並自動將當前值加1;
同時此功能要求在文字檔案中去掉對應的id列
該表總共有22列 使用cut命令 去除第一列
[oracle@justin ~]$ more justin.txt | cut -d ',' -f 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 > justinnew2.txt
另外mysql匯出文字檔案的時候,當欄位為空值的時候,其對應的字元為\N, 當使用sqlldr載入至Oracle,會報錯
Record 2: Rejected - Error on table justin, column "justin11".
ORA-01722: invalid number
採用tr命令來消除,將\N用空格來代替
[oracle@justin ~]$ more justinnew2.txt | tr '\\N' ' ' > justinnew.txt
接下來呼叫sqlldr命令
[oracle@justin ~]$ $ORACLE_HOME/bin/./sqlldr userid=justin/****** control=control.ctl readsize=500000 rows=2000 direct=true log=justin.log
採用sqlldr載入, 報錯如下
Record 5957: Rejected - Error on table justin, column "LOG_LEVEL".
Column not found before end of logical record (use TRAILING NULLCOLS)
日誌顯示從第5957行開始,找不到最後一列"LOG_LEVEL"的值了
檢視一下發現 經過os命令轉變後 原檔案的相應行的最後一列“-1”被切掉了
[oracle@justin ~]$ head -5960 justin.txt | tail -10
\N,\N,\N,\N,"1","0"
\N,\N,\N,\N,"1","0"
\N,\N,\N,\N,"1","0"
\N,\N,\N,\N,"1","0"
\N,\N,\N,\N,"1","0"
\N,\N,\N,\N,"1","0"
\N,\N,"805688",\N,"1","-1"\N,\N,"5579643",\N,"1","-1"
\N,\N,"6092314",\N,"1","-1"
\N,\N,"788776",\N,"1","-1"
[oracle@justin ~]$ head -5960 justinnew.txt | tail -10
, , ,"1","0"
, , ,"1","0"
, , ,"1","0"
, , ,"1","0"
, , ,"1","0"
, , ,"1","0"
, ,"805688", ,"1" —-只有了1,後面的”-1”沒有了
, ,"5579643", ,"1"
, ,"6092314", ,"1"
, ,"788776", ,"1"
經確認,問題出在cut命令上,我本意是想把第一列去掉,沒想到從5957行開始,把最後一列也給切了,導致報錯Column not found before end of logical record (use TRAILING NULLCOLS)
反覆驗證後發現了問題,當呼叫cut命令時候,採用','作為分隔符,但是中間有個欄位值裡面已經有了',',類似"asdgasg,asdf",故os把它當作了兩個不同的列來處理。
解決方法: 呼叫cut時候後面多加一個數字23即可
注: 我們的sqlldr的控制檔案也是採用','作為分隔符,但是由於加上了fields terminated by ',' OPTIONALLY ENCLOSED BY '"',故不會像cut命令一樣把此欄位當成兩個來處理
重新載入 發現又報錯 但是這次已經載入了50多萬行 比上次有進步了
先把能夠載入的全都載入進去 設定errors引數為10000
[oracle@justin ~]$ $ORACLE_HOME/bin/./sqlldr userid=justin/******* control=control.ctl readsize=500000 rows=2000 direct=true log=justin.log errors=10000
結果顯示才95條遺漏的
Table justin
:
3006277 Rows successfully loaded.
95 Rows not loaded due to data errors.
0 Rows not loaded because all WHEN clauses were failed.
0 Rows not loaded because all fields were null.
考慮到是日誌跟蹤表 這個錯誤率還是可以接受的
[ 本帖最後由 myownstars 於 2011-2-25 17:51 編輯 ]
解決思路;先將資料從mysql匯出一個文字檔案,然後傳送的目標伺服器,進而用sqlldr將其載入至oracle
第一步: 匯出檔案
Mysql 匯出檔案
在此省去表結構
mysql> select * from justin into outfile '/data/mysqldata/justin.txt' fields terminated by ',' enclosed by '"';
第二步
將其傳輸到目標伺服器
[rkun@localhost mysqldata]$ scp justin.txt oracle@192.168.0.1:
oracle@192.168.0.1's password:
justin.txt
第三步
目標伺服器上建立control.ctl
load data
characterset UTF8
infile '/home/oracle/justin
new.txt'
append into table justin
fields terminated by ',' OPTIONALLY ENCLOSED BY '"'
(
"ID" sequence(MAX,1),
**********
**********
)
注:我們在此採用sqlldr直接路徑載入,必須在控制檔案指定載入字符集,使之與目標資料庫保持一致,否則會預設採用OS端的字符集,中文字元會產生亂碼
另外,mysql中id對應值全為0,而對應的oracle表該欄位為主鍵,為防止主鍵衝突,使用sqlldr的sequence功能生成主鍵,sequence(max,1)插入前找出表中id最大值並自動將當前值加1;
同時此功能要求在文字檔案中去掉對應的id列
該表總共有22列 使用cut命令 去除第一列
[oracle@justin ~]$ more justin.txt | cut -d ',' -f 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 > justinnew2.txt
另外mysql匯出文字檔案的時候,當欄位為空值的時候,其對應的字元為\N, 當使用sqlldr載入至Oracle,會報錯
Record 2: Rejected - Error on table justin, column "justin11".
ORA-01722: invalid number
採用tr命令來消除,將\N用空格來代替
[oracle@justin ~]$ more justinnew2.txt | tr '\\N' ' ' > justinnew.txt
接下來呼叫sqlldr命令
[oracle@justin ~]$ $ORACLE_HOME/bin/./sqlldr userid=justin/****** control=control.ctl readsize=500000 rows=2000 direct=true log=justin.log
採用sqlldr載入, 報錯如下
Record 5957: Rejected - Error on table justin, column "LOG_LEVEL".
Column not found before end of logical record (use TRAILING NULLCOLS)
日誌顯示從第5957行開始,找不到最後一列"LOG_LEVEL"的值了
檢視一下發現 經過os命令轉變後 原檔案的相應行的最後一列“-1”被切掉了
[oracle@justin ~]$ head -5960 justin.txt | tail -10
\N,\N,\N,\N,"1","0"
\N,\N,\N,\N,"1","0"
\N,\N,\N,\N,"1","0"
\N,\N,\N,\N,"1","0"
\N,\N,\N,\N,"1","0"
\N,\N,\N,\N,"1","0"
\N,\N,"805688",\N,"1","-1"\N,\N,"5579643",\N,"1","-1"
\N,\N,"6092314",\N,"1","-1"
\N,\N,"788776",\N,"1","-1"
[oracle@justin ~]$ head -5960 justinnew.txt | tail -10
, , ,"1","0"
, , ,"1","0"
, , ,"1","0"
, , ,"1","0"
, , ,"1","0"
, , ,"1","0"
, ,"805688", ,"1" —-只有了1,後面的”-1”沒有了
, ,"5579643", ,"1"
, ,"6092314", ,"1"
, ,"788776", ,"1"
經確認,問題出在cut命令上,我本意是想把第一列去掉,沒想到從5957行開始,把最後一列也給切了,導致報錯Column not found before end of logical record (use TRAILING NULLCOLS)
反覆驗證後發現了問題,當呼叫cut命令時候,採用','作為分隔符,但是中間有個欄位值裡面已經有了',',類似"asdgasg,asdf",故os把它當作了兩個不同的列來處理。
解決方法: 呼叫cut時候後面多加一個數字23即可
注: 我們的sqlldr的控制檔案也是採用','作為分隔符,但是由於加上了fields terminated by ',' OPTIONALLY ENCLOSED BY '"',故不會像cut命令一樣把此欄位當成兩個來處理
重新載入 發現又報錯 但是這次已經載入了50多萬行 比上次有進步了
先把能夠載入的全都載入進去 設定errors引數為10000
[oracle@justin ~]$ $ORACLE_HOME/bin/./sqlldr userid=justin/******* control=control.ctl readsize=500000 rows=2000 direct=true log=justin.log errors=10000
結果顯示才95條遺漏的
Table justin
:
3006277 Rows successfully loaded.
95 Rows not loaded due to data errors.
0 Rows not loaded because all WHEN clauses were failed.
0 Rows not loaded because all fields were null.
考慮到是日誌跟蹤表 這個錯誤率還是可以接受的
[ 本帖最後由 myownstars 於 2011-2-25 17:51 編輯 ]
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15480802/viewspace-688359/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 將應用程式從Sql Server遷移到OracleSQLServerOracle
- (原)將Oracle遷移到SQLServerOracleSQLServer
- 將表從一個表空間遷移到另外一個表空間
- 從Oracle遷移到MySQL的各種坑及自救方案OracleMySql
- 將OPEN BRAVO資料庫從oracle 遷移到DB2資料庫OracleDB2
- 將SAP 後臺資料庫從DB2 遷移到ORACLE資料庫DB2Oracle
- 從Oracle遷移到Mysql之前必須知道的50件事OracleMySql
- [譯] 將現有的 API 從 REST 遷移到 GraphQLAPIREST
- SQLITE 遷移到 MYSQLSQLiteMySql
- 透過MySQL Workbench 將 SQL Server 遷移到GreatSQLMySqlServer
- 如果需要從Oracle遷移到MS SQLServer (2)OracleSQLServer
- 如果需要從Oracle遷移到MS SQLServer (1)OracleSQLServer
- oracle將控制檔案從裸裝置遷移到檔案系統Oracle
- 將OPEN BRAVO後臺資料庫從ORACLE遷移到DB2資料庫OracleDB2
- 從 PDF 表單遷移到 IBM Lotus FormsIBMORM
- 從Firebase+Redis遷移到PlanetScale+MySQLRedisMySql
- oracle 將表空間下的資料檔案從檔案系統遷移到ASM磁碟組OracleASM
- 將spfile從ASM裡遷移到檔案系統ASM
- 【遷移】SqlServer 遷移到 MySQL 方法ServerMySql
- 從Perforce遷移到GitGit
- 從MySQL遷移到VoltDB的一點經驗MySql
- 將pentaho資料庫遷移到oracle資料庫資料庫Oracle
- 將資料庫從ASM遷移到檔案系統資料庫ASM
- 將資料庫從檔案系統遷移到ASM資料庫ASM
- 從 golang flag 遷移到 cmdrGolang
- 從 Nginx 遷移到 Envoy ProxyNginx
- 平安科技從 Oracle 遷移到 UbiSQL 的實踐OracleSQL
- Oracle11g使用rman從rac遷移到racOracle
- mysql5.1遷移到oracle10.2.0.5步驟MySqlOracle
- 【Linux】將Oracle安裝目錄從根目錄下遷移到邏輯卷LinuxOracle
- 將 CentOS 8 作業系統遷移到 Oracle LinuxCentOS作業系統OracleLinux
- 如何將 CentOS遷移到 AlmaLinux?CentOSLinux
- 將nodejs遷移到D盤NodeJS
- Facebook將花費幾年時間將資料庫遷移到MySQL 8.0資料庫MySql
- [譯]從 SQLite 逐步遷移到 RoomSQLiteOOM
- 從mpvue遷移到uni-appVueAPP
- EF Core從TPH遷移到TPT
- [譯] 從 SQLite 逐步遷移到 RoomSQLiteOOM