2009년 5월 31일 일요일

MySQL Cluster의 특징 2

◆레코드 데이터와 인덱스를 메모리 상에서 관리

NDB 스토리지 엔진의 행 데이터는 , 데이터 영역, 인덱스 영역을 포함해서 전부 메모리상에서 관리된다.

그 때문에 데이터 액세스는 매우 빠르다.

무엇보다도 메모리는 디스크에 비교해 꽤 비싸기 때문에 수백기가급의 대량 데이터를

다룰 필요가 있다면 MySQL Cluster로 전부 관리하는 것은 현실적이지 않을 수 있다.

다만, MySQL에서는 테이블단위로 스토리지 엔진을 선택가능하기 때문에 고속화가

필요한 테이블은 NDB로 하고 그 이외에는 InnoDB이나 MyISAM으로 하는 구성도 가능하다.

또 5.1에서부터는 테이블데이터(인덱스영역은 빼고)를 디스크상에서 관리할까 메모리상에서

관리할까 하는 선택이 가능하게 된다.

데이터양이 많은 시스템이라서 MySQL Cluster를 사용할 수 없는 것은 아니다.

◆트랜잭션에 대응

InnoDB와 마찬가지로 트랜잭션의 커밋, 롤백이 가능하다.

다만, 분리 레벨은 Read Committed만이 지원된다.

읽고 있는 중에는 Lock을 걸지 않는 것도 InnoDB하고 같다.

◆체크포인트와 그룹 커밋에 따른 영속화

메모리상에서 관리한다라고 하면 머신을 멈추면 모든 데이터가 날라가버린다고 생각할 지도 모른다.

그러나 MySQL Cluster(Data Node)에서는 정기적으로 체크포인트처리가 수행되어

메모리상에 있는 데이터가 디스크에 저장된다. 정상정지나 이상정지등의 이유로 Data Node가

멈추어 재기동이 필요하게 된 경우에는 디스크로부터 테이블 데이터를 읽어들여 메모리에서

전개하게 된다. 그 때문에 Data Node의 프로세스를 멈추어도 테이블 데이터를 잃어버릴 염려는 없다.

이 처럼 Data Node의 모든 메모리데이터를 디스크에 쓰는 처리를 Local Checkpoint라고 부르고 있다.

Local Checkpoint는 기본적으로 수분 간격으로 수행되어진다. (TimeBetweenLocalCheckpoint라는 파라미터로 제어 가능하다. )

그렇지만 이 외에도 트랜잭션의 커밋결과를 디스크에 저장하는 처리도 이루어진다.

이 처리는 Global Checkpoint라고 불리운다.

그러나 InnoDB하고 달리, 커밋 동시에 저장은 하지 않고 일정시간(TimeBetweenGlobalCheckpoint에서 지정한 밀리세컨드)간격으로 그때까지의 커밋정보가

같이 디스크에 쓰여지게 되어있다.

이것은 성능을 높이기 위한 조치이다.

커밋시 동시 저장의 목적은 정전등의 노드 장해가 발생하더라도 직전 커밋정보까지 복원가능케 하는 것이 지만

MySQL Cluster에서는 같은 데이터를 여러개의 노드가 가지고 있기 때문에 1개의 노드에 장해가

발생하더라도 시스템정지으로 되지는 않는다. 그 때문에 엄밀한 커밋시 동시 저장을 하지 않아도

문제는 없다라는 것이다. SQL문등 어플리케이션레벨에서의 튜닝이 필요한 환경에서는 REDO로그 파일에 동기 저장이 bottle neck이 되는 경우가 많지만

MySQL Cluster에서는 그런 걱정이 없다. 이것도 성능 향상에 큰 공헌을 하고 있다.







MySQL Cluster의 특징

MySQL Cluster는 다음과 같은 특징을 가지고 있다.

  • 레코드 데이터와 인덱스를 메모리 상에서 관리
  • 트랜잭션대응
  • 체크포인트와 그룹커밋에 따른 영속화
  • 테이블데이터를 분산배치
  • 동기 replication
  • 복수의 replication 단위
  • shared nothing형
  • Data Node의 fail over 구조를 스스로 갖고 있다.
cluster구성 특유의 기능도 있지만 레코드데이터와 인덱스를 메모리 상에서 관리한다는 매우 큰

특징도 지니고 있다.


2009년 5월 30일 토요일

