혦's STACK
데이터베이스 첫걸음 - 한빛미디어 본문
데이터베이스 첫걸음 - 한빛미디어
INDEX
1장. 데이터베이스란 : 용도, 역할
2장. 관계형 데이터베이스란 : 가장 대표적인 데이터베이스
3장. 데이터베이스의 비용 : 초기비용과 운영비용
4장. 데이터베이스와 아키텍처 구성
5장. DBMS 조작 기본 지식
6장. SQL 문의 기본
7장. 트랜잭션과 동시성 제어
8장. 테이블 설계의 기초
9장. 백업과 복구 : 장애 대비
10장. 성능 향상
한빛미디어의 '데이터베이스 첫걸음'은 올해 초에 지인이 추천한 책입니다. 그 동안 마음의 짐으로 남겨 뒀는데 여유가 생긴 김에 포스팅을 하였습니다. 이 책은 데이터베이스의 용도부터 성능 튜닝을 위한 실행계획까지 방대한 범위를 약 300페이지 분량으로 설명합니다. 개인적으로 가볍게 읽으면서 데이터베이스의 기초를 쌓을 수 있어서 매우 유용하였습니다. 새로 알게 된 지식이나 매우 중요한 내용들을 가볍게 포스팅하여 나중에 복습 용으로 활용하고자 합니다.
1장. 데이터베이스란 : 용도, 역할
1 . 데이터베이스의 기본 기능
데이터베이스의 기능들은 기본적으로 사용자 편의성과 트레이드 오프의 관계에 놓이는 경우가 많다. 데이터 무결성과 보안이 그 대표적인 예입니다.
검색과 갱신 (삽입, 삭제, 수정)
넓은 의미에서 갱신은 삽입, 삭제, 제거를 포괄합니다.
데이터를 조작할 때에는 각 데이터가 '고유성'을 갖도록 유의해야 합니다. 책에서는 포맷에 주의하라고 넓은 의미로 표현하였습니다.
처리성능에 유의해야 합니다. 검색이나 갱신에서 성능은 매우 중요합니다. 검색과 갱신의 성능이 모두 좋은 것이 가장 좋은 방법입니다. 그러나 비용과 아키텍처 등의 다양한 요소에 따라 둘 중 하나의 성능을 빠르게 하면 다른 성능이 저하 될 수 있습니다. 이때에는 모듈의 사용빈도와 중요도 등을 파악하여 검색의 성능을 빠르게 하거나 갱신의 성능을 빠르게 하여야 합니다.
Ex) 정규화와 반정규화, Index 설정 등...
동시성 제어
데이터베이스는 기본적으로 다수의 사용자의 사용을 지원해야 합니다. 이 때 사용자가 동시에 한 자원에 접근 했을 때, 데이터베이스는 여러 선택을 할 수 있습니다. 즉, 복수의 사용자가 다양한 쿼리를 입력했을 때, 데이터베이스는 선택을 해야 합니다. 이러한 기능을 지원하는 것을 '동시성 제어'라고 합니다.
수정 완료 전까지 접근 금지
수정 완료 전까지 읽기(조회) 기능만 가능
수행 완료를 빨리 한 사람의 결과가 반영 (비추)
만약 이를 수행한다면 사용자의 입장에서는 언제든지 데이터베이스를 이용할 수 있으니 좋아할 수도 있습니다. 그러나 이러한 행위는 누구도 결과를 예상하거나 짐작하기 힘들며, 쿼리가 복잡할 때에는 자신의 의도대로 쿼리가 수행되었는지 검증하는데에 더 많은 시간이 걸릴 수 있기 때문에 지양해야 합니다.
- 더티 쓰기 : 나중에 수행된 쪽의 갱신이 반영되는 경우 (데이터 무결성 침해 가능성 높음)
장애 대응
데이터베이스에 장애가 발생했을 때 비용적 측면으로 큰 손해를 입을 수 있습니다. 또한 완벽히 안전한 데이터베이스는 없기 때문에 데이터베이스 관리자 및 설계자는 장애에 대비해야만 합니다.
데이터 손실의 문제
- 분산 데이터베이스 운영
- 백업 : 사후 대책
데이터베이스의 서비스 레벨과 비용의 딜레마 : 완벽한 장애 대비를 하고 싶지만 운영하는 서비스의 비용이 낮게 책정되거나 중요성이 낮아 차선책으로 밀려남으로써 발생하는 딜레마 입니다.
보안
데이터베이스의 보안은 권한이 없는 사용자의 접근을 막는 것을 말합니다.
- 클라이언트 기능의 보안 구멍 최소화
- 데이터 기밀성 유지 : 사용자 이용 및 접근 제한 (사용자 편의성과 트레이드오프)
일반적으로 데이터베이스는 보안을 위해 사용자가 인식하지 못하도록 (접근하지 못하도록) 설계되어 있다.
2장. 관계형 데이터베이스란 : 가장 대표적인 데이터베이스
1 . 관계형 데이터베이스
관계형 데이터베이스란 데이터를 이차원 표를 사용하여 관리하는 데이터베이스 입니다. 이차원 표는 역사적으로 정보를 관리할 때 가장 많이 사용하였던 형식(역사적 관점)이며, 기능적으로도 뛰어난 구조입니다. 특히 관계형 데이터베이스는 'SQL'을 통해 개발 지식이 없어도 데이터베이스를 관리, 조작할 수 있습니다.
조작 명령어와 구성요소
관계형 데이터베이스는 SQL 을 통해 기본 조작을 지원한다.
- SELECT : 조회
- INSERT : 삽입
- UPDATE : 갱신
- DELETE : 삭제
또한, 관계형 데이터베이스는 이차원 표를 기반으로 하고 있기 때문에 열과 행, 테이블로 데이터를 표현합니다. 이때 표는 'table (테이블)'이라고 하며 열은 'column(컬럼)', 행은 'row(로우)' 라고 합니다.
데이터베이스와 DBMS 는 혼용되기 쉬운 용어이지만 구분 해야 합니다. 데이터베이스는 추상적인 개념으로 데이터를 관리하는 구조 혹은 기능을 말합니다. 그러나 DBMS는 데이터베이스를 실현하기 위한 구체적인 소프트웨어 (시스템)을 말합니다.
특히 DBMS 에 대해 자세히 논하자면, 소프트웨어의 계층구조를 이해해야 합니다. 소프트웨어는 OS -> 미들웨어 -> 에플리케이션으로 계층을 갖습니다. 사용자가 쉽게 접근하는 것은 애플리케이션이고, DBMS는 미들웨어입니다. 즉 애플리케이션을 매개로 사용자는 DBMS에 접근합니다. 또한 OS에 DBMS 를 설치하여 데이터베이스를 구현합니다. 이렇듯 소프트웨어를 계층으로 분리하여 관리하는 이유는 DBMS 관점에서 이야기 한다면 보안성을 높이고 자원을 효율적으로 사용하고, 개발 비용을 낮추기 위해서 입니다.
애플리케이션을 실현하는 수단은 크게 '스크래치'와 '패키지'가 있습니다. 스크래치는 직접 구현하여 세세한 기능 구현이 가능하지만 개발 비용이 크다는 단점이 있습니다. 반면에 패키지는 기존의 제품을 설치하여 개발 비용을 줄일 수 있지만 커스터마이징 위험이 있어 오히려 비용부담이나 개발 부담이 클 수 있습니다.
3장. 데이터베이스의 비용 : 초기비용과 운영비용
1 . DBMS와 비용
데이터베이스를 구현, 운영할 때에는 필연적으로 비용이 발생합니다. 이는 크게 초기 비용과 운영 비용으로 구분할 수 있습니다. 초기에 시스템을 구현할 때 드는 비용을 초기 비용이라 하며, 이를 운영하면서 드는 비용이 운영 비용입니다. 시스템은 기존 업무의 효율성을 높이고, 새로운 서비스를 전산화하여 이윤을 높이기 위해 사용됩니다. 이때 초기비용과 운영비용을 측정한다면 효율성을 극대화 하고 시스템 선택에 도움이 됩니다.
초기비용
소프트웨어의 초기 비용은 '라이선스 비용'이 대표적입니다. 이는 크게 프로세서 라이선스와 사용자 라이선스로 구분합니다. 성능에 따라 가격이 결정 되는 것이 프로세서 라이선스이며 사용자 수에 따라 책정되는 것이 사용자 라이선스 입니다. 이들은 일반적으로 시스템의 규모와 비례합니다.
초기비용을 결정하는 요소에는 에디션과 옵션도 있습니다. 먼저 에디션은 신뢰성과 가용성, 성능, 보안에 따라 비용이 달라집니다.
에디션
- 신뢰성(가용성) : 클러스터 구성, 리플리케이션
- 성능 : 프로세서 기술 지원, 테이블 파티셔닝, 성능 리포트 출력, 데이터 압축 기능 지원
- 보안 : 데이터 암호화, 로그
데이터베이스는 품질을 높이기 위한 기능을 제공하는데 이는 옵션으로 이용 가능합니다.
운영비용
운영비용은 일반적으로 데이터베이스를 운영하는 데에 필요한 비용입니다. DBMS 는 자체적으로 개발하기 보다는 다른 회사의 DBMS 를 구입하여 사용하는 경우가 많으며 초기 설계 및 구현 또한 자체 개발 보다는 다른 업체에서 구현합니다. 그러므로 운영하면서 생기는 버그나 에러를 기존의 개발자 혹은 운영자가 감당하지 못하는 경우가 생기는데, 이를 대비하여 기술 지원 계약을 하며 주기적으로 비용을 지불합니다.
무료 기술 지원의 경우 비용은 들지 않지만 'EOSL' (지원 종료 타이밍)에 유의하여야 합니다. 이때에는 소프트웨어의 수명에 주의하여 소프트웨어를 선택해야 하는데, 새로운 버전의 경우 수명은 길지만 위험부담이 높고, 오래된 버전의 경우 안정성은 높지만 기술 지원 기간이 짧을 위험이 있습니다.
-> 서브스크립션 : 기한을 정한 사용허가 (기한에 따라 비용이 달라짐)
신뢰성(가용성) : 클러스터 구성, 리플리케이션
초기비용의 트릭
초기 비용을 낮게 책정하는 대신 운영 비용을 높게 책정하여 반대의 경우와 총 비용은 같지만 인식적으로 낮다고 판단하는 것 으로, 사람의 '편향 (Bias)'을 이용한 전략입니다.
4장. 데이터베이스와 아키텍처 구성
1 . 아키텍처 구성 : 다중화 중심
데이터베이스의 아키텍처는 일반적으로 DBMS 별로 SGA, RAC, 데이터 파일 등의 구조와 프로세스의 기능에 따라 분류하여 설명하는 경우가 많습니다. 그러나 이 책을 통해 다중화를 중심으로 아키텍처를 설명하여 시스템을 위한 물리 레벨의 조합을 통해 아키텍처를 이해할 수 있습니다.
역사와 개요
Stand-alone
데이터베이스가 독립적으로 동작하는 머신으로써, 네트워크에 접속하지 않고 동작하는 형태로 물리적으로 제약이 있다는 단점이 있지만 보안은 높습니다. 특히 복수 사용자가 동시에 작업할 수 없기 때문에 기능적으로 문제가 있습니다.
클라이언트 / 서버 구성
특정 데이터베이스 서버 1대에 복수 사용자의 단말이 접속하는 구성입니다. 이를 통해 물리적으로 데이터베이스 서버와 떨어진 장소에서도 데이터베이스에 접근이 가능해 졌습니다. 그러나 각각의 애플리케이션의 환경에 대응하여 애플리케이션을 갱신 및 관리 하여야 했기에 비용 부담이 발생하였습니다.
웹 3계층 구성
클라이언트와 데이터베이스 계층 사이에 웹 서버 계층과 애플리케이션 계층이 있는 상태로 현재 많이 사용되는 방식입니다.
Ex ) 아파치-톰캣
가용성과 확장성의 확보
견고한 아키텍처 설계를 위해 가용성이 가장 중요합니다. 가용성을 높이는 전략으로는 심장 전략 (신뢰성은 높지만 한 곳에 기능 집중)과 신장 전략 (신뢰성은 낮지만 기능 분산) 이 있습니다. 일반적으로 현재에는 신장 전략을 주로 사용한다.
수확체감의 법칙 : 서버의 대수를 늘려도 어느 수준 이상으로는 시스템 가동률이 올라가지 않는다. (어느 지점 이후로는 더디게 올라간다.)
단일 장애점 : 단일 장애점의 신뢰성이 시스템 전체의 가용성을 결정한다.
서버의 다중화
데이터는 영속적으로 관리되어야 하기 때문에 DB서버의 아키텍처와 저장소는 이를 고려해야 한다. 특히 장애 발생에 대비하여 여러 서버를 구성하는 경우가 있는데 이를 위해 다중화를 구현하는 방법이 있습니다.
기본적인 다중화
Active - Active : 클러스터를 구성하는 컴포넌트를 동시에 가동
Active - Standby (Cold) : Active DB가 다운된 시점에 작동
Active - Standby (Hot) : Standby DB가 평소에도 작동
-> Heartbeat : 지속적으로 Active와 통신하며 장애가 발생했는지 확인하기 위해 통신
리플리케이션
저장소 부분을 다중화 하여 데이터를 다중화 하기 위한 경우로 물리적으로 데이터 저장소를 타중화한 클러스터 구성입니다. 즉 DB 서버와 저장소를 복수로 준비하는 것을 말합니다.
- RAID : 디스크 다중화 (디스크 병렬 구성)
리플리케이션은 물리적 손실에서 가용성이 매우 높아 재해대책으로 이용되는 경우도 있습니다. 리플리케이션은 물리적으로 떨어져 있기 때문에 동기화와 사용성 모두에서 높은 효율을 내기 힘듭니다. 일반적으로 리플리케이션은 피라미드형으로 구현되며, 부모에 걸리는 부하를 분산합니다. 이를 마스터-슬레이브 관계라고도 합니다.
성능을 위한 다중화 : Shared Nothing
일반적인 클러스터링 방식은 디스크를 공유하는 다중화로써 데이터베이스 서버를 늘려도 성능이 무한으로 향상되지 않는다는 단점이 있습니다. 이를 보안하기 위하여 선령적으로 서버와 저장소의 세트를 연결한 Shared Nothing 방식이 고안되었습니다. 이는 극적인 효율을 낼 수 있으며 Goolgle 에서는 이 구조를 '샤딩'이라고 표현했습니다. 이 방식은 서버를 횡으로 나열하기 때문에 성능을 높일 수 있지만, 각각의 서버가 저장소를 공유하지 않기 때문에 동일한 데이터를 액세스 할 수 없으며 이중 하나의 서버가 다운되었을 때 해당 데이터를 액세스 할 수 없다는 단점이 있습니다. 그러므로 다운 되었을 때 다른 서버가 이를 계속 처리 할 수 있게하는 커버링 구성등을 고려해야 합니다.
5장. DBMS 조작 기본 지식
이 부분은 생략합니다. ㅎㅎ
6장. SQL 문의 기본
View (뷰)
'뷰'는 가상의 테이블로 물리적으로는 저장되지 않는다. 뷰를 통해 복잡한 쿼리를 짧게 줄여 업무 효율을 높일 수 있으며 필요한 열과 행만을 이용하기 때문에 효율적이다. 또한 뷰를 이용하는 데에 기억 장치의 용량을 사용하지 않으며 뷰를 삭제해도 참조하는 테이블에는 영향을 주지 않습니다.
Join
- 내부조인 : 조건에 일치하는 것만 출력
- 외부조인 : 한 쪽 테이블을 기준으로 전체를 표시하고 다른 테이블은 값이 있으면 표시
7장. 트랜잭션과 동시성 제어
데이터베이스는 트랜잭션과 lock을 통해 일관성을 유지(보장) 합니다. MySQL 에서는 트랜잭션을 사용할 수 없는 'MyISAM' 과 트랜잭션 구조를 사용할 수 있는 'InnoDB' 두 종류의 테이블을 사용할 수 있습니다. (일반적으로 테이블을 생성할 때 스토리지 엔진을 지정할 수 있으며 MySQL 에서 많이 사용하는 스토리지 엔진은 InnoDB, MyISAM, Archive등이 있습니다. 이때, Archive는 로그 수집에서 많이 사용되는 스토리지 엔진입니다. )
트랜잭션
특징 (ACID)
1) 원자성 : All or Nothing 으로 유명한 것이 원자성입니다. 데이터 조작이 전부 성공하거나 실패하는 것을 트랜잭션 단위로 보증해줘야 합니다.
2) 일관성 : 데이터 조작 전후의 상태를 유지하는 것입니다. 이를 위해 다양한 제약조건을 걸어 놓습니다.
3) 고립성 : 복수의 사용자가 동시에 실행했을 때 서로의 결과에 영향을 주지 않는 것입니다. 즉 각각의 쿼리 실행이 일관성있게 진행되어야 합니다.
4) 지속성 : COMMIT 후에는 그 결과가 지속되는 성질입니다.
고립성
고립성을 보장하기 위해서는 많은 사용자가 참조할 때 다양한 방법으로 제어해야 합니다. 먼저 DBMS 에서는 직셜화 가능 이라는 사양을 지원합니다. 이는 고립성을 보장하지만 성능에서 실용적이지 않습니다.
이보다는 격리수준을 완화해 4개의 단계를 ANSI에서 정의하였습니다.
- 커밋되지 않은 읽기
- 커밋된 읽기
- 반복 읽기
- 직렬화 가능
그러나 이러한 완화에 따라 예기치 못한 다양한 현상들이 나타날 수 있습니다. 더티읽기, 애매한 읽기, 팬텀 읽기가 그 예입니다.
복수 커넥션과 트랜잭션
이 장에서는 MVCC와 이에 따른 MySQL 특성을 설명한다. 먼저 MVCC에 대해 이해한 후에 상황별 특성을 이해하는 것이 좋다.
MVCC는 Multi Version Concurrency Control의 약자로 데이터를 로드(read)할 때 Lock이 되지 않으며 트랜잭션 분리레벨은 Read Committed와 Repeatable Read를 지원한다. 이는 동시성 제어를 위한 기술로써 많이 사용되고 있다.
1) 갱신 중에도 읽기를 수행할 수 있다.
2) 읽기 내용은 격리 수준에 따라 내용이 바뀔 수 있다.
- MySQL의 트랜잭션 격리 수준의 기본 값은 반복읽기 (Repeatable Read) 입니다. 이는 최초 쿼리를 실핼한 시점의 데이터를 읽습니다. 즉, 이후의 트랜잭션의 결과는 조회시 반영되지 않으며 격리 수준의 완화에 따라 일어나는 다양한 현상을 방지할 수 있습니다. (여러번 조회해도 결과가 바뀌지 않음)
- 반면에, 커밋된 읽기는 쿼리를 실행한 시점의 커밋된 데이터를 읽습니다. 즉 다른 트랜잭션에서 데이터를 커밋한다면 그 커밋된 데이터를 읽습니다.
- 갱신을 수행한 트랜잭션은 자신이 수행한 갱신을 즉시 조회 가능합니다.
3) 갱신 시에 배타적 잠금을 얻는다. MySQL 의 잠금은 기본적으로 행 단위로 이루어 지며 그 양이 많을 경우에는 테이블 잠금으로 전환된다.
4) 갱신 중인 테이블은 나중에 온 트랜잭션이 lock 을 획득하려고 할 때 블록된다. 일정 시간이 지나면 'Lock Timeout'된다.
5) 갱신 시에는 그 전의 데이터를 롤백 세그먼트에 UNDO 로그로 저장한다. 이는 롤백시에 갱신 전으로 되돌리는 것이며, 복수의 트랙잭션으로부터 갱신 데이터를 참조하는 데 이용한다. (Read 시에 다양한 버전 유지 가능)
잠금 타임아웃 (Lock Timeout)
in MySQL
set innodb_lock_wait_timeout =1;
갱신 중인 데이터를 다른 트랜잭션이 갱신할 때 이를 기다리는 것을 잠금 대기라고하며, 일정 시간이 지날 때 Timeout이 발생합니다.
교착상태 (Deadlock)
트랜잭션 두 개가 잠금을 얻었을 때, 잠금을 유지하며 갱신을 시도할 때 상황이 바뀌지 않고 지속될 때 이를 교착 상태라고 합니다. DBMS 는 교착 상태를 검출하고 인식하여 한 트랙잭션을 개시 시점까지 롤백합니다. (영향이 작은 트랜잭션을 롤백)
교착상채 대비 방안 (DBMS)
COMMIT 단위를 작게 하여 가능성을 낮춘다.
액세스 순서 일치 (행, 테이블 액세스 순서를 같게 한다. )
읽기 잠금 획득의 사용 줄이기
테이블 잠금을 획득하여 갱신을 직렬화한다.
MySQL 은 인덱스를 통해 쿼리에 인덱스를 추가하여 스캔한 행 전체에 잠금이 되도록 하고 있다.
하면 안되는 트랜잭션 처리
- 오토커밋 : 커밋 부하의 가능성이 높다
- 긴 트랜잭션 : 동시성, 자원의 유효성 저하
트랜잭션을 처리할 때 가장 중요한 것은 교착상태와 타임아웃의 상황을 대비하는 것이라고 생각한다. 교착상태와 타임아웃이 발생했을 때를 대비하여 DBMS의 설정을 조정하고, 프론트 단의 제어로 오류에 대처하여 비효율을 최소화 해야합니다.
8장. 테이블 설계의 기초
관계형 데이터베이스에서 테이블은 매우 중요한 개념입니다. 데이터베이스를 구성하는 모든 데이터는 테이블 형태로 되어 있기 때문입니다. 특히 관계형 데이터베이스가 주류가 된 이유에는 데이터의 정합성을 높이기 위한 설계 노하우가 매우 발달했기 때문이라는 의견이 있습니다. 개인적으로 정보를 관리하기 위한 직관적인 정보 관리 체계로 테이블이 전통적으로 사용되었기 때문에 사용자의 노하우도 많이 발달했다고 생각합니다.
테이블의 기본 개념
테이블 설계는 논리 설계로서 논리의 세계에서 결정된다.
테이블은 원자의 집합으로 어떤 공통의 속성을 가진 것의 집합을 나타내야 한다.
테이블은 현실 세계를 반영한다. (직관적으로) 현실세계에서 존재하는 개념으로 존재해야 한다.
테이블은 사물과 집합의 계층성을 반영해야 한다.
- 집합의 계층성을 반영하는 것은 데이터의 정합성을 유지하는데에 매우 중요합니다. 계층성을 반영하지 못한다면 가비지 값 때문에 잡다한 데이터를 생성하게 됩니다. 이는 테이블을 생성할 때 인간의 의식을 반영한다는 모호성 때문에 발생합니다. 이를 방지하기 위해서 상위 개념에 대해 논리적으로 접근해야 하며 이 테이블이 지속적으로 사용된다는 생각을 바탕으로 유동적, 포괄적인 테이블 설계를 위해 노력해야 합니다.
테이블은 기본키 할당이 기본이다.
정규형
정규형은 설계에서 매우 중요한 개념입니다. 정규형을 풀어서 얘기하면, 데이터의 갱신이 발생한 경우에도 이상이 나타나기 어려운 테이블 형태 입니다. 이를 위해 '테이블은 함수다'라는 개념을 이해해야 합니다. 테이블은 입력 값과 출력 값이 대응됩니다. 기본키와 다른 열 사이에 성립하는 함수적인 유일성을 '함수 종속성'이라고 합니다. 즉 어떠한 열(A) 가 다른 열(B)의 값을 결정할 때 '{A}->{B}' 라고 표기하며 함수 종속성이라고 합니다.
제1정규형 (1NF)
테이블 셀에 복합적인 값을 포함하지 않는다. 모든 셀은 단일값(원자값, 스칼라 값)을 가진다.
제2정규형 (2NF)
부분 함수 종속성을 없앤다. 즉 기본키를 구성하는 열의 일부에만 함수 종속이 존재할 때 테이블을 분리해야 합니다. 이를 통해 전체 열이 기본키만으로 함수 종속을 가지게 됩니다. -> 갱신 이상 방지
제3정규형 (3NF)
이행적 함수 종속을 제거한다. (책에서는 추이함수 종속을 제거한다고 표현했습니다.) 기본키가 아닌 열간에 함수 종속이 발생하여 기본키 입장에서 2단계의 함수 종속이 발생하는 경우에 이를 제거하는 것입니다.
정규화를 진행하며 테이블을 설계하다 보면 테이블의 수는 단계를 거듭할 수록 증가합니다. 많은 테이블을 효율적으로 관리하고 유지보수, 협업을 하기 위해서 설계도는 필연적으로 필요한 요소 입니다. 이를 위하 ER 다이어그램이 고안되었습니다. 이는 테이블의 관계성을 파악할 수 있게 고안된 기술입니다. 이는 엔터티와 관계를 표현하는데, 이때 중요한 것은 외래키입니다. ERD의 관계는 외래키의 존재에 의해 표현됩니다.
9장. 백업과 복구 : 장애 대비
데이터베이스는 서버나 OS의 비정상 종료 등과 같은 시스템 장애에서도 지속성을 유지해야 합니다. 이를 위해서 DBMS 는 백업과 복구를 지원합니다.
로그와 버퍼
로그 선행 쓰기 (WAL, Write Ahead Log)
- 로그로 변경 내용을 기술하고 이를 동기화하는 구조(디스크 성능, 높은 효율성)
데이터베이스 버퍼 : 데이터 파일로의 변경을 효율성 높게 실행
갱신의 흐름
1) 갱신 대상의 데이터(페이지)가 버퍼 풀에 있는지 확인, 없다면 데이터 파일에서 읽기
2) 버퍼 풀의 해당 페이지에서 갱신 수행
3) 커밋과 함께 로그에 기록
4) 데이터 페이지는 데이터 파일에 써짐 (체크 포인트)
5) 체크 포인트 이전 로그 파일은 불필요해짐
크래시 복구
- WAL : 마지막으로 커밋된 갱신 정보
- 데이터베이스 버퍼 : 전부 소실
- 데이터베이스 파일 : 최후 체크 포인트 까지 갱신 정보
크래시 이후에는 갱신 정보를 사용하여 최신 상태로 수정 합니다. 이를 Roll-Forward 라고 합니다.
백업과 복구
일반적으로 DBMS 는 로그를 아카이빙 하여 백업 이후의 임의의 시점으로 복원할 수 있다. 이를 PITR 이라고 합니다. PITR에 이용되는 로그의 이름은 DBMS 마다 다르게 사용되며 각각의 기능에도 차이가 있습니다. 이를 위해 일반적으로 WAL 을 사용하는데, '아카이브 지정'을 통해 크래시 복구용으로는 불필요한 로그도 PITR용으로 보존하는 것을 의미합니다.
바이너리 로그
MySQL 에서는 PITR을 위해 '바이너리 로그'를 이용합니다.
이러면 의문점이 생깁니다. 앞서 설명하였던 Replication 에서의 PITR 처리는 바이너리 로그를 어떻게 관리하는지,,, Replication 에서는 마스터DB가 이를 기록하며 바이너리 로그를 통해 각각의 이벤트를 저장합니다.
백업의 3가지 관점
데이터베이스 상태에 따라
데이터베이스를 가동한 채로 백업 데이터를 얻는 것을 핫 백업(트랜잭션 구조, 스냅샷, mysqldump 유틸리티, OS의 기능) 이라고 합니다. 반면에 콜드 백업(디렉터리와 파일, 테이더테이스의 기능)은 오프라인 백업으로 대상 데이터베이스를 정지한 후에 데이터를 얻습니다.
백업 데이터 형식에 따라
SQL 기반의 텍스트 형식을 사용하면 논리 백업이며, 데이터 영역을 그대로 덤프하는 이미지로 바이너리 형식으로 기록된다면 물리 백업입니다.
데이터 양에 따라
전체 데이터를 매일 백업 한다면 풀 백업이며, 우선 풀 백업을 한 후에 갱신된 데이터를 백업 하는것을 부분 백업이라고 합니다. 특히 부분 백업에는 차등백업과 증분백업이 있습니다. 풀 백업 이후의 갱신 데이터를 백업하는 것을 차등 백업이라고 하며 백업 이후의 갱신 데이터를 백업한다면 증분 백업 이라고 합니다.
기본적으로 풀 백업만으로 복원하는 것은 백업 시점입니다. 하지만 WAL 을 증분 백업으로 보존하여 풀 백업 시점 이후의 임의 시점까지 복원 가능합니다. 이를 롤포워드 리커버리라고 합니다.
10장. 성능 향상
데이터베이스 성능은 매우 중요하다. 하핳 일반적으로 데이터베이스의 성능이 중요한 원인은 데이터베이스가 지속적으로 이용되는 저장소이기 때문이다. 기한이 없고 지속적으로 데이터는 늘어나기 때문에 시간이 지날 수록 데이터의 양은 많아지는 데에 반해 물리적인 디스크 공간은 한정되어 있어 성능 이슈가 발생하게 된다. 이를 측정하는 지표에는 응답 시간과 처리율 (초당 트랜잭션의 갯수 : TPS)이 있다. 동시 실행 처리 수가 증가하다가 한계에 도달하면 응답시간은 상승하고 처리율은 떨어지는 버틀넷 포인트(병목 현상)가 발생합니다.
병목 원인
- 취급하는 데이터의 양이 많다.
- 자원 증가를 통한 해결이 어렵다. (구조적 한계/ 비용적 한계)
주어진 자원 내에서 융통성있게 업무를 처리하기 위해 튜닝이 발달하였습니다.
튜닝
데이터베이스가 결과를 통지하는 과정
1) Parser : 구문 오류가 없는지 확인하는 내부 프로그램입니다.
2) 실행 계획과 옵티마이저 : 데이터에 어떤 경로로 접근할 지 결정합니다.
3) 통계정보 : 실행계획을 세울 때 참조하는 정보입니다. (테이블의 행,열 의 수/ 각 열의 길이와 테이터형 / 테이블의 크기 / 제약정보와 키/ 값의 분산과 편향)
- 이렇게 옵티마이저를 통해 실행계획을 세울 때 많은 작업을 거치게 된다. 업무를 하다 보면 같은 SQL 을 여러번 날리는 경우가 많은 데 그때마다 같은 옵티마이징 과정을 반복하는 것은 비효율적이다. 그래서 DBMS 는 SQL 별로 실행 계획을 저장하는데, 이때 이용하는 것이 라이브러리 캐시이다. 즉, Parsing 을 끝낸 후에 라이브러리 캐시에서 같은 SQL 이 있는지 확인 한 후에 없으면 실행계획을 세우고 이를 라이브러리 캐시에 저장한다.
INDEX
1) FULL SCAN : 전체 테이블 조회
2) RANGE SCAN : 인덱스 기반 조회, 조건을 주어 번위를 제한하는 경우
인덱스는 색인으로써 검색 효율을 높여준다. SQL 문을 변셩하지 않아도 성능을 개선할 수 있으며, 테이블의 데이터에 영향을 주지 않는다는 장점이 있다. 이는 'B-tree' 구조를 기반으로 정렬이 되어 있기 때문이다. 이는 탐색에 특화된 알고리즘이다. B-tree 탐색의 과정은 루트에서 탐색을 시작해 데이터의 대소를 비교하며 범위를 좁혀 목적 리프 노드에 도달한다. 이러한 구조는 균형 트리로의 지속적인 작업을 야기하는데, 데이터의 삽입 삭제에 따라 변형되는 트리의 균형을 되찾는 작업을 인덱스 재구성이라고 한다. 인덱스를 사용할 때 주의할 점은 데이터의 탐색에만 특화되어 있다는 점이다. 인덱스는 갱신에 취약하다.
Review.
이 책은 기본 개념에 대해 전반적으로 정리하는데에 도움이 됩니다. 그러나 단원 별로 깊이의 차이가 있어서 책의 제목처럼 '데이터베이스 첫걸음'으로 선택하기엔 조금 무리가 있을것 같습니다.
짧은 분량에다 새로운 관점으로 데이터베이스에 접근하고 있기 때문에 다양한 시각으로 데이터베이스 개념을 습득할 때 도움이 되었습니다.bb