記一次Oracle數(shù)據(jù)遷移踩過的坑

一.背景

應(yīng)用系統(tǒng)之間進(jìn)行大量的數(shù)據(jù)交換一般通過數(shù)據(jù)文件的形式來處理,數(shù)據(jù)文件又分為二進(jìn)制文件和文本文件(也稱平面文件),采用文本文件的形式比較便于數(shù)據(jù)的查看和操作。
本次數(shù)據(jù)遷移是把中臺(tái)的記錄的歷史交易明細(xì)遷移到后臺(tái),有些數(shù)據(jù)后臺(tái)沒有記錄,需要中臺(tái)的數(shù)據(jù)來進(jìn)行更新。

二.實(shí)施方案

1. 導(dǎo)出數(shù)據(jù)

這個(gè)步驟是由中臺(tái)來操作的,使用的是orato8a工具導(dǎo)數(shù)據(jù)。orato8a 是一個(gè)可以快速、高效地從 oracle 數(shù)據(jù)庫系統(tǒng)中抽取數(shù)據(jù),并將數(shù)據(jù)保存到指定文件中的專用工具。orato8a 還提供查詢語句導(dǎo)出和全表導(dǎo)出兩種方式,其中全表導(dǎo)出的登錄用戶需要對(duì) dba_extents、dba_objects和 dba_tables 這三張表有 select 權(quán)限。
導(dǎo)出數(shù)據(jù)腳本:

export NLS_LANG="SIMPLIFIED CHINESE_CHINA".AL32UTF8 //設(shè)置編碼
export LD_LIBRARY_PATH=/home/other/test/lib:$LD_LIBRARY_PATH // 設(shè)置程序共享庫位置
export ORACLE_HOME=/u01/oracle/10.2.0/db_1 // 設(shè)置oracle環(huán)境變量
export SQLPATH=$ORACLE_HOME/sqlpath
export TNS_ADMIN=$ORACLE HOME/network/admin
./orato8 --user='' --query='SELECT * FROM TABLE_A' --file='/tmp/data/00-1124MG-TABLE_A-20210327' --format='3' --field='|!' --line_separator='\n'
./orato8a --user='' --query='SELECT * FROM TABLE_B' --file='/tmp/data/00-1124MG-TABLE_B-20210327' --format='3' --field='|!' --line_separator='\n'
2.GTP傳輸數(shù)據(jù)

這一塊不太了解

3.導(dǎo)入數(shù)據(jù)
3.1 建數(shù)據(jù)庫表

根據(jù)中臺(tái)給的數(shù)據(jù)庫建表語句,新建了兩張數(shù)據(jù)庫表

3.2 備份歷史表

采用先建表,再導(dǎo)入數(shù)據(jù)的方式進(jìn)行備份

insert /*+append*/ into table_A_bk  (id,name,...) select id,name,... from table_A;
3.3 數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫

采用sql loader方式將中臺(tái)傳輸?shù)臄?shù)據(jù)進(jìn)行入庫,

sqlldr ${username}/${password}@${dbserver:${port}/${sid} contrl="TABLEALOAD.ctl" log=${TABLE_A_LOGFILE}
3.4 數(shù)據(jù)驗(yàn)證

驗(yàn)證條數(shù)是否和中臺(tái)一致;是否有空值等

3.5 建索引
4. 預(yù)處理生成中間表
5. 更新備份表

采用的是MERGE INTO的方式,用法參考:

MERGE INTO A
USING B
ON
WHEN MATCHED THEN
6. 校驗(yàn)歷史數(shù)據(jù)表與與備份表一致性
7.互換表名

三.遇到的錯(cuò)誤及解決方案

1.SQL*Loader-00510報(bào)錯(cuò)

SQL*Loader-00510 Physical record in data file (string) is longer than the maximum(number)
官網(wǎng)解釋:

Cause: The datafile has a physical record that is too long.
Action: Use CONCATENATE or CONTINUEIF. Break up the physical records.

解決方案: 在網(wǎng)上找到各種原因和解決方法,如:

  1. 由于導(dǎo)入文件中存在不同格式的回車換行引起的
    有^M和兩種回車換行導(dǎo)致,所以用dos2unix命令統(tǒng)一轉(zhuǎn)換成Linux回車換行。
    dos2unix filename
  2. 還有一些其他的,具體不太記得了。

最后嘗試過各種方法后,才發(fā)現(xiàn)中臺(tái)傳給我們的數(shù)據(jù)文件中,換行符和我們之前約定的不一樣,導(dǎo)致SQL*Loader導(dǎo)入數(shù)據(jù)庫時(shí)無法識(shí)別換行,把整個(gè)文件當(dāng)成一行來處理了。后面讓中臺(tái)重新按約定的換行符給我們重導(dǎo)一份數(shù)據(jù)就可以了。
啟示:在涉及到不同部門或單位合作的時(shí)候,一定要事先約定好規(guī)則,并要求各個(gè)合作部門嚴(yán)格按照約定的規(guī)則來辦事。

2. 導(dǎo)入數(shù)據(jù)庫時(shí),報(bào)長(zhǎng)度過長(zhǎng)和插入null值錯(cuò)誤。

通過分析,發(fā)現(xiàn)有些數(shù)據(jù)竟然不能插入數(shù)據(jù)庫,通過和中臺(tái)那邊確認(rèn),發(fā)現(xiàn)那邊的該字段并沒有null值,在這里我們花了很多時(shí)間來排查,后面才發(fā)現(xiàn)中臺(tái)給我們的ctl文件重字段順序和給我們的文件數(shù)據(jù)不一致導(dǎo)致字段錯(cuò)位引起的。暈~~~~~

解決方法: 要么中臺(tái)重新給我們傳數(shù)據(jù),要么我們這邊調(diào)整ctl文件字段適應(yīng)他們的數(shù)據(jù)。最后想到讓中臺(tái)搞不知道要到什么時(shí)候,還是自己調(diào)整ctl來適應(yīng)他們的數(shù)據(jù)了。

3. rename 報(bào)錯(cuò)

在測(cè)試環(huán)境使用的更改表名的方式時(shí)
rename oldName to newName
在生產(chǎn)環(huán)境竟然報(bào)錯(cuò),然后改為如下方式:
alter table oldName rename to newName
啟示:一定要提前了解生產(chǎn)環(huán)境和測(cè)試環(huán)境的差異,做好備用方案,多測(cè)試。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容