作者 | 鄭松林
創(chuàng)新互聯(lián)建站主要從事網(wǎng)站制作、網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)木壘哈薩克,十余年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792
轉(zhuǎn)自 | 數(shù)據(jù)和云
微信號 | OraNews
分析一次SQL并行執(zhí)行的產(chǎn)生過程
1、并行引起的災(zāi)禍
一大早,某網(wǎng)省兄弟告訴我,數(shù)據(jù)庫會話執(zhí)行的SQL開啟了并行,導致負載很高,會話也高,查了半天,沒找到具體原因,也不知道該如何解決?
對于他的問題,我直接回應(yīng)了:這還不清楚嗎?常見原因無非有以下兩個:
第一:對象開啟了并行(包括索引和表)
第二:SQL語句里面使用了PARALLEL的HINTS
現(xiàn)場兄弟說,都查了并沒有上面的情況,聽到他的回答,我首先對他查詢的方式持懷疑態(tài)度的,沒有設(shè)置并行度,也沒有加HINTS,執(zhí)行的SQL怎么會并行執(zhí)行呢?帶著這個疑問,我叫現(xiàn)場兄弟把查詢結(jié)果一一截圖給我,如下(文中案例都是事后補充):
看到結(jié)果后我一時也有點摸不著頭腦,怎么回事?遇到問題我總是告訴自己要冷靜,不急。
2、層層推進,分析問題
是不是什么參數(shù)控制了?
SQL> show parameter parallel
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
fast_start_parallel_rollback string LOW
parallel_adaptive_multi_user boolean TRUE
parallel_automatic_tuning boolean FALSE
parallel_degree_limit string CPU
parallel_degree_policy string MANUAL
parallel_execution_message_size integer 16384
parallel_force_local boolean FALSE
parallel_instance_group string
parallel_io_cap_enabled boolean FALSE
parallel_max_servers integer 320
parallel_min_percent integer 0
parallel_min_servers integer 0
parallel_min_time_threshold string AUTO
parallel_server boolean FALSE
parallel_server_instances integer 1
parallel_servers_target integer 128
parallel_threads_per_cpu integer 2
recovery_parallelism integer 0
沒有發(fā)現(xiàn)可疑參數(shù)。
至此,表面排查的結(jié)果已經(jīng)解決不了這個問題了,于是我讓現(xiàn)場找了一條正在并行的SQL ,手動執(zhí)行,并收集一個10053事件trace,看看是否能有新發(fā)現(xiàn)。腳本如下
很快現(xiàn)場提供了TRACE FILE文件給我,我優(yōu)先看參數(shù)列表。
這時,我發(fā)現(xiàn)一個可疑的參數(shù):parallel_query_default_dop = 16
找到mos上關(guān)于該參數(shù)的相關(guān)信息,是一個默認并行度的參數(shù),該參數(shù)值的算法如下:
DEFAULT DOP = cpu_count * parallel_threads_per_cpu* cluster_database_instances
我立刻問現(xiàn)場同事,執(zhí)行的SQL在活動會話中體現(xiàn)的是不是16個并行進程。現(xiàn)場同事答復我,觀察到的基本就是。至此問題明朗起來了,執(zhí)行的SQL使用了默認并行度執(zhí)行,受參數(shù)parallel_query_default_dop控制。既然是默認的并行度,那也應(yīng)該需要設(shè)置(如果不設(shè)置,默認是1)。于是我把前期的查詢驗證對象并行度是否開啟的SQL改造了下,具體如下(文中案例都是事后補充)
查詢結(jié)果截圖發(fā)出來,我就開心了,這里明顯有一個設(shè)置了并行度為DEFAULT(如果我們不設(shè)置就是1)的表和索引。然后確認了他們正是正在運行的sql中的對象。
3、問題解決
既然設(shè)置了默認并行度,那么只需要取消默認并行度即可,即執(zhí)行如下SQL
--針對表
alter table table_name noparalle;
--針對索引
Alter index index_name noparallel;
于是我叫現(xiàn)場把對象并行度修改為1,再次執(zhí)行該SQL,發(fā)現(xiàn)并行消失了,數(shù)據(jù)庫恢復了正常。
問題雖然解決了,但還有一個疑問沒有解開,什么情況下會設(shè)置的并行度為DEFUALT呢?正常創(chuàng)建索引和表都是1。
4、如何設(shè)置并行度為default
通過實踐發(fā)現(xiàn)如下2種方式可以實現(xiàn)并行度設(shè)置為DEFAULT。
1、創(chuàng)建表的時候指定:
2、創(chuàng)建表之后可以修改
小結(jié):該問題解決第一個是思路 ,第二個是基本功要扎實。
1
DB升級之后,DBLINK引起執(zhí)行計劃異常分析
背景如下:某網(wǎng)省采集中間庫從10.2.0.4升級到11.2.0.4(備注升級不是在老的機器上面直接升級,而是在新機器上面采用安裝遷移的方式)
升級完第二天現(xiàn)場找到我,說以前同步檔案數(shù)據(jù)的接口功能目前都運行非常慢(數(shù)據(jù)接口同步的方式采用的DBLINK),有時甚至無法正常運行完,影響檔案資料的同步,看來已經(jīng)很嚴重了。
關(guān)鍵字:DB升級從10G升級到11G
我以前遇到過相關(guān)案例,覺得可能是升級帶來的執(zhí)行計劃變化引起的。于是告知現(xiàn)場嘗試修改優(yōu)化器參數(shù)即optimizer_features_enable改成10.2.0.4,可以在線改,立刻生效,腳本如下:
alter system set optimizer_features_enable='10.2.0.4' scope=both;
修改完成后,重新在執(zhí)行同步檔案資料接口的任務(wù)看是否正常。
現(xiàn)場經(jīng)過一番測試之后,問題沒有解決,看來老的經(jīng)驗無法解決該問題。
好,接下來我們做了以下模擬測試:
該SQL的文本如下:
INSERT INTO EPCT.C_CUST_ADDR@EPEXDB
(CUST_ID,
CUST_ADDR,
PROVINCE_CODE,
CITY_CODE,
COUNTY_CODE,
STREET_CODE,
VILLAGE_CODE,
ROAD_CODE,
COMMUNITY_CODE,
PLATE_NO,
TYPE_CODE,
POSTALCODE,
CA_ID,
APP_NO)
SELECT A2.CUST_ID,
A2.CUST_ADDR,
A2.PROVINCE_CODE,
A2.CITY_CODE,
A2.COUNTY_CODE,
A2.STREET_CODE,
A2.VILLAGE_CODE,
A2.ROAD_CODE,
A2.COMMUNITY_CODE,
A2.PLATE_NO,
A2.TYPE_CODE,
A2.POSTALCODE,
A2.CA_ID,
''
FROM SGPM.C_CUST_ADDR A2
WHERE A2.CUST_ID=ANY
(SELECTA3.CUST_ID
FROM SGPM.C_CONS A5,
SGPM.R_CP_CONS_RELA A4,
SGPM.C_CUST A3
WHERE A4.CONS_ID=A5.CONS_ID
AND A4.CP_NO=:B1
ANDA5.CUST_ID=A3.CUST_ID);
可以看到是用到DBLINK從A數(shù)據(jù)庫到B數(shù)據(jù)庫的插入語句,這個SQL發(fā)起端在A數(shù)據(jù)庫,也就是程序部署在A數(shù)據(jù)庫中,而該SQL實際執(zhí)行端在B數(shù)據(jù)庫。雖然是往B數(shù)據(jù)庫插入數(shù)據(jù),但是會派生一個查詢SQL到A數(shù)據(jù)庫取數(shù)。
針對INSERT INTO remote_table@dblink select * from local_table這種SQL執(zhí)行端都會在遠端,不是本地,無法使用HINTS driving_site指定執(zhí)行端。
2、然后會在A數(shù)據(jù)庫確認一下是否派生一個SQL,并且找到該SQLID
3、現(xiàn)場提供SQLID之后,我們可以獲取該sql執(zhí)行的相關(guān)信息:
select *from table(dbms_xplan.display_cursor('1ar4us01aj0hu',null,'ADVANCED'));
紅框里出現(xiàn)的字樣引起了我的注意,眼尖的DBA應(yīng)該很快會發(fā)現(xiàn)其中的貓膩。
對的,這里調(diào)用了一個內(nèi)部函數(shù)。這個函數(shù)的說明如下:
The internal Oracle function SYS_OP_C2C performs conversion
from one character set to another character set C(haracterSet)2C(haracterSet).
字符集之間的轉(zhuǎn)換。OK ,看到這里我問現(xiàn)場,新舊兩套B數(shù)據(jù)庫中字符集是什么? A數(shù)據(jù)庫字符集又是什么?
現(xiàn)場答復如下:
老的B數(shù)據(jù)庫字符集是utf-8
新的B數(shù)據(jù)庫字符集是zhs16gbk
而A數(shù)據(jù)庫字符集是utf-8
這個也就說明了,遷移到新采集中間庫之后性能急劇下降的原因找到了。
那么解決方式有如下2種方式:
第一修改字符集,保證源目標字符集一致。
第二創(chuàng)建函數(shù)索引。
2
域索引導致提交報告的展開討論
域索引導致提交報錯
最近處理了一個網(wǎng)省的問題,現(xiàn)場反饋提交報錯 ,報錯如下:
COMMIT;
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20000: Oracle Text error:
DRG-50610: internal error: drexdsync
DRG-50857: oracle error in drekrtd (reselect rowid row locator)
ORA-00942: table or view does not exist
ORA-06512: at "CTXSYS.SYNCRN", line 1
ORA-06512: at line 1
看到這個錯誤,我們獲取到如下信息
1、這個是關(guān)于域索引的報錯
2、這個是遞歸SQL導致的報錯
3、這個是報表或者視圖不存在(最大可能是權(quán)限 或者可能就是真不存在)
見到這個錯誤,首先找現(xiàn)場核實下權(quán)限問題,包括操作用戶的權(quán)限
核查結(jié)果并沒有異常。
進一步分析:
1、查詢域索引信息
Select * from ctxsys.ctx_indexes
2、創(chuàng)建一個域索引會自動創(chuàng)建屬性為BASIC_STORAGE的四個二級表對象和一個索引對象出來
BASIC_STORAGE has the following attributes:
i_table_clause Parameter clause for dr$<indexname>$I table creation.
The I table is the index data table.
k_table_clause Parameter clause for dr$<indexname>$K table creation.
The K table is the keymap table.
r_table_clause Parameter clause for dr$<indexname>$R table creation.
The R table is the rowid table.
n_table_clause Parameter clause for dr$<indexname>$N table creation.
The N table is the negative list table.
i_index_clause Parameter clause for dr$<indexname>$X index creation.
大家可以在自己的環(huán)境中使用如下SQL查詢
Select owner,object_name,object_type,secondary,status
from dba_objects
where owner ='SGPM'
and object_name like 'DR$INDEX_NAME$%' --INDEX_NAME修改為你實際的名稱
現(xiàn)場查詢結(jié)果為空,說明域索引已經(jīng)不存在了,從而導致提交報錯,也就是遞歸執(zhí)行域索引的SQL報錯。
問題定位到,解決問題的辦法很容易:
重建域索引即可。
我這里給出的例子指出了域索引的實際存儲表空間位置,目的就是可控,如果不指定就是創(chuàng)建用戶所在默認的表空間。
begin
--創(chuàng)建詞法分析
--ctx_ddl.create_preference ('chinese_lexer', 'chinese_lexer');
--存儲參數(shù)
ctx_ddl.create_preference('t1_stor','BASIC_STORAGE');
ctx_ddl.set_attribute('t1_stor','I_TABLE_CLAUSE','tablespace TEST');
ctx_ddl.set_attribute('t1_stor','I_INDEX_CLAUSE','tablespace TEST');
ctx_ddl.set_attribute('t1_stor','K_TABLE_CLAUSE','tablespace TEST');
ctx_ddl.set_attribute('t1_stor','R_TABLE_CLAUSE','tablespace TEST');
ctx_ddl.set_attribute('t1_stor','N_TABLE_CLAUSE','tablespace TEST');
end;
--創(chuàng)建域索引 指定storage參數(shù)和lexer詞法分析器參數(shù)
create index idx1_t1 on t1(object_name) indextype is ctxsys.context parameters ('lexer chinese_lexer storage t1_stor');
--同步域索引數(shù)據(jù):(該操作有風險業(yè)務(wù)低估操作)
查詢確認域索引是否需要同步
select u.username, i.idx_name
from ctxsys.dr$index i, dba_users u
where u.user_id=i.idx_owner#
and idx_id in (select pnd_cid from ctxsys.dr$pending);
exec ctx_ddl.sync_index('IDX1_T1');
--優(yōu)化域索引數(shù)據(jù)(該操作有風險業(yè)務(wù)低估操作)
exec ctx_ddl.optimize_index ('IDX1_T1', 'full');
3
作者簡介
鄭林松,朗新科技股份有限公司數(shù)據(jù)庫技術(shù)專家,從業(yè)10多年,主要服務(wù)移動運營商客戶,電力客戶,證券客戶,制造業(yè)客戶。精通 Oracle 性能優(yōu)化,故障診斷和處理,也擅長MySQL數(shù)據(jù)庫優(yōu)化和故障處理。主要負責朗新公司國家電網(wǎng)12個網(wǎng)省性能優(yōu)化和故障處理工作以及南方電網(wǎng)性能優(yōu)化和故障處理工作,主導過某證券公司冷熱數(shù)據(jù)隔離和空間回收工作(總數(shù)據(jù)量100T),主持過某電網(wǎng)公司XTTS遷移工作;電網(wǎng)公司核心營銷系統(tǒng)歷史數(shù)據(jù)空間回收和高水位處理工作,合計回收空間15T。
文章題目:那些年,我們處理過的SQL問題
文章起源:http://www.rwnh.cn/article32/jiphsc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、動態(tài)網(wǎng)站、移動網(wǎng)站建設(shè)、域名注冊、App設(shè)計、外貿(mào)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)