• 참고 URL
    • JCA로 이해하는 암호화와 보안 : http://d2.naver.com/helloworld/197937
    • JCA로 이해하는 암호화와 보안2 : http://d2.naver.com/helloworld/227016
    • 안전한 패스워드 저장 : http://d2.naver.com/helloworld/318732
    • 암호화 알고리즘 종류와 관련 용어 : http://modoris.blogspot.kr/2011/11/blog-post_08.html
    • [KISA] 암호기술 구현 안내서 2013
    • http://ohgyun.com/433
    • http://dinguri.tistory.com/entry/Base643216-Encodings
    • update, doFinal 메서드 차이
    • wikipedia
      • https://en.wikipedia.org/wiki/Cryptographic_hash_function
      • https://en.wikipedia.org/wiki/Hash-based_message_authentication_code
      • https://ko.wikipedia.org/wiki/%EB%B2%A0%EC%9D%B4%EC%8A%A464
    • bcrypt cryptography


개념은 알지만 막상 구현하려니 헷갈리던 암호화,, Java에서는 다행히도 javax.crypto 패키지 하위의 클래스를 통해 보안 관련 기능을 제공하고있다.
위의 URL들은 암호화/복호화의 개념을 잡을수 있도록 잘 정리된 페이지이며, 이를 바탕으로 나중에 참고하기 위해 간단히 정리해보고자 한다 :3
나름대로 정리한 자료지만 혹시 틀릴수도 있으니 참고 URL이나 미심쩍을때는 최신 정보를 검색해보는것을 추천함.


MesasgeDigest

MD5, SHA1과 같은 알고리즘이 MessageDigest(해시)의 대표적인 알고리즘이다.
다른말로는 체크섬(checksum)이라는 명칭으로도 불리며, 원본파일(메시지)가 그대로인지 파악하는 무결성 검사에 사용한다.
이 알고리즘들은 다양한 길이의 입력값을 고정길이의 해시값으로 출력하며, 단방향 알고리즘이므로 해시값에서 역으로 원본값을 추출할 수 없다.
때문에 패스워드를 암호화 할 때, 원본 패스워드의 노출을 막기 위해 해시값으로 변환하여 저장하고, 마찬가지로 비밀번호 검증시에도 해시화된 값이 동일한지로 비교하게된다.

[대표적인 해쉬함수] (출처 : KISA)

 

HAS-160 

SHA-1 

SHA-2 

SHA-224

SHA-256 

SHA-384 

 SHA-512

 해시값 길이(bit)

160 

160 

224 

256 

384 

512 

[보안강도별 해쉬함수 분류] (출처 : KISA)

 보안강도(*)

해쉬함수 

권고여부 

 80비트 미만

MD5, SHA-1 

권고하지 않음 

 80비트

HAS-160 

 112비트

SHA-224 

권고함 

128비트 

SHA-256 

 192비트

 SHA-384

 256비트

 SHA-512

* 보안강도 : 2^n번의 계산을 해야 비밀키 또는 알고리즘 취약성을 알아낼 수 있다는 것을 의미한다. (국내 권고수준은 112비트 이상)


비밀번호와 Salt

동일한 비밀번호이더라도 다른 해쉬결과를 얻기 위해 Salt라는 비밀값을 추가하여 해쉬함수를 적용한다.
사용자별로 다른 Salt값을 적용하면 비밀번호만 해싱하는것에 비해 비밀번호 사전공격 취약점을 해결하고, 동일비밀번호이더라도 다른 해쉬결과를 얻을 수 있어 암호를 유추하기 어려워진다.

salt를 추가하는 방법은 다음과 같이 다양한 방식이 존재한다.
비밀번호와 salt를 연접하는 방법은 가낭 흔히 사용하므로 다양한 방법을 응용하여 사용하는것이 좋다.
- hashing ( salt || password || salt)
- hashing (salt || hashing (password))
- hashing ( password || hashing (password || salt))
- hashing ( hashing (salt) || hashing (password))
- hashing1 (hashing2 (password || salt))


MessageDigest와 Cryptography

내가 헷갈린다는 것도 몰랐던 Digest와 암호화의 차이.. 사실 이미 구현된 결과만 놓고보면.. 둘다 알 수 없는 숫자 문자열의 나열들이니..
변명이지만 변명할 수도 있겠지. :3 나말고도 헷갈리는사람이 꽤 있는듯하다.

이 둘의 차이점은 복호화가 가능한지 여부인것으로 보인다. MessageDigest는 단방향 알고리즘으로 결과값에서 원본값을 추출할 수 없으나 Cryptography는 암호화 키(대칭키, 비대칭키)를 통해 결과값에서 원본값으로 복원을 할 수 있다.


MAC (Message Authentication Codes)

암호화관련 자료를 찾아보면서 낯선것은 Mac 이었다. 처음 봤을때는 A사의 사과제품을 떠올렸던.. (그..그럴수도 있지!!)