MySQL 개요2

◆Data Node(ndbd)

Data Node는 MySQL Cluster의 중핵에 해당되는 것으로 테이블 데이터의 분산관리, 동기 replication, 분산 트랜잭션 제어, failover/recovery등을 담당한다. 

실제로는 ndbd라는 프로세스가 처리를 수행한다. 

다른 말로 말하면 Data Node를 기동하기(MySQL Cluster를 이용하기)위해서는 ndbd프로세스를 
새롭게 기동할 필요가 있다는 말이다. 

◆SQL Node(mysqld) 
SQL Node는 Data Node에 대해서 테이블 데이터의 취득, 트랜잭션제어등을 지시하기 위한 노드이다. 
MySQL Cluster에서는 NDB API 라는 인터페이스가 있어서 SQL Node에서 NDB API를 이용해서

Data Node에 접근함으로써 테이블데이터 취득, 트랜잭션 제어등을 수행할 수 있다. 

mysqld는 이 NDB API를 호출하는 코드를 가지고 있어 (sql/ha_ndbcluster.cc), mysqld에서부터 이용자가 NDB스토리지엔진에 접근했을 경우에는 
mysqld가 내부적으로 NDB API경유로 Data Node에 접근하고 결과를 되돌리는 처리를 수행하고 있다. 

이때문에  기본적으로 NDB API를 이용자가 의식할 필요는 없다. 

NDB API를  이용한 프로그램을 스스로가 작성해서 직접 Data Node에 접근하는 것도 가능하다.

이 경우에는 mysqld를 필요로 하지 않는다. 

NDB API는 C++로 만들어져 있기 때문에 C++의 지식이 있으면 그다지 곤란없이 프로그램을 작성할 수 있다. 


◆Management Node(ndb_mgmd)

Management Node는 Data Node와 SQL Node관리를 수행하기 위한 노드이다. 

MySQL Cluster에서는 각 노드에  특별한 노드 번호를 할당해서 식별하고 있다. 

또 Data Node에는 특유의 설정파라미터가 다수 있다.  이것의 정보는 Management Node가 일괄 관리한다. 

Data Node와 SQL Node는 기동시에 우선 Management Node에 접속해서 자기 자신의 설정정보를 얻거나  노드 번호에 
관한 정보(예를 들면 노드 번호3은 SQL Node인가 Data Node인가 Management Node인가하는 정보)를 취득하거나 한다. 

MySQL Cluster가 기동한 뒤에는 큰 부하가 되는 처리는 Management Server에 할당되지 않기때문에  장비의 스펙으로서  고성능의 것이 요구되어지지 않는다. 

 


MySQL Cluster개요

MySQL Cluster에 따라서 성능및 가용성을 향상가능하다.  특히 성능의 향상은 극적이 부분이 있어 초간 10만건을 넘는 검색/갱신을 처리했던 사례도 있다.

여기에서는 이 MySQL Cluster의 개요와 이용방법에 대해서 기초적인 부분을 해설해 본다.

MySQL Cluster 를 구성하는 프로세스
MyISAM과 InnoDB등 보통 스토리지엔진만을 사용하는 경우, 데이터베이스 서버 구성으로서는 MySQL본체 프로세스(mysqld) 한개만 쓰이는 것이 기본형이 된다. 

이 응용으로써 replication에 따른 마스터의 mysqld에 대해서 복수의 슬레이브 mysqld를 구성하는 것도 가능하지만 어쨌든 MySQL의 본체 프로세스 mysqld를 1개, 또는 복수 사용하는 구성이 된다. 

한편 MySQL Cluster의 경우 조금 복잡한 구성이 된다.  

다음의 3종류의 노드로부터 구성되고 이 노드를 전부 준비해 둘 필요가 있다. 

  • Data Node(ndbd)
  • SQL Node(mysqld)
  • Management Node(ndb_mgmd)


2009년 5월 25일 월요일

MySQL Cluster

MySQL에서는 MyISAM, InnoDB, MEMORY등 여러가지 다양한 스토리지엔진이 존재해서

용도에 맞게 테이블단위로도 선택가능하다는 특징이 있다.

많은 스토리지엔진은 단위별로 DB서버상에서 사용하는 것을 전제로 하고 있으나

클러스터링 구성이 가능한 NDB라는 스토리지엔진도 있다.

