Programming/Oracle

ORACLE 캐릭터셋 변경~하기

초록깨비 2008. 12. 2. 09:31
728x90

SHUTDOWN IMMEDIATE;
<do a full backup>
SQL> STARTUP MOUNT;
SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;
SQL> ALTER DATABASE OPEN;
SQL> ALTER DATABASE CHARACTER SET KO16MSWIN949;
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP;


SQL> SHUTDOWN IMMEDIATE;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.

Total System Global Area  171966464 bytes
Fixed Size                   777956 bytes
Variable Size             145760540 bytes
Database Buffers           25165824 bytes
Redo Buffers                 262144 bytes
Database mounted.
SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;

System altered.

SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0
  2  ;

System altered.

SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;

System altered.

SQL> ALTER DATABASE OPEN
  2  ;

Database altered.

SQL> ALTER DATABASE CHARACTER SET KO16MSWIN949;

Database altered.

-- 한편 현재 캐릭터셋의 Superset이 아닌 캐릭터셋으로는 변경이 불가능하다.

SQL> ALTER DATABASE CHARACTER SET WE8DEC;
ALTER DATABASE CHARACTER SET WE8DEC
*
ERROR at line 1:
ORA-12712: new character set must be a superset of old character set

-- 다시 데이터베이스를 재구동하면 이제 어엿한 KO16MSWIN949 데이터베이스가 되어 있다.

C:\Documents and Settings\jwryoo>set NLS_LANG=.KO16MSWIN949

C:\Documents and Settings\jwryoo>sqlplus scott/tiger@KSC5601

데이터 마이그레이션

준비작업
데이터베이스 컬럼 길이 점검 : 데이터 자체가 변경되므로 데이터의 길이 또한 변경될 수 있다.
애플리케이션 점검 : 애플리케이션 또한 스키마 및 캐릭터셋 변경으로 인해 영향을 받지 않는지 점검한다. 특히 UTF8으로 갈 경우, 한글을 2바이트로 가정하고 작성한 코드가 없는지 점검한다.
CSSCAN 실행
CSSCAN은 캐릭터셋 변경시 발생할 수 있는 문제점을 미리 감지하고 보고서를 생성해준다는 점에서 매우 유용하다. 비록 이것을 실행하는 것이 완전히 필수적인 요소라고 할 수는 없어도(CSALTER 방식에서는 필수, 지난 일주일 내에 CSSCAN을 수행한 결과가 있어야 함) 지금 보유하고 있는 데이터가 소중하다고 생각된다면 반드시 돌려보는 것이 좋을 것이다.


1) CSSCAN 설치
SQL> connect / as sysdba
Connected.
SQL> @/home/oracle/oracle/rdbms/admin/csminst.sql

2) CSSCAN 구동
[oracle@krrnddel oracle]$ csscan system/..

Connected to:
Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Production
With the Partitioning, OLAP and Data Mining options

(1)Full database, (2)User, (3)Table: 1 > 2

Current database character set is KO16KSC5601.

Enter new database character set name: > KO16MSWIN949

Enter array fetch buffer size: 102400 >

Enter number of scan processes to utilize(1..32): 1 >

Enter user name to scan: > SCOTT

Enumerating tables to scan...

. process 1 scanning SCOTT.DEPT[AAAL+oAAEAAAAAJAAA]
. process 1 scanning SCOTT.EMP[AAAL+qAAEAAAAAZAAA]
. process 1 scanning SCOTT.BONUS[AAAL+sAAEAAAAApAAA]
. process 1 scanning SCOTT.TESTTBL[AAAME1AAEAAAAA5AAA]
. process 1 scanning SCOTT.KANGYS[AAAME5AAEAAAABBAAA]
. process 1 scanning SCOTT.DEPTENTITY_GRADUATE_DEPTCOMP[AAAMI8AAEAAAABJAAA]
. process 1 scanning SCOTT.DEPTENTITY_DEPT_DEPTCOMP[AAAMJAAAEAAAAB5AAA]
. process 1 scanning SCOTT.NLSTECH_SAMPLE_SORT_KOREAN_M[AAAMm8AAEAAAABZAAA]
. process 1 scanning SCOTT.NLSTECH_SAMPLE_SORT_KSC5601[AAAMm9AAEAAAACBAAA]
. process 1 scanning SCOTT.CHARSET_TEST[AAAMwLAAEAAAACJAAA]
. process 1 scanning SCOTT.T[AAAM9IAAEAAAACRAAA]

Creating Database Scan Summary Report...

Creating Individual Exception Report...

Scanner terminated successfully.

$ ls scan*
scan.err  scan.out  scan.txt
 


scan.out : STDOUT에 출력된 결과를 저장해 놓은 파일

scan.err : 캐릭터셋 변경시 손실되는 데이터

scan.err의 내용물 예:

