기술 정보
home
채널 소개
home

통계 수집 중 ERROR_OPT_INVALID_HISTOGRAM_NDV(-28018) 오류 발생

문서 유형
장애 해결
분야
관리/환경설정
키워드
dbms_stats
ERROR_OPT_INVALID_HISTOGRAM_NDV
FREQEUNCY
HEIGHT
HISTOGRAM
SET_COLUMN_STATS
적용 제품 버전
7FS02PS
오류코드
28018

현상

통계 수집 과정에서 ERROR_OPT_INVALID_HISTOGRAM_NDV(-28018) 오류가 발생하였습니다.
해당 오류는 AL_TRANSACTION_LOG_07, AL_TRANSACTION_LOG_08, AL_TRANSACTION_LOG_10 테이블의 STARTNODEID 컬럼에 대해 통계 수집을 수행하는 도중 발생하였으며, 해당 컬럼에 대한 통계 수집이 실패하였습니다.
sys.log
[2025-04-26T00:33:17.340918] [FRM-1084] [I] THROW. ec=ERROR_OPT_INVALID_HISTOGRAM_NDV(-28018) [ Invalid ndv on column 'AL_TRANSACTION_LOG_07.STARTNODEID' frequency histogram (Current value: 125). ] (sql_id:(null), sub_sql_id:fngnts8r3az36, user:SYS, ap_module:(null), program:JDBC Thin Client, host:prdteaiap01) [stat.c:230:stats_load_internal] [2025-04-26T00:33:17.340977] [OPT-1084] [I] Loading histogram of column AL_TRANSACTION_LOG_07.STARTNODEID failed. (obj_id=11431,col_no=14, ec=-28018) [2025-04-26T00:33:17.342202] [FRM-1084] [I] THROW. ec=ERROR_OPT_INVALID_HISTOGRAM_NDV(-28018) [ Invalid ndv on column 'AL_TRANSACTION_LOG_08.STARTNODEID' frequency histogram (Current value: 125). ] (sql_id:(null), sub_sql_id:fngnts8r3az36, user:SYS, ap_module:(null), program:JDBC Thin Client, host:prdteaiap01) [stat.c:230:stats_load_internal] [2025-04-26T00:33:17.342222] [OPT-1084] [I] Loading histogram of column AL_TRANSACTION_LOG_08.STARTNODEID failed. (obj_id=11433,col_no=14, ec=-28018) [2025-04-26T00:33:17.347715] [FRM-1084] [I] THROW. ec=ERROR_OPT_INVALID_HISTOGRAM_NDV(-28018) [ Invalid ndv on column 'AL_TRANSACTION_LOG_10.STARTNODEID' frequency histogram (Current value: 143). ] (sql_id:(null), sub_sql_id:fngnts8r3az36, user:SYS, ap_module:(null), program:JDBC Thin Client, host:prdteaiap01) [stat.c:230:stats_load_internal] [2025-04-26T00:33:17.347740] [OPT-1084] [I] Loading histogram of column AL_TRANSACTION_LOG_10.STARTNODEID failed. (obj_id=11437,col_no=14, ec=-28018)
SQL
복사

원인

 sys._dd_hist_head 테이블 확인 결과