이 NDB스토리지엔진을 사용한 MySQL환경을
MySQL Cluster
라고 부른다.

2009년 5월 24일 일요일

InnoDB 모니터 3

SHOW ENGINE INNODB MUTEX의 출력항목

SHOW ENGINE INNODB MUTEX으로 표시되는 항목은 다음과 같다.

mysql>SHOW ENGINE INNODB MUTEX\G
***************** 1. row *************************
Type: InnoDB
Name: &purge_sys->mutex:trx0purge.c
Satus: count=2, spin_wait=0, spin_rounds=0, os_waits=0, os_yields=0, os_wait_times=0

Type는 항상 InnoDB가 된다.
Name은 소스 파일명과 mutex의 이름이다.
Status는 mutex의 상태를 나타낸다. 자세하게는 다음과 같다.

  • count mutex가 몇번 요청되었나
  • spin_waits spinlock이 몇번 실행되었나
  • spin_rounds spinlock의 회전(round)수(spin_rounds/ sin_waits=평균회전수)
  • os_waits spinlock이 동작하지 않았을 경우의 OS대기회수
  • os_yields mutex가 timeslice와 yield를 포기한 횟수
  • os_wait_times os대기시간(msec.)


timed_mutexes 서버변수(표준은 0)를 1로 하면 os_wait_times는 OS의 wait 시간의 합계(msec.)가 된다.

InnoDB 모니터 2

SHOW ENGINE INNODB STATUS와 innodb_monitor출력항목

SHOW ENGINE INNODB STATUS하고 innodb_monitor의 출력에 포함되는 항목(섹션)은 다음과 같다.

  • SEMAPHORE mutex의 spin wait수, round수, OS의 wait수등의 통계정보
  • LATEST FOREIGN KEY ERROR 최후의 Foreign Key에 관한 에러
  • LATEST DETECTED DEADLOCK 최후의 deadlock의 에러
  • TRANSACTIONS lock대기의 정보
  • FILE I/O I/O스레드정보
  • INSERT BUFFER AND ADAPTIVE HASH INDEX Insert Buffer와 Adaptive Hash Index의 상황
  • LOG 로그상황
  • BUFFER POOL AND MEMORY Buffer pool의 사용상황, 페이지의 이용상황
  • ROW OPERATIONS 메인스레드의 상황

InnoDB 모니터(SHOW ENGINE INNODB STATUS)

InnoDB에서는 내부상태를 출력하는 InnoDB모니터 기능을 준비하고 있어 성능등의 조정에 도움이 된다.

다음과 같은 방법으로 InnoDB 모니터가 가능하다.

>InnoDB 모니터를 개시한다.
CREATE TABLE innodb_monitor( a INT) ENGINE=INNODB;

CREATE TABLE innodb_monitor를 실행하면 에러 로그파일에 15초단위로 status가 출력된다.

>InnoDB 모니터를 중지한다.
DROP TABLE innodb_monitor;

출력을 멈추게 하기위해서는 DROP TABLE innodb_monitor를 실행한다.

>광범위 정보를 모니터한다.
SHOW ENGINE INNODB STATUS;
SHOW INNODB STATUS;

SHOW ENGINE INNODB STATUS에서는 InnoDB정보가 다른 SHOW문과 마찬가지로 표준출력으로 표시된다.
SHOW INNODB STATUS는 SHOW ENGINE INNODB STATUS로 개정되었다.

>MUTEX통계를 표시한다.
SHOW ENGINE INNODB MUTEX;

SHOW ENGINE INNODB MUTEX는 MUTEX정보(상호 배제)를 표시한다.


InnoDB 특징및 제한

InnoDB제한 및 그 특징은 다음과 같다.

  • 테이블의 필드수는 1000개까지
  • VARCHAR(), BLOB, TEXT필드를 제외하고 레코드크기의 최대는 1/2페이지사이즈
  • 모든 VARCHAR()의 최대 사이즈의 합계는 65535까지
  • FULLTEXT인덱스는 아직 지원하지 않음.
  • SELECT COUNT(*)은 인덱스를 이용해서 계산
  • SHOW TABLE STATUS는 InnoDB에 관해서는 정확한 값을 보여주지 못한다.
  • 다음에 할당해야하는 AUTO INCREMENT값은 디스크에 기록되지 않는다. (MyISAM은 디스크에 기록)


2009년 5월 20일 수요일

InnoDB flush 2