[Application data individual exceptions]

User  : SCOTT
Table : TESTTBL
Column: VAL
Type  : VARCHAR2(100)
Number of Exceptions         : 1
Max Post Conversion Data Size: 6

ROWID              Exception Type      Size Cell Data(first 30 bytes)
------------------ ------------------ ----- ------------------------------
AAAME1AAEAAAAA9AAA lossy conversion         <8c>c
------------------ ------------------ ----- ------------------------------
...
 


scan.txt : 종합 보고서. 다음 예에 나온 섹션들이 가장 핵심적인 부분이라 하겠다. Data Dictionary 분석 테이블이 비어 있는 것은위의 CSCSAN 실행을 User단위로(SCOTT 사용자에 한해) 테스트를 했기 때문이다. 새로운 캐릭터셋에서도 변경이 없는 데이터(Changeless, 주로 아스키 영문 데이터)와 변경 가능한(Convertible) 데이터들의 합이 정상적으로 마이그레이션되는 데이터의 비중을 보여준다.

Truncation : 변경 후 Truncate될 데이터
Lossy : 변경 후 손상될(깨질) 데이터


...
[Data Dictionary Conversion Summary]

Datatype                    Changeless      Convertible       Truncation            Lossy
--------------------- ---------------- ---------------- ---------------- ----------------
VARCHAR2                             0                0                0                0
CHAR                                 0                0                0                0
LONG                                 0                0                0                0
CLOB                                 0                0                0                0
VARRAY                               0                0                0                0
--------------------- ---------------- ---------------- ---------------- ----------------
Total                                0                0                0                0
Total in percentage              0.000%           0.000%           0.000%           0.000%


[Application Data Conversion Summary]

Datatype                    Changeless      Convertible       Truncation            Lossy
--------------------- ---------------- ---------------- ---------------- ----------------
VARCHAR2                            37               20                1                5
CHAR                                 0                0                0                0
LONG                                 0                0                0                0
CLOB                                 4                0                0                0
VARRAY                               0                0                0                0
--------------------- ---------------- ---------------- ---------------- ----------------
Total                               41               20                1                5
Total in percentage             61.194%          29.851%           1.493%           7.463%

[Distribution of Convertible, Truncated and Lossy Data by Table]

USER.TABLE                                              Convertible       Truncation            Lossy
-------------------------------------------------- ---------------- ---------------- ----------------
SCOTT.CHARSET_TEST                                                0                0                3
SCOTT.DEPTENTITY_DEPT_DEPTCOMP                                    2                1                0
SCOTT.NLSTECH_SAMPLE_SORT_KOREAN_M                                5                0                0
SCOTT.NLSTECH_SAMPLE_SORT_KSC5601                                 5                0                0
SCOTT.T                                                           0                0                1
SCOTT.TESTTBL                                                     8                0                1
-------------------------------------------------- ---------------- ---------------- ----------------

[Distribution of Convertible, Truncated and Lossy Data by Column]

USER.TABLE|COLUMN                                       Convertible       Truncation            Lossy
-------------------------------------------------- ---------------- ---------------- ----------------
SCOTT.CHARSET_TEST|CHARCOL                                        0                0                3
SCOTT.DEPTENTITY_DEPT_DEPTCOMP|DNAME                              2                1                0
SCOTT.NLSTECH_SAMPLE_SORT_KOREAN_M|TEXT                           5                0                0
SCOTT.NLSTECH_SAMPLE_SORT_KSC5601|TEXT                            5                0                0
SCOTT.T|SVAL                                                      0                0                1
SCOTT.TESTTBL|VAL                                                 8                0                1
-------------------------------------------------- ---------------- ---------------- ----------------

[Indexes to be Rebuilt] : 캐릭터셋 변경 후 재생성되어야 하는 인덱스들의 리스트

USER.INDEX on USER.TABLE(COLUMN)                                                        
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
 


 이 결과를 보면 어떤 테이블의 어떤 행에서 어떤 컬럼에 어떤 데이터가 손상이 될 수 있는지 살펴볼 수 있다. 단 US7ASCII 데이터베이스에 한글을 저장해 놓고 KO16MSWIN949 또는 UTF8로 데이터 마이그레이션 및 캐릭터셋 변환이 가능한지 CSSCAN을 돌려보고 싶다면 그러지 않기를 권장한다. 그것은 불가능하다는 것은 명백하고 잘못하면 엄청난 크기의 리포트만을 하염없이 기다려야 할 지도 모른다.

그런데 데이터 딕셔너리에는 Changeless만 있는 것이 사실 가장 안전하다. 변경 가능한(Convertible) 데이터가 존재하는 것이 100% 나쁘다고 할 수는 없겠지만, 딕셔너리가 수정되었을 때의 파장은 알 수 없으므로 이는 조심해야 한다.