MAC은 초기화 비밀키(SecretKey, 대칭키)를 활용하여 해시값을 추출하며 MessageDigest와 유사하지만 다르다.
이 초기화 키로 인해 MessageDigest는 누구나 무결성 검사가 가능하지만(예: 파일다운로드시 checksum 활용), MAC은 초기화 키를 가지고 있어야만 동일한 해시값을 추출하여 무결성 검사가 가능하다. 

대표적인 알고리즘으로는 HMAC이 있다.

jca8

 [MAC 동작 흐름(이미지 출처) ]

Base64Encoding/Decoding

Base64는 8비트 이진 데이터를 문자코드에 영향받지 않는 공통 ASCII 영역 문자열로 바꾸는 인코딩 방식이다.
인코딩된 문자열은 알파벳 대소문자와 숫자, +, / 기호 64개로 이루어지며 =는 끝을 알리는 코드로 사용하며, 인코딩 된 문자열은 원본보다 약 4/3 정도 증가한다.


Cryptography

해시함수와 다르게 Cryptography는 암호화, 복호화가 가능한 양방향 알고리즘을 사용한다.
알고리즘에는 암호화를 위한 키가 필요하며, 키의 유형에 따라 대칭키(공유키), 비대칭키(공개키, 비밀키)로 나뉜다.

[암호화 알고리즘 분류(출처 : 모도리 블로그)

알고리즘 분류

대표 알고리즘 

 대칭형

 블록 암호

DES (Data Encryption Standard), 3-DES 
AES, SEED, ARIA

 스트림 암호

 MASK

 비대칭형

 RSA (Rivest Shamir Adleman)
DSA (Digital Signature Algorithm; 후에 Digital Signature Standard로 명명)

[대표적 블록암호(CBC) 알고리즘] (출처 : KISA)

 

 SEED

ARIA

AES 

 입출력크기(비트)

 128

128 

128 

 비밀키크기(비트)

128 

128 / 192 / 256 

128 / 192 / 256 

[보안강도별 블록암호 알고리즘 분류] (출처 : KISA)

보안강도

블록암호 알고리즘 

권고여부 

 80 비트 미만

DES 

권고하지 않음 

80 비트 

2TDEA 

 112 비트

3TDEA 

128 비트 

SEED, HIGHT, ARIA-128, AES-128 

 권고함

192 비트 

ARIA-192, AES-192 

256 비트 

ARIA-256, AES-256 



JCA (Java Cryptography Architecture)

Java에서는 JCA (Java Cryptography Architecture)라는 보안 플랫폼을 통해 해시, 암호화, 전자서명 등 다양한 보안기능을 제공하고있다.

Cipher

Cipher 클래스는 암호화/복호화 기능을 제공한다.

예) Cipher cipher = Cipher.getInstance("AES");
알고리즘명, 피드백모드, 패딩모드를 전달하여 생성된 Cipher 객체를 반환받는다.  (피드백모드, 패딩모드 생략 가능)
내부적으로는 전달된 알고리즘이 구현한 서비스객체와 피드백모드(default:ECB), 패딩모드(default : PKCS5Padding)를 설정하여 Cipher 객체를 생성 후 반환한다.

예) cipher.init(Cipher.ENCRYPT_MODE, key);
이 Cipher 객체를 사용하기 위해서 init 메서드를 통해 운영모드와 Key값을 전달하여 초기화한다. 
init 메서드는 인자로 opmode, key, (AlgorithmParameters)params, random을 전달받는데 운영모드에 따라 생략이 가능하며 생략된 값은
 내부적으로 자동 생성하여 사용한다. 기존에 설정된 변수값은 모두 삭제되므로 cipher객체를 초기화하여 사용하는경우, getParameters() 메서드를 호출하여 암호화시 자동으로 생성된 params값을 저장해두어야 한다. 이 값은 복호화시에 동일하게 전달되어야 복호화가 가능하기 때문이다.

  • Cipher 운영모드(opmode)
    • ENCRYPT_MODE : 암호화 모드. 
    • DECRYPT_MODE : 복호화 모드
    • WRAP_MODE : key를 안전하게 전송할 수 있도록 java.security.Key를 래핑하여 바이트 변환
    • UNWRAP_MODE : WRAP_MODE에서 래핑한 Key 를 java.security.Key 객체로 변환
예) cipher.update(byteArray); cipher.doFinal(lastByteArray);
암호화/복호화는 update(), doFinal() 메서드를 통해 수행하며 마지막 데이터(혹은 단일 바이트 데이터)인경우 doFinal을 통해 해당 작업이 완료되었음을 알린다. doFinal이 호출되면 cipher 객체는 모든 데이터에 대한 암호화가 완료되었음을 인지하고 데이터블록의 빈자리에 Padding작업을 수행한다.


jca6

[ Cipher 객체 동작 흐름(이미지 출처) ]

블록암호 피드백모드와 IV (Initial Value)

