Undo segment를 과도하게 사용하여

예를 들어, 개발한 배치, 개발자의 임의 작업 등이 잘못 진행되고 있다가 뒤늦게 발견하여 cancel했을 경우라던가 할 때

이를 rollback을 하는 중이지만 UNDO tablespace의 unexpire 영역이 반환되지 않아,

정규 배치 등의 서비스가 실패할 가능성이 있는 시나리오에 대응하려면

다음 쿼리들을 통해 문제를 해결하도록 한다.



Rollback 진행 중인 undo segment를 조회하는 쿼리


parallel rollback 일 경우

select * from v$fast_start_transactions where state='RECOVERING';


serial rollback 일 경우 (x$KTUXE(Kernel Transaction Undo Transaction Entry))

select ktuxesiz from sys.xm$ktuxe where ktuxesta = 'ACTIVE' and KTUXECFL = 'DEAD' ;


Undo tablespace의 사용량은 다음과 같이 확인한다.

col msg format a80
WITH TB AS (
    SELECT TABLESPACE_NAME
          ,(SELECT ROUND(SUM(BLOCKS)*8/1024) FROM DBA_DATA_FILES WHERE TABLESPACE_NAME=A.TABLESPACE_NAME) TOT_MB
          ,SUM(DECODE(A.STATUS,'ACTIVE'   ,SIZE_MB,0)) ACTIVE_MB
          ,SUM(DECODE(A.STATUS,'UNEXPIRED',SIZE_MB,0)) UNEXPI_MB
          ,SUM(DECODE(A.STATUS,'EXPIRED'  ,SIZE_MB,0)) EXPIRE_MB
    FROM  (
           SELECT TABLESPACE_NAME, STATUS, ROUND(SUM(BYTES)/1024/1024) SIZE_MB
           FROM   DBA_UNDO_EXTENTS
         --WHERE  tablespace_name in ( select value from v$parameter where name='undo_tablespace')
           GROUP  BY TABLESPACE_NAME, STATUS
          ) A
    GROUP BY TABLESPACE_NAME
)
SELECT to_char(sysdate,'HH24:MI:SS')||' '||TABLESPACE_NAME||' : '||round((active_mb+unexpi_mb+expire_mb)/tot_mb*100)||
       ' % -> Act('||active_mb||') Unexp('||unexpi_mb||') Exp('||expire_mb||') TOT('||TOT_MB||')' MSG,
       round(100*(ACTIVE_MB)/TOT_MB,2),
       round(100*(ACTIVE_MB+UNEXPI_MB)/TOT_MB,2)
FROM TB;


현재 진행되고 있는 rollback의 잔여시간은 다음 쿼리로 대충 추산할 수 있다.

set serveroutput on
declare
    l_start number ;
    l_end   number ;
    r_min   number ;
begin
    select ktuxesiz into l_start from sys.xm$ktuxe where ktuxesta = 'ACTIVE' and KTUXECFL = 'DEAD' ;
    dbms_lock.sleep(60);
    select ktuxesiz into l_end   from sys.xm$ktuxe where ktuxesta = 'ACTIVE' and KTUXECFL = 'DEAD' ;
    r_min := round(l_end / (l_start - l_end)  ) ;
    dbms_output.put_line('['||to_char(sysdate,'HH24:MI:SS')||'] Remain Time : '|| r_min ||'분 '|| round(r_min/60,2)||'시간 / '||(l_start-l_end)||' blocks done / '|| l_end ||' Total blocks remains' );
end ;
/


운영DB에 임시 UNDO Tablespace를 생성한 후, 향후의 트랜잭션들은 이 UNDO tbs를 사용하도록 조치한다.

create undo tablespace undotbs2 datafile '/dev/rdsk/vsp1_000_ra000/dat_000_20G_001';

alter tablespace undotbs2 add datafile '/dev/rdsk/vsp1_000_ra000/dat_000_20G_002';

...

alter tablespace undotbs2 add datafile '/dev/rdsk/vsp1_000_ra000/dat_000_20G_NNN';