innodb_flush_method

데이터 파일과 로그파일의 flush방법을 지정한다. 
이 지정은 Unix계열의 운영체제에서만 동작한다. 

Windows에서는 항상 무효로 async_unbuffered고정이다. 

innodb_flush_method={fdatasync|O_DSYNC|O_DIRECT}

지정가능한 값은 다음과 같다. 

fdatasync 표준값.  데이터 파일과 로그 파일을 fsync()를 사용해서 flush.

O_DSYNC O_SYNC로 로그 파일을 flush. 데이터 파일을 fsync()를 사용.

O_DIRECT O_DIRECT(Linux에서 사용가능)로 데이터 파일을 오픈.
                      fsync()로 데이터 파일과 로그 파일을 flush.

현재, SAN상에 데이터 파일과 로그 파일이 있으면 O_DIRECT인 경우에 퍼포먼스가 
나빠진다는 보고가 있다. 



2009년 5월 19일 화요일

InnoDB flush 1

innodb_flush_log_at_trx_commit

트랜잭션 상황을 로그에 써 넣는 타이밍은 innodb_flush_log_at_trx_commit옵션으로 설정한다. 

innodb_flush_log_at_trx_commit={0|1|2}

지정가능한 값은 다음과 같다. 

0  log buffer내용이 1초간격으로 로그파일에 쓰여지고 flush된다.  commit할 때는 아무것도 하지 않는다. 

1  log buffer내용이 commit할 때에 로그 파일에 쓰여지고 flush된다. 

2  log buffer내용이 commit할 때에 로그 파일에 쓰여지고 flush는 1초간격으로 이루어진다. 

표준은 1로 , 안전성은 0이 가장 낮다.  만약 서버가 고장났을 경우에 1초간의 트랜잭션은 사라지기 때문이다.  

물론, 1이나 2의 경우에도 급한 정전, 운영체제의 crash에 따른 영향을 100% 피할 수는 없다. 

replication을  실행하고 있는 다면 다음과 같이 설정하고 가능한한 손실을 적게하는 것이 낫다. 

replication을 사용하고 있는 경우 설정
[mysqld]
innodb_flush_log_at_trx_commit=1
sync_binlog=1




2009년 5월 13일 수요일

InnoDB REDO,UNDO로그구조

REDO로그의 각 레코드는 다음과 같다. 

  • Page Number( 4bytes) 테이블스페이스내의 페이지 번호
  • Offset (2bytes)  페이지내의 옵셋
  • Record Type(1byte)  INSERT, UPDATE, DELETE의 구별
  • 변경후의 데이타

UNDO로그

 UNDO로그의 각 레코드는 다음과 같은 관리정보를 지닌다. 
  •  Primary Key의 값(페이지 번호가 아니다.)
  • 이 레코드를 변경한 트랜잭션ID
  • 변경전의 각 필드값
테이블스페이스내의 롤백세그먼트에 UNDO로그의 각 레코드가 기록된다. 

INSERT조작의 경우에 , 커밋되면 롤백세그먼트에서 UNDO로그의 레코드가 지워진다. 

UPDATE, DELETE의 경우에,  버퍼가 디스크에 flush되고 history list라고 불리우는 리스트에 UNDO로그 레코드가 추가된다. 

 history list에 있는 UNDO 로그의 레코드는 필요하지 않게 되었을 때 리스트로부터 지워진다. 

이것을 PURGE operation이라도 부른다. 




InnoDB 레코드 구조

레코드를 보존할 때에는 데이터에 관리정보가 추가된다. 

  • Record Header(6bytes)  다음 레코드에 대한 포인터, 필드수등
  • Transaction ID (7bytes)  타임스탬프
  • Roll Pointer(7bytes)  변경전 레코드 포인터
  • Field Pointer(1~2bytes/field) 다음 필드 개시위치 

2009년 5월 12일 화요일

테이블 스페이스 페이지, 세그먼트

InnoDB테이블 스페이스는 페이지 단위를 최소단위로서 데이터가 관리된다. 
관리단위는 다음과 같다. 

  • 1 Page = 16KB
  • 1 Extent = 64 Page(1MB)
  • 1 Segment = N Extent
  • 1 Table Space = M Segment 
(N,M은 정수)

