前言
Oracle在做數(shù)據(jù)遷移、還原測(cè)試庫(kù)以及其他需要導(dǎo)出、導(dǎo)入數(shù)據(jù)的需求下,我們常用到數(shù)據(jù)泵來進(jìn)行數(shù)據(jù)的轉(zhuǎn)移操作,但往往很多事后我們要操作的庫(kù)數(shù)據(jù)量都非常大,且數(shù)據(jù)庫(kù)中clob字段非常多,就給我們導(dǎo)出帶來了一些問題,導(dǎo)出慢或者卡在那里很久不動(dòng)等問題;
有小伙伴可能會(huì)說你開并行不就行了嗎?事實(shí)上當(dāng)你數(shù)據(jù)庫(kù)中大對(duì)象數(shù)據(jù)量占用較大時(shí)候,你會(huì)發(fā)現(xiàn)開并行沒有任何用,那么怎么解決這個(gè)問題呢?那么思路是先排除大對(duì)象的表;然后大表再通過rowid切片多個(gè)進(jìn)程導(dǎo)出導(dǎo)入。
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
一、大表數(shù)據(jù)
截圖中可以看到,此表占用446G數(shù)據(jù)量,壓縮完后大小為51G,開了2個(gè)進(jìn)程并行,但沒有效果,最終執(zhí)行了10小時(shí),時(shí)間是非常久的。
附:查詢大表
--查看大對(duì)象,先排除導(dǎo)出,然后再單獨(dú)導(dǎo)出
SELECT owner,tablespace_name,case SEGMENT_type
when 'LOBSEGMENT' then
(select table_name || '.' || column_name
from dba_lobs t
where t.segment_name = s.segment_name)
else
SEGMENT_NAME
end as SEGMENT_NAME,
BYTES / 1024 / 1024 MB,
BYTES / 1024 / 1024 / 1024 GB
FROM DBA_SEGMENTS s
Order By 4 Desc,3 asc;
二、解題思路
1.導(dǎo)出排除大表的數(shù)據(jù)
命令參考:
expdp system/oracle@ip:1521/sidname directory=datapump_dir parallel=8 cluster=N dumpfile=exp_full0824_%U.dmp logfile=exp_full_20230824.log schemas=usrname COMPRESSION=ALL exclude=statistics exclude=TABLE:\"in\(\'table_name\'\)\"
這里可以看到排除大表后整體導(dǎo)出時(shí)間下降到了17分鐘!?。?/p>
2.rowid切片導(dǎo)出大表數(shù)據(jù)
rowid切片導(dǎo)出數(shù)據(jù)是從0開始,我們需要知道rowid的分配來控制最終想執(zhí)行的并行數(shù)。
Linux代碼如下(示例):
#!/bin/bash
chunk=9
for ((i=0;i<=8;i++));
do
expdp system/oracle TABLES=tablename QUERY=tablename:\"where mod\(dbms_rowid.rowid_block_number\(rowid\)\, ${chunk}\) = ${i}\" directory=DMP dumpfile=TX_${i}.DMP logfile=TX_${i}.log &
echo $i
sleep 10
done
Windows代碼如下(示例):
@echo off
#這里可以帶上IP地址、端口、sid
set connStr=system/oracle@ip:1521/sid_name
#這里指的并行數(shù)
set chunk=10
#sid_name
set oracle_sid=orcl
#oracle_home路徑注意bin后邊的‘\’
set oracle_home_path=d:\oracle\product\10.2.0\db_1\bin\
rem 格式:FOR /L %variable IN (start,step,end) DO command [command-parameters]
#10個(gè)并行,0~9(開始標(biāo)號(hào)、每次增加量、結(jié)束標(biāo)號(hào))
for /l %%a in (0,1,9) do (
start /b %oracle_home_path%expdp %connStr% TABLES=table_name QUERY=table_name:\"where mod\(dbms_rowid.rowid_block_number\(rowid\)\,%chunk%\) = %%a\" directory=expdpdump dumpfile=TX_%%a.DMP logfile=TX_%%a.log
timeout 10 >nul 2>nul
)
手工執(zhí)行代碼如下(示例):
#如下,打開三個(gè)窗口分別粘貼執(zhí)行,如果要開更多的進(jìn)程,需要更改3后后面的0~2
SQL> create or replace directory dmp as 'D:\dump\';
SQL> grant read,write on directory dmp to public;
expdp system/oracle tables=table_name QUERY=table_name:\"where mod\(dbms_rowid.rowid_block_number\(rowid\)\,3\) = 0\" directory=DMP dumpfile=xxxx_0.dmp logfile=xxxx_0.log
expdp system/oracle tables=table_name QUERY=table_name:\"where mod\(dbms_rowid.rowid_block_number\(rowid\)\,3\) = 1\" directory=DMP dumpfile=xxxx_1.dmp logfile=xxxx_1.log
expdp system/oracle tables=table_name QUERY=table_name:\"where mod\(dbms_rowid.rowid_block_number\(rowid\)\,3\) = 2\" directory=DMP dumpfile=xxxx_2.dmp logfile=xxxx_2.log
)
以上我拿一張14G數(shù)據(jù)表進(jìn)行測(cè)試,3個(gè)并行度執(zhí)行實(shí)際4分半,實(shí)際測(cè)試中切片導(dǎo)出數(shù)據(jù)也可以加壓縮參數(shù)。
對(duì)比此張圖可以看到我的切片測(cè)試已將導(dǎo)出實(shí)際提升了2倍左右,如果并行度更高的話,那么我們的整體時(shí)間會(huì)成倍降低。
3.rowid切片導(dǎo)入大表數(shù)據(jù)
導(dǎo)入前準(zhǔn)備
在導(dǎo)入大表數(shù)據(jù)之前需要做的是:
#確保大表所在的表空間存在
select table_name,tablespace from user_tables where table_name='TABLE_NAME';
#創(chuàng)建用戶以及表結(jié)構(gòu),建議使用plsql查詢
SELECT DBMS_METADATA.GET_DDL('TABLE','TABLE_NAME') from DUAL;
linux代碼如下(示例):
#!/bin/bash
for ((i=0;i<=8;i++));
do
#echo dumpfile=TX_${i}.DMP
impdp \"/ as sysdba\" directory=impdpdump dumpfile=TX_${i}.DMP logfile=impdp_TX_${i}.log DATA_OPTIONS=DISABLE_APPEND_HINT TRANSFORM=DISABLE_ARCHIVE_LOGGING:Y CONTENT=DATA_ONLY &
sleep 10
done
windows代碼如下(示例):
@echo off
set connStr=system/oracle
set oracle_sid=orcl
set oracle_home_path=d:\oracle\product\10.2.0\db_1\bin\
rem 格式:FOR /L %variable IN (start,step,end) DO command [command-parameters]
for /l %%a in (0,1,9) do (
rem 11g upper >start /b %oracle_home_path%impdp %connStr% directory=impdpdump dumpfile=TX_%%a.DMP logfile=imp_TX_%%a.log DATA_OPTIONS=DISABLE_APPEND_HINT TRANSFORM=DISABLE_ARCHIVE_LOGGING:Y CONTENT=DATA_ONLY
start /b %oracle_home_path%impdp %connStr% directory=impdpdump dumpfile=TX_%%a.DMP logfile=imp_TX_%%a.log CONTENT=DATA_ONLY
timeout 10 >nul 2>nul
)
測(cè)試表導(dǎo)入成功,和切片導(dǎo)出的時(shí)間基本相同。文章來源:http://www.zghlxwxcb.cn/news/detail-682312.html
三、導(dǎo)出時(shí)業(yè)務(wù)卡頓如何停止
select s.inst_id,to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') "DATE", s.program, s.sid, 'orakill orcl2 '||spid,'kill -9 '||spid,
s.status, s.username, d.job_name, p.spid, s.serial#, p.pid ,'ALTER SYSTEM KILL SESSION '||''''||s.SID||','||s.SERIAL#||',@'||s.inst_id||''''||' IMMEDIATE;' killse
from gv$session s, gv$process p, dba_datapump_sessions d
where p.addr=s.paddr and s.saddr=d.saddr and s.inst_id=p.inst_id and s.inst_id=d.inst_id;
select 'orakill orcl '||spid ,'ALTER SYSTEM KILL SESSION '||''''||t1.SID||','||t1.SERIAL#||''''||' IMMEDIATE;' killse
--,'kill -9 '||spid
from sys.gV_$PROCESS t,gv$session t1,dba_datapump_sessions d
where t.addr=t1.paddr and t1.saddr=d.saddr
and t1.Type='USER' and t1.username is not null;
select 'drop table ' || owner_name || '.' || job_name || ' purge;' from dba_datapump_jobs where state = 'NOT RUNNING' ;
參考文獻(xiàn):https://mp.weixin.qq.com/s/pKNe2EzpB_PM0itpa4jrdA文章來源地址http://www.zghlxwxcb.cn/news/detail-682312.html
到了這里,關(guān)于給oracle邏輯導(dǎo)出clob大字段、大數(shù)據(jù)量表提提速的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!