SQL> select * from sys._dd_hist_head where obj_id in (select obj_id from sys._dd_col where obj_id = (select obj_id from sys._dd_tbl where obj_id = (select obj_id from sys._dd_obj where name='AL_TRANSACTION_LOG_10' and subname is null)));
SQL
복사
HIST_HEAD_ID OBJ_ID COL_NO BUCKET_CNT NULL_CNT TIMESTAMP_NO SAMPLE_SIZE DISTINCT_CNT LOW_VAL HIGH_VAL DENSITY AVG_COL_SIZE RESERVED1 RESERVED2 RESERVED3 RESERVED4 ------------ ---------- ---------- ---------- ---------- ------------------------------ ----------- ------------ -------------------------------------------------- -------------------------------------------------- ---------- ------------ ---------- ---------- ---------- --------------- ... 5965 11437 14 2992160 0 2025/04/10 17:18:39 149608 1000 I_TBIL_SVR1 I_TRAT_SVR1 .0001 11 7 0 0 0 ...
SQL
복사
obj_id = 11437, col_no = 14(STARTNODEID 컬럼)의 통계 정보 중 bucket_cnt = 2,992,160, distinct_cnt = 1000으로 설정되어 있었습니다.
내부 로직에서는 bucket_cnt > distinct_cnt인 경우 해당 히스토그램을 Frequency 히스토그램으로 인식합니다. 하지만 Frequency 히스토그램의 정의상 distinct_cnt는 반드시 1이어야 하며, 현재는 1000으로 되어 있어 오류가 발생하게 됩니다.
과거에 DBMS_STATS.SET_COLUMN_STATS를 이용하여 통계 정보를 수동 조작한 이력이 확인되었습니다.
EXEC dbms_stats.set_column_stats( ownname => 'BSSDBA', tabname => 'AL_TRANSACTION_LOG_16', colname => 'STARTNODEID', distinct => 1000, density => 0.001, force => TRUE);
SQL
복사
이 과정에서 통계(특히 NDV)가 잘못 보정되었으며, 이후 통계 수집 시 height histogram 수집 후 distinct_cnt를 보정하는 로직에도 문제가 있어 동일 현상이 반복되었습니다.
Tibero 내부적으로 NDV 보정 로직이 미흡한 부분이 있었던 것으로 보이며, 예를 들어 기존 bucket_cnt와 NDV의 관계를 다시 검증하지 않고 무조건 NDV를 덮어써 "bucket_cnt > NDV" 구조가 유지되었습니다.
이로 인해 height histogram임에도 내부 로직상 Frequency 히스토그램으로 해석되어 오류가 발생하게 되었습니다.

해결

문제 컬럼들에 대해 통계를 재수집하여 NDV 및 히스토그램 정보를 정정합니다.
또는, DBMS_STATS.DELETE_COLUMN_STATS 함수를 사용하여 해당 컬럼의 통계 정보를 삭제하고 기본 통계로 작동하도록 변경할 수 있습니다.
SQL> EXEC DBMS_STATS.DELETE_COLUMN_STATS (ownname=> ' ' , tabname=> ' ', colname=>' ');
SQL
복사
height histogram 수집 시 distinct_cntbucket_cnt보다 작게 보정되는 사례를 방지할 수 있도록, 내부 로직 상 방어 코드가 개선될 예정입니다.
참고
DBMS_STATS.SET_COLUMN_STATS 함수 사용 시 주의사항
Height 히스토그램을 사용하는 경우, distinct_cnt 값을 bucket_cnt보다 크게 설정해서는 안 됩니다.
임의 조정할 경우, Frequency/Height 히스토그램의 기준에 어긋날 수 있으므로 일관성을 반드시 유지해야 합니다.
Frequency Histogram (도수 분포형 히스토그램)
하나의 값이 하나의 bucket을 차지하는 방식입니다.
NDV (Number of Distinct Values) ≤ Bucket 개수
Frequency 히스토그램인 경우에는 distinct_cnt 값이 반드시 1이어야 정상입니다.
Height-balanced Histogram (높이 균형형 히스토그램)
각 bucket에 동일한 개수의 record가 분배되도록 수집됩니다.
NDV가 bucket 개수보다 클 경우 사용되며, bucket이 256개를 초과할 경우 Height-balanced 히스토그램을 강제 적용합니다.
bucket_cnt > distinct_cnt 인 경우 Frequency로 인식되는가?
Frequency 히스토그램은 "하나의 값 = 하나의 bucket" 구조로 수집되기 때문에
bucket_cntdistinct_cnt보다 많아야 한다는 정의가 전제되어 있습니다.
따라서, 내부 로직에서는 bucket_cnt > distinct_cnt 조건이 만족되면 해당 히스토그램을 Frequency 유형으로 간주하게 됩니다.