레코드는 페이지안에 포함되어 한개의 페이지에 복수개의 레코드가 저장되게 된다. 
세그먼트는 사용목적에 따라서 여러개의 종류가 있다. 

  • Rollback Segment (MVCC를 위해 구 버전의 레코드를 보존등)
  • Leaf node Segment ( B+ Tree의 Leaf를 위한 세그먼트)
  • non-Leaf node Segment


2009년 5월 10일 일요일

InnoDB의 인덱스

InnoDB에서는 레코드 저장에 「Clustered Index」라는 특별한 인덱스를 채용하고 있다. 

1. Clustered Index
InnoDB에서는 clustered index라는 인덱스를  한 테이블당  한개 작성한다. 
이것은 B+ Tree인덱스이다. 
인덱스의 Leaf에 실레코드가 직접저장된다. 
clustered index는 primary키를 중심으로 인덱스를 작성하고 있다. 
만약 사용자가 테이블에  primary 키 또는 unique키를 정의하지 않았을 경우 , InnoDB자신이 
내부에 자동적으로 primary키 대신의 것을 생성하고 그것에 따라서 인덱스를 만든다. 

InnoDB가 자동적으로 할당한 것은 사용자는 볼 수 없다. 
InnoDB에서는 이 clustered index키를 중심으로  행 lock를 동작시킨다. 

따라서 만약에 사용자가 primary 키 또는 unique 키를 테이블에 정의해놓지 않으면 행 lock은 동작하지 않으므로 주의 해야한다. 

2. Secondary Index
Secondary Index는  Primary 키이외의 인덱스에 대해서 작성되는 것이다. 
인덱스 leaf에 primary 키의 값과 non-primary키가 셋트로 기록된다. 

primary 키이외의 키가 query에서 사용되었을 경우 이 secondary index가 탐색되어 판명된 primary 키를 중심으로 레코드를 읽어 냄으로  2단계 처리가 이루어짐으로 검색의 속도가 떨어진다. 
secondary index의 소트 알고리즘도 B+ tree이다. 
또 한개의 non-unique인덱스당 한개가 작성된다. 

3. Adaptive Hash Index
테이블이   거의 메모리에서 처리가능할 때 InnoDB는 자동적으로 이 테이블의 hash index를 메모리(buffer pool)안에 작성한다.  이 인덱스를 사용하면  키 값으로 부터 레코드의 기술 위치를 알 수 있다. 이것이 Adaptive Hash Index이다. 

모든것이 index화되어서 buffer pool에서 넣어지는 것이 아니라 액세스 빈도가 많은 것이 있으면 그것에 맞추어서 작성된다. 

레코드 검색시 B+ tree 인덱스를 검색하기 전에 Adaptive Hash Index를 조사한다. 
만약 Adaptive Hash Index에 레코드의 기술위치정보가 있으면  그 밖의 B+ Tree 인덱스 검색은 건너뛰고 직접 레코드를  읽어들이게 된다. 



2009년 5월 7일 목요일

InnoDB 스레드

InnoDB처리를 실행하는 전용 스레드가 만들어지고 이것이 백그라운드에서 요구를 순차적으로 처리해 간다. 
이 스레드는 한개의 클라이언트당 한개의 스레드가 생성되는 것이 아니고 MySQL서버 한개당 한정된 수만큼만 생성된다. 

이 스레드 수는 다음의 MySQL서버의 옵션에서 변경가능하다. 

innodb_thread_concurrency 

추가적으로 MySQL버전에 따라서 표준 스레드수가 다르다. 

5.1.12-beta  8
5.0.8-beta ~ 5.0.18  20(무제한)
5.0.19~5.0.20  0(무제한)

5.0.19상위 버전에서는 20은 20개라는 의미로 변경되었다. 

현재, 이 수를 마구 늘리면 좋다는 것은 아니다.  테스트 툴등을 사용해서 어느정도의 클라이언트 수 일 때 최적인지 확인해두는 것이 좋을 것이다. 

우선은 8개전후로 시도해보는 것이 좋다. 

이외에도 I/O처리를 담당하는 스레드가 생성된다.  
「read thread」「write thread」「log thread」「insert buffer thread」라고 불리우는 4개의 스레드이다. 

다음의 옵션으로 이 수를 늘리는 것은 가능하지만(4이상) , 추가된 것은 read, write의 예비 역할을 하게 된다. 
그러나 이 옵션은 5.1.12-beta에서는 windows에서만 동작한다. 

innodb_file_io_threads