블록 암호화는 블록단위로 데이터를 암호화 하는데 입력데이터가 같으면 동일한 암호화된 결과값을 갖게되어 해킹공격에 취약점을 가지게된다. 이러한 점을 보완하고 암호화의 복잡도를 높이기 위해 피드백 모드가 도입되었다.

피드백모드는 이전 데이터블록을 활용해 다음 블록의 암호화를 진행한다. N번째 암호화 과정에서 N번째 입력 데이터 블록 (또는 N번째 암호화된 결과 데이터 블록)과 N-1번째 입력 데이터 블록(또는 N-1번째 암호화된 결과 데이터 블록)을 XOR 연산으로 조합하는 것이다. 이때 첫번째 블록의 경우는 N-1번째 블록이 존재하지 않기때문에 이 값을 대체하는 변수값이 IV(Initial Value) 이다. IV값을 통해 동일한 입력값이더라도 전혀다른 암호화된 결과값을 얻을 수 있다.

다음의 그림은 원본파일 / 피드백모드를 사용하지 않는 암호화 결과 / 피드백모드를 사용한 암호화 결과의 차이를 잘 나타내고 있다.

jca7

[ 이미지 암호화(이미지 출처: http://en.wikipedia.org/wiki/Modes_of_operation) ]



Simple Implements Examples (for JAVA)

Encode/Decode Codec Library Import

※ JVM의 encode, decode library를 사용하지 않는 이유
    - http://www.oracle.com/technetwork/java/faq-sun-packages-142232.html
    - java.*, javax.*, org.* 패키지에서 제공되는 클래스는 JVM에서 public API를 제공하고 관리되지만,
      sun.misc.*, com.sun.* 패키지의 기능은 그렇지 않으므로 언제든 변경되거나 사라질 수 있는 위험성을 내포하고 있다.

<!-- http://mvnrepository.com/artifact/commons-codec/commons-codec/1.9 -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>


Byte Array <-> Hex String 

import org.apache.commons.codec.binary.Hex;

Hex.encodeHexString(byteArray); // byte[] => hex string
Hex.decode(hexString); // hex string => byte[]


BASE64 Encoding/Decoding

import org.apache.commons.codec.binary.Base64; 

Base64.encodeBase64String(byteArray); // byte[] => base64 encoded string
Base64.decodeBase64(encodedString); // base64 encoded string => byte[] , new String(byteArray)를 통해 문자열로 변경


AES 암호화 (출처 : AES256 암호화 Java 샘플)

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AES256Cipher {

    private final String AES_ALGORITHM = "AES/CBC/PKCS5Padding";

    /** @return encryptData */
    public static byte[] encode(String key, String plainData, String iv) {
        SecretKey secretKey = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance(
AES_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv.getBytes()));

        return cipher.doFinal(plainData.getBytes("UTF-8"));
    }

    /** @return decryptData(plainData)  */
    public static String decode(String key, String encryptData, String iv) {
        SecretKey secretKey = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance(
AES_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv.getBytes()));

        return new String(cipher.doFinal(encryptData.getBytes(), "UTF-8");
    
}

}


RSA 암호화


import javax.crypto.Cipher;
import java.security.Key;

public class RSACipher {

    private final String RSA_ALGORITHM = "RSA";
    private final int KEY_SIZE = 2048;

    /** @return KeyPair */
    public static KeyPair generateRSAKeyPair() throws Exception {
        KeyPairGenerator generator = KeyPairGenerator.getInstance(
RSA_ALGORITHM);
        generator.initialize(KEY_SIZE);
        return generator.genKeyPair();
    }

    /** @return encryptData */
    public static byte[] encode(Key key, String plainData) {
        Cipher cipher = Cipher.getInstance(
RSA_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);

        return cipher.doFinal(plainData.getBytes("UTF-8"));
    }

    /** @return decryptData(plainData)  */
    public static String decode(Key key, String encryptData, String iv) {
        Cipher cipher = Cipher.getInstance(
RSA_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv.getBytes()));

        return new String(cipher.doFinal(encryptData.getBytes(), "UTF-8");
    
}

    public static void main(String[] args) {
        String data = "원본 데이터입니다.";

        KeyPair rsaKeyPair = generateRSAKeyPair();
        byte[] encrypted = encode(rsaKeyPair.getPrivate(), data);
        String decrypted = decode(rsaKeyPair.getPublic(), encrypted);

        assertEquals(data, decrypted);
    }
}





Posted by dreamhopp
,

처리 성능 개선

데이터베이스 규칙 완화 또는 파기에 따른 문제점과 성능개선에 대한 가치 비교가 필요하다

데이터 구조의 무분별한 수정의 결과로 발생할 수 있는 문제들

  • 일관성 없는 데이터 : 불필요한 이중 필드를 도입한 경우 발생
  • 중복 데이터 : 불필요한 이중 필드를 도입한 경우 발생
  • 손상된 데이터 무결성
  • 부정확한 정보 제공
데이터베이스 규칙 완화 또는 파기는 최후의 수단으로 두고, 다른 대안을 통해 성능개선을 시도해야한다.
  • 하드웨어 Scale Up / Scale Out
  • OS 옵션 최적화
  • 데이터베이스 구조가 올바르게 설계되었는지 검토
  • 데이터베이스의 구현 검토 : 효율적이고 안전하게 정의했는가 검토
  • 데이터베이스를 사용하는 응용프로그램 검토


설계 지침

후보 키의 요소

  • 다중 부분 필드가 될 수 없다.
  • 유일한 값을 가져아 한다.
  • 널(null)값을 포함할 수 없다.
  • 그 값은 조직의 보안이나 비밀 규칙을 깨뜨리도록 할 수 없다.
  • 그 값이 전체 또는 부분적으로 선택적이지 않다.
  • 유일성을 정의하기 위해 필요한 최소 개수의 필드들을 포함한다.
  • 그 값들이 테이블 내의 각 레코드들을 유일하게 그리고 배타적으로 식별해야만 한다.
  • 그 값이 주어진 레코드 내의 각 필드의 값을 구체적으로 식별해야만 한다.
  • 그 값은 아주 드물고 극단적인 경우에만 수정될 수 있다.
외래키의 요소
  • 복사된 주 키의 이름과 같은 이름을 갖는다.
  • 복사된 기본 키에 대한 필드 명세의 복제를 사용한다.
  • 참조하는 주 키에서 값을 도출한다.
주 키의 요소
  • 다중 부분 필드일 수 없다.
  • 반드시 유일한 값을 가져야 한다.
  • 널(null)값을 포함할 수 없다.
  • 그 값이 조직의 보안 또는 비밀 규칙을 깨뜨릴 수 없다.
  • 그 값이 전체 또는 부분적으로 선택적이지 않다.
  • 유일성을 정의하기 위해 필요한 최소 개수의 필드들을 포함한다.
  • 그 값이 테이블에 있는 각 레코드들을 유일하고 배타적으로 식별해야만 한다.
  • 그 값은 주어진 레코드에 있는 각 필드값을 구체적으로 식별해야 한다.
  • 그 값은 아주 드물고 극단적인 경우에만 수정될 수 있다.
이상적인 필드의 요소
  • 테이블의 대상의 뚜렷한 특징을 나타낸다.
  • 단 하나의 값만을 포함한다.
  • 더 작은 구성요소로 해체될 수 없다.
  • 계산되거나 연결된 값을 포함하지 않는다.
  • 전체 데이터베이스 구조 내에서 유일하다.
  • 하나 이상의 테이블에 나타날 때에는 속성들의 대부분을 보유한다.
이상적인 테이블의 요소
  • 개체 또는 사건일 수 있는 하나의 대상을 나타낸다.
  • 주 키를 갖는다.
  • 다중 부분 필드나 다중값 필드를 포함하지 않는다.
  • 계산된 필드를 포함하지 않는다.
  • 불필요한 중복 필드들을 포함하지 않는다.
  • 절대적으로 최소화된 중복 데이터만을 포함한다.
필드 이름을 생성하기 위한 지침
  • 전체 조직에 의미 있는 유일하고 설명적인 이름을 생성한다.
  • 필드가 나타내는 특징들을 정확하고 명확하게 그리고 모호하지 않게 식별하는 이름을 생성한다.
  • 필드가 나타내는 특징의 의미를 전달할 때 필요한 최소 개수의 단어를 사용한다.
  • 두문자어를 사용하지 않으며, 약어를 신중하게 사용한다.
  • 필드 이름의 의미를 혼동할 수 있는 단어를 사용하지 않는다.
  • 암시적이거나 명시적으로 하나 이상의 특징을 식별하는 이름을 사용하지 않는다.
  • 이름의 단수형을 사용한다.
테이블 이름을 생성하기 위한 지침
  • 전체 조직에 의미 있는 유일하고 설명적인 이름을 생성한다.
  • 테이블의 대상을 정확하고 명확하게 그리고 모호하지 않게 식별하는 이름을 생성한다.
  • 테이블의 대상을 전달할 때 필요한 최소 개수의 단어를 사용한다.
  • 물리적인 특징을 전달하는 단어들을 사용하지 않는다.
  • 두문자어와 약어를 사용하지 않는다.
  • 테이블에 입력될 수 있는 데이터를 과도하게 제한하는 이름이나 다른 단어들을 사용하지 않는다.
  • 하나 이상의 대상을 암시적이거나 명시적으로 식별하는 이름을 사용하지 않는다.
  • 이름의 복수형을 사용한다.


'기타' 카테고리의 다른 글

암호화, 해시 그리고 인코딩  (0) 2015.07.28
[도서] 오라클의 눈으로 알티베이스를 보다  (0) 2014.10.16
Posted by dreamhopp
,

Altibase

  • Hibrid Database로 테이블을 생성하는 테이블스페이스에 따라 메모리DB와 DiskDB를 제공한다.(테이블단위)
  • Disk Database의 경우 Oracle과 유사하게 지원되며, Memory Database의 경우 테이블을 모두 Memory에 적재하기때문에 Disk I/O가 발생하지 않고 빠른 속도로 접근 및 실행이 가능하다.
  • 알티베이스 기동시,
    • 메모리 스페이스의 모든 테이블은 메모리상에 올려 디스크 I/O 없이 사용가능
    • 디스크 스페이스 테이블의 경우 일정 크기의 버퍼가 할당되고 필요(질의)에 따라 일부 데이터들을 버퍼에 로딩하여 접근(Page단위, 오라클의 block에 대응되는 개념)
  • 메모리 테이블 스페이스의 질의 등의 작업 수행시 메모리영역에서 데이터 변경이 발생하며, 영속성 유지 및 복구시간 단축을 위해 메모리 데이터에 대한 백업본을 디스크에 저장(Checkpoint)하는 과정이 추가로 발생한다.
  • BCB(Buffer Control Block)의 Status
    • Free : 버퍼에 데이터가 적재되지 않은 상태
    • Clean : Free 상태에서 데이터 적재 후 변경되지 않은 상태 (최초 1회만 적재된 상태)
                 Checkpoint 혹은 Flush가 발생하여 변경사항이 Disk에 반영된 후의 상태 (Disk와 동일한 상태)
    • Dirty : Clean 혹은 Dirty 상태에서 데이터변경이 발생한 상태(2회이상 데이터가 적재된 상태)
  • Altibase의 Buffer List 처리구조 (p41)
    • 버퍼가 필요한 경우 Prepare List에서 Clean(Disk와 동기화), Free(데이터 미적재) 상태의 버퍼를 찾는다.
    • 찾은 버퍼에 Disk Page에 대한 내용을 적재하고 LRU List Cold 영역으로 이동시킨다.
      만약 가용버퍼를 찾지 못한경우 LRU List Cold영역의 old 영역부터 가용버퍼(Clean, Free)를 찾는다.
    • Prepare List, LRU List에서 가용버퍼를 찾는과정 중 Dirty 상태의 버퍼를 만나면 해당 버퍼를 Flush List로 옮기고 나중에 Disk에 반영한다.
  • Redo Log 처리 Process
    • Redo Log Buffer : 데이터베이스 데이터의 변경에 대한 정보를 저장하는 공간
    • 설정 파라미터
      - PREPARE_LOG_FILE_COUNT : 미리 만들어놓을 Log File의 수.
      - CHECK_POINT_MAX_Log file : 해당 값보다 Log file의 수가 많아지면 Checkpoint를 수행.
      - LOG_BUFFER_TYPE : 1인경우 트랜잭션 로그를 Redo Log Buffer에 저장. 0인경우 OS 커널에 기록
    • Log File Manager 쓰레드가 감시하면서 PREPARE_LOG_FILE_COUNT 의 수만큼 사용가능한 Log file을 만든다.
      일정 시점마다 Checkpoint가 발생하면서 Log File의 내용을 Disk로 옮긴 후 Log File을 삭제한다. CHECK_POINT_MAX_Log file의 수보다 Log file의 수가 많은경우 자동으로 Checkpoint를 발생시키며 저장된 Log File을 삭제한다.
    • 영속성 유지를 위한 Process
      LOG_BUFFER_TYPE이 1인경우 Redo Log Buffer에 저장하여 메모리에만 반영후 응답하므로 속도향상을 꾀할 수 있다. 그러나 알티베이스 비정상종료시 Disk와의 동기화를 보장하기 어려우므로 영속성 유지가 어렵다.
      LOG_BUFFER_TYPE을 0으로 설정하는 경우 트랜잭션로그를 OS커널에 기록하므로 알티베이스가 비정상 종료되더라도 OS만 살아있다면 Disk에 트랜잭션 로그가 반영되므로 영속성 유지가 보다 뛰어나다.
  • Private Memory Area 최대값을 제한하는 이유
    • 알티베이스에서는 사용가능한 메모리 영역의 크기제한이 없으나 무한정 가용범위내에서 사용하다보면 무한히 증가되어 성능에 악영향을 미치므로 프로퍼티를 통해 최대 사용가능한 값을 지정할 수 있다.
    • Max값을 넘어가게 되는경우, 해당 Query만 실패한다.(크기를 초과했습니다. 에러 발생)
  • 테이블 스페이스
    • 메모리 테이블 스페이스
    • 휘발성 테이블 스페이스 : DB가 구동중인 동안에만 의미있는 데이터를 위한 공간으로 Redo Log 작성, Checkpoint 과정을 수행하지 않는다. 메타정보를 저장하는 작업에 대해서만 Disk I/O가 발생하며, 그 외의 경우에는 발생하지 않는다.
    • 디스크 테이블 스페이스 : Oracle과 비슷한 방식으로 데이터를 저장하고 동작한다.
  • 쓰레드 구조(p66)
    • Dispatcher Thread (Oracle의 listener역할) : 클라이언트가 접속을 요청하면 기 생성된 Service Thread 중 하나를 할당.
    • Service Thread (Server Process) : 할당받은 하나 이상의 클라이언트의 요청을 처리.
                      DB 구동시 default로 CPU의 갯수만큼 구동(프로퍼티로 조정가능)
    • Load Balancer Thread : Service Thread에 고르게 일을 재분배하거나 Idle한 Thread를 정리한다.
                      - MULTIPLEXING_THREAD_COUNT : Idle상태시 설정된 값 만큼으로 thread를 정리
    • Session Manager Thread : 클라이언트의 상황을 감지하여 비정상적으로 클라이언트의 연결이 끊어지지 않았는지 체크
  • 메모리 상태정보 조회
    • V$MEMSTAT : 현재 메모리 공간을 얼마나 차지하는지 알 수 있는 성능 뷰
    • 현재 상태(버퍼의 hit율) 등의 값을 조회할 수 있는 뷰도 존재함. (V$SESSION_WAIT, V$SYSTEM_EVENT)
    • SQL Plan Cache, Buffer Pool의 최적 크기의 예상치를 보여주는 뷰는 존재하지 않음.
  • MVCC (Multi Version Concurrency Control) (p89)
    • Out-place MVCC (메모리 스페이스)
      • 데이터가 변경될 경우 변경된 최신의 데이터를 새로운 곳에 저장하고 이를 연결하는 방식
      • 장점 : 서로다른 트랜잭션이 같은 컬럼을 조회할 경우, Versioning에 따른 CR Copy 비용이 들지 않아 성능이 훨씬 빠름.
      • 단점 : Versioning 정보 저장을 위해 계속 메모리에 생성하므로 메모리 사용량이 증가함.
             메모리 사용을 적정하게 하기 위해 Versioning을 유지할 필요 없는 공간(commit, rollback 후)은 Memory Ager Thread
             가 자동으로 삭제하여 공간을 재사용 할 수 있도록 함. (트랜잭션이 오래 지속되는 경우는 정리되지 않으므로 주의!)
    • In-place MVCC (디스크 스페이스)
      • 데이터가 변경될 경우 변경된 최신의 데이터를 원래 위치에 덮어쓰는 방식


Oracle과 Altibase 비교

 Oracle

Altibase 

  • 조회빈도가 높은 특정기간 or 특정 마스터정보를 메모리영역에 keep
  • 주기적으로 정보를 읽어 buffer Cache 영역에서의 Hit 율 향상
  • Result Cache 사용 (11g Feature) 
  • 빠른성능이 요구되는 데이터는 메모리 DBMS, 접근빈도가 낮은 데이터는 디스크 DBMS로 처리 (테이블 생성된 스페이스에 따라 DBMS 선택됨. 테이블단위로 )
  • Library Cache 공유
    - 수행 SQL문장에 대한 Parse Tree와 실행계획 포함하는 영역
    - 다른 유저에 의해 동일 SQL이 실행되는경우 Shared SQL Area를 공유함으로써 메모리영역을 재사용 
  • SQL Plan Cache 공유
    - SQL Plan(parse-validate-optimize 결과물)
    - SQL Plan을 SQL Plan Cache에 저장하여 여러 세션이 이를 공유하여 사용함.
  • Data Dictionary Cache
    - 데이터베이스 구조와 사용자에 대한 정보를 포함하는 데이터를 Row단위로 Cache에 보관(데이터는 Disk 저장)
    - SQL Parsing 등의 작업에 항상 참고되며 LRU 알고리즘으로 관리
  • Data Dictionary 메타정보를 메모리영역에 보관
    - 빈번하게 사용되는 정보이므로 메모리영역에 보관
    - SYS_TBS_DIC 테이블 스페이스가 이 영역에 해당됨.
  • Buffer Cache
    - Data Block 의 Copy를 가진 SGA의 일부영역으로 User Process들은 이를 공유하여 사용
  • Buffer Cache의 List
    - Dirty List : 변경되었지만 Disk에 기록되지 않은 데이터를 포함
    - LRU List : Free Buffer, Pinned Buffer(사용중), Dirty Buffer(Dirty List 옮기기전 Buffer) 관리
  • Buffer Pool
    - BCB(Buffer Control Block;버퍼제어블록) : 버퍼프레임과 Disk page를 연결하는 정보(p39) 저장
    - Buffer Frame : Disk page에 매핑
  • Buffer Pool의 List(p40)
    - Prepare List : Clean, Free상태의 BCB 집합
    - LRU List : 데이터가 적재된 BCB 집합
    - Checkpoint List : Dirty 상태의 BCB 집합
    - Flush List : Buffer Replace 과정중 Prepare List와 LRU List에서 발견된 Dirty 상태의 BCB 집합
  •  Redo Log Buffer
    - 데이터 영속성 유지를 위한 안정성을 목표로 함.
    - 디스크장애에 대비하여 Thread당 3개 이상의 Group, Group당 2개 이상의 Member로 분산저장하는것을 권장.
    - 특정크기의 Redo Log File을 계속 유지하는 방식
  • Redo Log File이 Full인 경우, File의 내용을 Disk에 저장 후 재사용한다.
  • Redo Log Buffer
    - 성능향상을 위해 디스크 I/O를 분산하기 위한 목적
    - 영속성 유지를 위한 안전성은 Archive Log 모드를 통해 제공
    - Redo Log File을 사용후 Disk에 반영하면 삭제하는 방식
  • Redo Log File이 Full인 경우, 다음 사용할 File을 미리 만들어 놓는 방식으로 동작하므로 File생성 혹은 Checkpoint로 인한 병목지점을 발생시키지 않는다.
  •  Private Memory Area
    - 개별 프로세스 단위 내에서만 사용가능한 공간.
    - Private SQL Area : Bind data, Query 실행상태 저장
    - SQL Work Area : 메모리자원을 필요로하는 작업들에 대한 정보 저장
    - Session Memory : (dedicated환경인경우) 세션정보 저장
  • Private Memory Area
    - Global Area에 위치함.(메모리 공간이 나뉘진 않음)
    - Query_Prepare, Query_Binding, Query Execute, Query_PSM_Execute 영역과 대응되며, 하나의 세션에서만 사용가능.
  •  commit 방식(p94)
    - 기본값 : commit write immediate wait (10g 부터 제공)
    - 커밋명령어 실행즉시 파일에 기록 후 완료되면 트랜잭션에 응답.
  • rollback 방식(p98)
    - 1개 이상의 Undo Table Space를 가질 수 있으며, 현재는 자동으로 관리된다.
    - undo 영역이 full인 경우 영역 재사용여부를 트랜잭션의 완료여부로 판단하며, 해당 영역을 참조하는 SQL이 있는경우 다른 트랜잭션에 의해 정보가 변경되어 Snapshot Too Old 발생할 수 있음.
    - UNDO_RETENTION : undo정보를 얼마나 유지해야할지 설정가능
  •  commit 방식(p96,p97)
    - 기본값 : 메모리에만 기록후 트랜잭션에 응답(fast commit)
  • rollback 방식
    - 1개의 Undo Tablespace를 가지고 파라미터를 통해 크기변경이 가능하며, 시스템이 자동으로 관리한다.
    - Undo를 처음 쓴 Statement보다 더 이전에 수행된 Statement 존재여부로 판단하므로 동일영역 재사용에 따른 데이터 변경이슈인 Snapshot Too Old 에러는 발생하지 않는다.
    그러나 오라클에 비해 Undo Tablespace 공간을 더 많이 사용하므로 Full이 차지 않는지 모니터링을 꼭 해야한다.
  • lock (p104,p105)
    • DML Lock
      - TX Lock(row lock), TM Lock(table lock)이 있다.
    • DDL Lock :  Object 구조정의 보호를 위해 TM lock 적용
    • Select시 Lock 설정
      - Null Lock(Breakable Lock) : SELECT 결과 Fetch 중 다른 트랜잭션에서 테이블 Drop하는것을 방지하기 위해 Lock 설정
  • Dead Lock (p108)
    - deadlock이 발생한 자원에 대해 먼저 lock을 점유하던 트랜잭션에 rollback 수행함.
  • lock (p105, p106)
    • Select시 Lock 설정
      - IS Lock(table lock, select 허용모드) : SELECT문이 종료되기 전에 다른 트랜잭션에서 X Lock(table lock, 1 트랜잭션만 접근가능) 설정 방지
      - 한 트랜잭션이 사용중인 테이블에 대해서 DDL 작업 불가
  • Dead Lock(p109)
    - deadlock이 발생한 자원에 대해 나중에 자원획득을 시도하려던 트랜잭션을 rollback 수행함.
  • SQL Optimization
    - default : CBO(Cost Based Optimization; 10g이후)
    - 샘플링 데이터를 통한 통계정보
    - 실행계획과 runtime시 실행계획이 다른경우가 있음(ex:bind peeking)
    - null 값을 index에 저장하지 않음(null조건 index scan 불가)
    - oracle hint (p134)
  • SQL Optimization
    - default : CBO
    - DML이 발생할때마다 통계정보 변경반영.(전체 데이터에 대한 통계정보)
    - 실행계획과 runtime 실행계획이 항상 일치
    - null값도 index에 저장함(null 조건 index scan 가능)
    - altibase hint (p131)
  • 실행계획 조회
    - ALTER SESSION SET explain plan =
    {option}
    - option : on(실행계획+실행결과), off(실행결과), only(실행계획)
    - index scan : fixed key(상수조건), variable key(변수,조인조건)
    - table scan : filter
  • 대용량데이터 처리기법
    - 파티션테이블 : 대량의 데이터를 월별과 같이 나누어 관리함으로써 한번에 읽어들어야 할 데이터의 양을 쪼개어 처리성능 향상
    - 압축기법 : 조회나 이력관리를 위한 데이터의 경우 중복된 데이터값의 제거를 통해 데이터 read block을 감소시켜 성능향상
    - 병렬처리기법 : 클라이언트의 요청을 여러개의 서버 프로세스를 사용하여 처리
  • 대용량데이터 처리기법
    - 파티셔닝 지원(Range, List, Hash, Composite)
    - 병렬처리는 지원하지 않음.
    - 통신사의 과금통계시스템에서 적용중이며 4중화 대용량의 HDB(ex: 1.5TB)를 구축하여 성능에 특화된 구조로 사용중임.
  •  고가용성 기법
    - 두개 이상의 서버를 운용하여 한 서버가 죽더라도 다른 서버를 통해 작업할 수 있도록 하는 기법
    - RAC, Replication을 통해 제공
    - RAC : 여러 인스턴스에서 디스크를 공유하는 방식
  •  고가용성 기법
    - 이중화 : TCP/IP 네트웍 기반의 데이터 복제 기법 사용
             별개의 서버에 데이터를 복제하여 양쪽 서버간의 데이터를 일치시켜주는 병렬 데이터베이스 아키텍처 사용
    - altibase 제품에 내장되어있어 별도의 설치과정 필요없음.




[부록] Oracle to Altibase 마이그레이션 (p159~)

  • 스키마 마이그레이션
    • 변환시 고려사항
      • ADD 구문의 괄호 제거
      • 2개 이상을 하나의 질의문으로 추가 불가. (질의문 분리해서 수행)
  • 데이터 마이그레이션
    • Oracle에서 데이터 내려받기
      - 데이터와 구분자의 조합으로 이루어진 형태로 내려받기 수행(Altibase HDB가 인식할 수 있는 형태
    • Altibase HDB로 데이터 올리기 (iLoader)
      - 참고 : http://atc.altibase.com/sub09/551b/html/iLoader/index.html
      1. 테이블의 From-File을 생성
        > iloader -s 127.0.0.1 -u sys -p manager -port 27584 formout -T dountries -f countries.fmt
      2. 오라클에서 내려받은 데이터파일 로딩
        > iloader -s 127.0.0.1 -u sys -p manager -port 27584 in -f countries.fmt -d countries.dat -t "^C-c^" -r R-r%n -log a.log -bad a.
  • 프로그램 마이그레이션
    • OCI 프로그램 변환(p176~183)
    • Embedded SQL 변환(p184~201)
    • Java 프로그램의 변환 (p202~217)
    • Procedure 변환 (p218~221)


Oracle과 Altibase의 Java Program 차이점 비교(p217)

 차이항목

Oracle 

Altibase 

설명 

 jdbc driver

 ojdbc5.jar

Altibase.jar 

오라클은 jdk 버전에 따라 사용하는 jdbc드라이버가 다르나 알티베이스는 jdk버전에 상관없이 동일한 driver 사용  

 jcbd url 지정

 String sURL=
'jdbc:oracle:thin:
@192.168.1.35:1522:orcl';

 String sURL=
'jdbc:Altibase:
//192.168.1.35:20416/mydb';

오라클은 @IP:포트번호:SID명을 사용

알티베이스는 //IP:포트번호/DB명 을 사용 

 driver 클래스명

 Class.forName
("oracle.jdbc.driver.OracleDriber");

 Class.forName
("Altibase.jdbc.driver.AltibaseDriver"); 

 



Oracle과 Altibase의 Procedure차이점 비교(p221)

 차이항목

Oracle 

Altibase 

설명 

 입력
파라미터

CREATE OR REPLACE PROCEDURE
show emplist
(p_jobid IN VARCHAR2) IS

CREATE OR REPLACE PROCEDURE
show_emplist
(p_jobid IN VARCHAR2(10) IS

오라클은 프로시져의 입력인자 타입이 VARCHAR2와 같이 length 없이 사용될 경우 32KB까지 사용가능.

알티베이스는 프로시져 입력 인자의 length를 반드시 선언해야한다.

 화면출력
함수

 DBMS_OUTPUT.PUT_LINE
 ('------');

 println('========')

오라클은 DBMS_OUTPUT 패키지의 PUT_LINE 함수를 사용

알티베이스는 패키지를 지원하지 않으며 출력함수로 println을 사용


'기타' 카테고리의 다른 글

암호화, 해시 그리고 인코딩  (0) 2015.07.28
[도서] 가장 쉬운 데이터베이스 설계 책  (0) 2014.11.25
Posted by dreamhopp
,