CLOB에 저장된 데이터 : US7ASCII에서는 CLOB에 있는 데이터 역시 US7ASCII 형식으로 저장되지만, KO16MSWIn949나 UTF8같은 멀티바이트 캐릭터셋에서는 데이터가 UCS-2와 호환되는 고정 바이트로 CLOB에 저장된다. 따라서, US7ASCII에서 다른 멀티바이트 캐릭터셋으로 마이그레이션하려고 CSSCAN을 구동했을 때에는 CLOB내의 데이터는 모두 Changeless가 아니라 Convertible로 처리될 것이다.
당연한 이야기이지만, 캐릭터들은 기존 캐릭터셋과 새로운 캐릭터셋에 모두 존재하지만 실제 바이너리값에서는 차이가 있다. KO16MSWIN949에서의 "가"(176 160)와 UTF8에서의 "가"(234 176 128)는 엄연히 바이너리 값이 다르다. 따라서, 멀티바이트(한글)로 테이블명이나 인덱스명을 생성했을 때 CSSCAN은 이들을 Convertible로 처리할 것이다.

exp/imp를 사용하여 새로운 데이터베이스로 데이터와 딕셔너리를 마이그레이션할 것이 아니라면(CSALTER를 사용할 것이라면), 오라클은 안전을 위해 CLOB에 들어있지 않은 딕셔너리 Convertible 데이터들을 마이그레이션 전에 처리할 것을 권장한다

한글 이름으로 된 테이블 이름 변경
한글 이름으로 된 테이블 및 객체들은 exp후 drop시키고, 마이그레이션 후 다시 imp한다
기타 딕셔너리에서 Lossy나 Corrupted된 데이터가 발생한다면 이는 심각하며 반드시 전문가나 오라클 기술 지원 인력과 상의해야 할 문제이다.

exp/imp를 이용한 변경
전통적인 백업 방식을 이용하여 마이그레이션하는 방법으로 다른 버전의 데이터베이스들끼리의 데이터 마이그레이션 작업을 상당히 깔끔하게 할 수 있다는 장점이 있다. 하지만, exp가 잘되었다거나 imp가 잘 되었다는 것이 데이터가 안전하게 저장되었다는 것을 검증해 주지는 못한다. 예를 들어 KO16KSC5601 데이터베이스에서 exp한 파일에 잘못된 데이터(숖)이 있다고 하더라도 이것을 다시 UTF8 데이터베이스에 imp했을 때 그것을 발견하지 못한다. exp/imp에 대해서는 앞서 충분히 보여주었으므로 따로 예제를 들지 않겠다. NLS_LANG 변수값의 설정이 매우 중요하다는 사실은 확실히 기억하기 바란다.

CSALTER를 이용한 변경
실제 CSALTER를 수행하기 전에 반드시 Full Database Scan이 이루어져야 한다. 그렇지 않으면 다음과 같은 메시지를 만나게 될 것이다.

SQL> @@/home/oracle/oracle/rdbms/admin/csalter.plb normal

0 rows created.


Function created.


Function created.


Procedure created.

This script will update the content of the Oracle Data Dictionary.
Please ensure you have a full backup before initiating this procedure.
Would you like to proceed ?(Y/N)?y
..
Full database scan is required

csalter.plb는 SYS사용자만이 수행할 수 있고, 수행 시점에서 이 데이터베이스에 접속된 유일한 세션이어야 한다. 그리고 반드시 새로운 캐릭터셋은 기존 캐릭터셋의 Superset이어야 한다. 한글 지원 캐릭터셋과 US7ASCII 캐릭터셋들의 Subset-Superset 관계는 앞서 ALTER DATABASE 방식을 설명하는 중 소개된 테이블을 참조하기 바란다.


글을 마치며
캐릭터셋 변경은 필요하고도 위험하다. 캐릭터셋을 잘못 사용해 왔다는 사실을 알게 되는 시점부터 운영자는 고민에 빠진다. 캐릭터셋을 잘못 사용해 왔다는 것은 그 상단의 애플리케이션조차도 잘못되어 있을 가능성이 높다는 의미이다. 따라서, 데이터를 잘 보존하면서 캐릭터셋을 옮기는 것도 리스크가 크지만, 그 상단의 애플리케이션 또한 다시 디버깅하고 테스팅해야 한다는 사실 또한 운영자에게 두려움으로 다가올 수 있다.

캐릭터셋 변경에 대한 방식을 충분히 습득하자
캐릭터셋 변경에 따른 위험성을 충분히 이해하자
캐릭터셋 변경에 대한 관계자들의 폭넓은 동의가 확보하자
캐릭터셋 변경 전에 반드시 변경을 되돌릴 수 있는 장치를 마련하자
캐릭터셋 변경 전에 충분히 테스트 DB로 테스트하자

728x90