alter system set undo_tablespace=undotbs2 ;

이때 UNDO tablespace를 변경하는 것 자체는 금방 수행되므로 긴장하지 않아도 된다.

다만, alert log에 'active transactions found in undo tablespace NN - moved to pending switch-out state 라는 로그가 트랜잭션 당 1 라인씩 계속 발생할 수 있는데, 어떤 사이트의 경우에는 이 메시지가 다량 발생하기도 하였다고 하므로, alert log가 존재하는 path의 가용량을 모니터링하면서 작업 수행하자.

이러한 세션들은 세션에서 commit을 찍고 알아서 종료되길 기다리거나, 아니면 kill하여 처리하면 된다.


UNDO tablespace를 switch 한 후, 이전의 UNDO tbs를 사용하는 채로 commit 되지 않고 남아있는 세션을 찾아본다

select a.usn, a.name, b.status, c.tablespace_name, d.addr, e.sid, e.serial#, e.username, e.program, e.machine, e.osuser
from   v$rollname a, v$rollstat b, dba_rollback_segs c, v$transaction d, v$session e
where  a.usn=b.usn
and    a.name = c.segment_name
and a.usn = d.xidusn
and    d.addr = e.taddr
and b.status = 'PENDING OFFLINE';


rollback이 종료되고 상황이 정상화 되면,

기존 UNDO tablespace를 사용하도록 파라미터를 재설정해주고,

추가했었던 UNDO tablespace를 drop하면 된다.

Posted by in0de
,

Windows 10 출시 1주년 업데이트를 통해 bash를 사용할 수 있게 되었다 (!)

다음과 같이 진행하면 Windows 10 bash 쉘을 설치한 후

root 유저의 패스워드를 변경하여 사용할 수 있다.

 

원칙적으로는 root 유저를 사용하기보다는

sudo 를 통해 수행할 커맨드만 root 권한으로 수행하는 게 맞겠지만

root 유저의 패스워드를 모르면 기분이 좋지 않으므로 바꿔두기로 한다.

 

 

 

C:\Users\in0de>bash
-- 베타 기능 --
이렇게 하면 Canonical에서 배포하고 다음에서 사용 가능한
조건에 따라 사용이 허가되는 Ubuntu가 Windows에 설치됩니다.
https://aka.ms/uowterms

계속하려면 "y" 입력: y
Windows 스토어에서 다운로드하는 중... 100%
파일 시스템을 추출하는 중... 몇 분 정도 걸립니다.
기본 UNIX 사용자 계정을 만드세요. 사용자 이름이 Windows 사용자 이름과 일치할 필요는 없습니다.
자세한 내용은 https://aka.ms/wslusers를 참조하세요.


새로운 UNIX 사용자 이름 입력: in0de
새 UNIX 암호 입력: ********
새 UNIX 암호 재입력: ********
passwd: password updated successfully
설치했습니다.
환경이 곧 시작됩니다.
https://aka.ms/wsldocs에서 설명서를 사용할 수 있습니다.

in0de@X:/mnt/c/Users/in0de$
in0de@X:/mnt/c/Users/in0de$ ls -la
합계 6792
drwxrwxrwx 2 root root       0  8월  9 22:26 .
dr-xr-xr-x 2 root root       0  8월  9 18:19 ..
drwxrwxrwx 2 root root       0  8월  9 18:18 AppData
drwxrwxrwx 2 root root       0  8월  9 19:44 Contacts
drwxrwxrwx 2 root root       0  8월  9 20:03 Desktop
drwxrwxrwx 2 root root       0  8월  9 19:44 Documents
drwxrwxrwx 2 root root       0  8월  9 22:57 Downloads
drwxrwxrwx 2 root root       0  8월  9 19:44 Favorites
drwxrwxrwx 2 root root       0  8월  9 19:44 Links
drwxrwxrwx 2 root root       0  8월  9 19:44 Music
                       ......
