<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          驚呆,Oracle的這個(gè)坑竟然讓我踩上了

          共 2740字,需瀏覽 6分鐘

           ·

          2021-10-13 00:17

          ?

          ?今天,系統(tǒng)中的一個(gè)業(yè)務(wù)處理莫名地執(zhí)行了6個(gè)小時(shí)都沒有結(jié)束,正常處理也就是3分鐘左右,對(duì)原因進(jìn)行定位,發(fā)現(xiàn)是在Oracle客戶端上同步執(zhí)行一個(gè)命令沒有響應(yīng)。今天來分享一下這個(gè)問題,讓更多的人避開這個(gè)坑。

          ?

          1 業(yè)務(wù)場(chǎng)景

          我們要把一個(gè)csv文件(文件名biz.csv)中的數(shù)據(jù)讀取到Oracle數(shù)據(jù)庫(kù)表(表名t_biz,t_biz)中,數(shù)據(jù)庫(kù)表t_biz表結(jié)構(gòu)如下:

          biz.csv文件內(nèi)容如下:

          id,a,b,c
          1,a1,b1,c1
          2,a2,b2,c2
          3,a3,b3,c3

          把biz.csv文件的內(nèi)容讀入到表t_biz,為了提高效率,這里使用了sqlldr 命令,命令如下:

          sqlldr?test/test123@biz?control=/home/jinjunzhu/biz/T_BIZ.ctl?log=/home/jinjunzhu/biz/T_BIZ.log?bad=/home/jinjunzhu/biz/T_BIZ.bad

          解釋一下這個(gè)命令,test/test123 是要訪問的數(shù)據(jù)庫(kù)實(shí)例的用戶名/密碼,biz 是數(shù)據(jù)庫(kù)實(shí)例名稱。T_BIZ.ctl是控制文件,內(nèi)容如下:

          options(skip=1,rows=10000,errors=0,parallel=true,bindsize=1048576,readsize=1048576)
          load?data?
          infile?'/home/jinjunzhu/biz/biz.csv'
          fields?terminated?by?','
          truncate?into?table?day_data
          trailing?nullcols
          (id,a,b,c)

          業(yè)務(wù)代碼中調(diào)用這個(gè)命令,代碼如下:

          private?int?execute(String?cmd)?throws?Exception{
          ????Process?process?=?Runtime.getRuntime().exec(new?String[]{"/bin/bash",?"-c",?cmd});
          ????process.waitFor(10,?TimeUnit.SECONDS);
          ????Integer?status?=?process.waitFor();
          ????return?status?==?null???-1?:?status;
          }

          ?

          2 問題現(xiàn)場(chǎng)

          程序執(zhí)行到上面第4行的時(shí)候,程序hang住了,一直沒有返回。這個(gè)代碼之前從來沒有出過問題,最近也沒有上過線,今天唯一的不同就是文件數(shù)據(jù)量越來越大,今天比昨天大了幾萬行。
          數(shù)據(jù)庫(kù)情況:
          • 看不到有sqlldr命令等待的情況
          • CPU正常
          • 手工執(zhí)行上面命令可以成功,但是打印的日志非常多,如下圖:

          3 原因分析

          網(wǎng)上搜這個(gè)問題竟然很多,原因有下面三類:

          3.1 Oracle版本低

          Oracle版本低,建議升級(jí)到10.2.0.2或以上,這個(gè)方案忽略,因?yàn)槲覀兊臄?shù)據(jù)庫(kù)版本是Oracle 11.2.0.4.0。

          3.2 數(shù)據(jù)落庫(kù)情況

          本以為sqlldr命令執(zhí)行失敗了,但是文件數(shù)據(jù)已經(jīng)全部落到t_biz表。這說明命令執(zhí)行成功了,只是Oracle沒有給應(yīng)用返回結(jié)果。難道是Oracle數(shù)據(jù)庫(kù)hang住了?但是上面的問題現(xiàn)場(chǎng)已經(jīng)確認(rèn),Oracle并沒有hang在sqlldr這個(gè)命令上。

          3.3 最終答案

          看了好多博客,最后發(fā)現(xiàn)竟然不是Oracle的原因。根本原因是使用java執(zhí)行shell時(shí),如果不讀取標(biāo)準(zhǔn)輸出,這個(gè)輸出就會(huì)輸出到缺省緩沖區(qū),如果輸出流太大,必將打滿緩沖區(qū),導(dǎo)致程序hang住。
          從上面問題現(xiàn)場(chǎng)的手工執(zhí)行中可以看到,因?yàn)榧虞d的數(shù)據(jù)量很大大,結(jié)果輸出也流非常大,這很容易超出缺省緩沖區(qū)大小。

          ?

          4 解決方案

          問題已經(jīng)很明確了,解決方案也就有了,處理sqlldr的輸出就可以解決。解決方法有下面三種。

          4.1 增加參數(shù)

          在sqlldr命令后面增加一個(gè)參數(shù),silent=(ALL),最后命令如下:

          sqlldr?test/test123@biz?control=/home/jinjunzhu/biz/T_BIZ.ctl?log=/home/jinjunzhu/biz/T_BIZ.log?bad=/home/jinjunzhu/biz/T_BIZ.bad?silent=(ALL)

          4.2 程序讀取標(biāo)準(zhǔn)輸出

          程序中讀取sqlldr命令返回的輸出,修改后的代碼如下:

          private?int?execute(String?cmd)?throws?Exception{
          ????Process?process?=?Runtime.getRuntime().exec(new?String[]{"/bin/bash",?"-c",?cmd});
          ????process.waitFor(10,?TimeUnit.SECONDS);
          ????Integer?status;

          ????BufferedReader?br?=?new?BufferedReader(new?InputStreamReader(process.getInputStream()));
          ????String?line;
          ????while?((line?=?br.readLine())?!=?null)?{
          ????????System.out.println(line);
          ????}
          ????return?(status?=?process.waitFor())?==?null???-1?:?status;
          }

          4.3 文件接收標(biāo)準(zhǔn)輸出

          可以在sqlldr命令中增加文件參數(shù)來接收命令的標(biāo)準(zhǔn)輸出,最后我采用了這種方式,命令如下:

          sqlldr?test/test123@biz?control=/home/jinjunzhu/biz/T_BIZ.ctl?log=/home/jinjunzhu/biz/T_BIZ.log?bad=/home/jinjunzhu/biz/T_BIZ.bad?1>/home/jinjunzhu/biz/std.log?2>/home/jinjunzhu/biz/err.log

          ?

          5 總結(jié)

          這個(gè)問題剛出現(xiàn)的時(shí)候,一直以為是Oracle的問題,但是后來研究發(fā)現(xiàn),這個(gè)鍋真的不能讓Oracle來背。關(guān)于sqlldr命令的詳細(xì)參數(shù)介紹,已經(jīng)比較成熟,大家可以自行網(wǎng)絡(luò)查找。

          有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)

          歡迎大家關(guān)注Java之道公眾號(hào)


          好文章,我在看??

          瀏覽 32
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美性爱xxxx黑人xxxx | 豆花视频一区二区 | 亚洲AAA网 | 人人插人人射 | 中文字幕日韩精品人妻 |