drwxrwxrwx 2 root root       0  8월  9 20:24 OneDrive
drwxrwxrwx 2 root root       0  8월  9 19:44 Pictures
drwxrwxrwx 2 root root       0  8월  9 19:44 Saved Games
drwxrwxrwx 2 root root       0  8월  9 19:44 Searches
drwxrwxrwx 2 root root       0  8월  9 19:44 Videos
-rwxrwxrwx 1 root root  262144  8월  9 18:18 ntuser.dat.LOG1
-rwxrwxrwx 1 root root  423936  8월  9 18:18 ntuser.dat.LOG2
-rwxrwxrwx 1 root root      20  8월  9 19:43 ntuser.ini

 

in0de@X:/mnt/c/Users/in0de$ cd /
in0de@X:/$ ls -la
합계 145
drwxr-xr-x 2 root root     0  1월  1  1970 .
drwxr-xr-x 2 root root     0  1월  1  1970 ..
drwxr-xr-x 2 root root     0  8월  9 22:58 acct
drwxr-xr-x 2 root root     0  3월 24 05:45 bin
drwxr-xr-x 2 root root     0  3월 24 05:54 boot
drwxrwx--- 2 root root     0  1월  1  1970 cache
drwxrwx--x 2 root root     0  1월  1  1970 data
drwxr-xr-x 2 root root     0  8월  9 22:56 dev
drwxr-xr-x 2 root root     0  8월  9 22:56 etc
drwxr-xr-x 2 root root     0  1월  1  1970 home
-rwxr-x--- 1 root root 38896  1월  1  1970 init
drwxr-xr-x 2 root root     0  3월 24 05:54 lib
drwxr-xr-x 2 root root     0  3월 24 05:42 lib64
drwx------ 2 root root     0  3월 24 05:46 lost+found
drwxr-xr-x 2 root root     0  3월 24 05:41 media
drwxr-xr-x 2 root root     0  1월  1  1970 mnt
drwxr-xr-x 2 root root     0  3월 24 05:41 opt
dr-xr-xr-x 1 root root     0  8월  9 22:56 proc
drwx------ 2 root root     0  1월  1  1970 root
drwxr-xr-x 2 root root     0  8월  9 22:56 run
drwxr-xr-x 2 root root     0  3월 24 05:45 sbin
drwxr-xr-x 2 root root     0  3월 24 05:41 srv
dr-xr-xr-x 1 root root     0  8월  9 22:56 sys
drwxrwxrwt 2 root root     0  8월  9 22:53 tmp
drwxr-xr-x 2 root root     0  3월 24 05:41 usr
drwxr-xr-x 2 root root     0  3월 24 05:45 var

 

 

in0de@X:/$ sudo su
[sudo] password for in0de: ********
root@X:/#
root@X:/# id
uid=0(root) gid=0(root) 그룹들=0(root)

root@X:/# passwd
새 UNIX 암호 입력: ********
새 UNIX 암호 재입력: ********
passwd: password updated successfully
root@X:/#
root@X:/# exit
exit
in0de@X:/$
in0de@X:/$ su -
암호: ********
root@X:~#

 

Posted by in0de
,

데이터가 많은 테이블의 건 수를 조회하려고 할 때

SQL0802N
Arithmetic overflow or other arithmetic exception occurred.
산술 오버플로우 또는 다른 산술 예외가 발생했습니다.


위와 같은 오류가 발생할 수 있다.


이는, MAX_LONGINT_INT 제약 (2,147,483,647) 보다 더 많은 건 수를 담고 있는 테이블에

SELECT COUNT 문을 수행했을 경우 발생하며


이 때는 COUNT_BIG 함수를 사용하면 정상적으로 수행할 수 있다.


select count_big(*) from HUGE_TABLE;


한편, INT 타입의 컬럼을 SUM 하다보면 INT 타입의 크기 제약으로 인해 산술 오버플로우가 발생할 경우도 있는데

이런 경우에는 CAST를 해서 SUM 하면 된다.

 

select SUM(CAST(col1 as BIGINT)) from TABLE;

select SUM(CONVERT(bigint, col1)) from TABLE;

Posted by in0de
,