레이블이 Binary log인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Binary log인 게시물을 표시합니다. 모든 게시물 표시

2010년 12월 26일 일요일

RAID 인터페이스의 WriteCache와 로그(BinaryLog 및 Redo log) 동기화


RAID 인터페이스의 WriteCache
  • 일반적인 DBMS용 장비에는 여러개의 디스크가 장착되어 있고,
  • 각 디스크들이 스트라이핑(RAID-0)되고 다시 미러링(RAID-1)된 형태로 구성된다(물론 그 반대도)
  • 그리고, 이러한 RAID 인터페이스에는 기본적으로 Cache 메모리가 장착되어 있으며,
  • 이 Cache 메모리는 쓰기용도와 읽기 용도를 구분해서 사이즈를 지정 가능하다.
  • 또한, 운영체제에서는 Write-Policy를 관리하여
    Cache 메모리까지 동기화시킬지(Write-back)
    최종 디스크까지 동기화를 시킬지(Write-through) 결정
  • 어떤 RAID 인터페이스는 BBU (Battery backed unit)이 장착되어 있어서
    시스템의 장애시에도 쓰기 캐시의 내용이 손상되지 않도록 한다.

Binary Log & Redo log
  • Binary log와 Redo log는 모두 Sequential I/O 방식으로 기록된다.
  • 하지만, Binary log를 디스크에 기록하는 방식인 sync_binlog와
  • Redo log를 디스크에 기록하는 방식인 innodb_flush_log_at_trx_commit가 동기화 방식으로 설정되면,
  • InnoDB의 Commit 단위 또는 MyISAM의 쿼리 실행 단위로 디스크 쓰기 요청을 발생시키게 된다.

테스트 결과
  • InnoDB의 redo log를 대상으로 테스트 해보지 못했고, MyISAM의 binary log를 대상으로 테스트
  • 하지만, InnoDB의 redo log도 크게 다르지 않을 것으로 예상됨
  • 아래 3가지 상황으로 IO 상태를 모니터링해 보았다
    (이 장비에는 디스크는 1개, RAID 인터페이스가 없고 Write cache도 없다)
    (또한 이 장비에서는 초당 SELECT - 100건, INSERT - 50건, UPDATE - 20건 정도의 부하가 있었음)
    - A) BinaryLog (활성) + sync_binlog (1, 동기화)
    - B) BinaryLog (활성) + sync_binlog (0, 비동기화)
    - C) BinaryLog (비활성)
  • 각 상황별 테스트 결과를 보면
    - B)와 C)의 경우, 거의 비슷한 결과를 보여주면서 양호하게 처리하고 있지만,
    - A)의 경우에는 Write request 회수도 상당히 높아지고 처리 시간도 상당히 소요되는 것을 알 수 있다.
    - 실제 Application에서는 A)의 경우에는 상당한 Slow Query가 발생하고 있었다.
  •  

결론적으로
  • DBMS용도의 장비라면 최소 2~3개 이상의 디스크에 Cache 메모리를 가진 
    RAID 인터페이스가 상당히 효과적으로 I/O를 개선해줌을 알 수 있다.
  • 만약, 비용적인 이유로 RAID와 Cache메모리 장착이 어렵다면 Binary log또는 Redo log의 
    동기화 옵션을 비활성화 시키는 것을 추천한다 
    (물론, 1~2초 정도의 데이터 손실을 감안할 수 있다면) 
    이로 인해서 얻을 수 있는 것과 잃을 수 있는 것은 상당히 클 것으로 보인다.
  • 또한, 일반적으로 MySQL 에서는 RAID의 Cache 메모리를 Read 보다는 
    Write를 위한 Cache로 집중 할당하는 것이  효과적일 것으로 생각한다.






MySQL Binary log의 일관성 유지


MySQL Binary log의 일관성 유지
MySQL Binary log는 매번 디스크와 동기화시키지 않는 것이 Default 설정이다.
그래서, 만약, 운영 체제나 장비(MySQL만의 장애가 아닌) 장애가 발생하면, Binary log의 마지막 부분들을 소실될 가능성이 있다.
이러한 손실을 막기 위해서, sync_binlog 시스템 변수를 설정하여 Binary log가 매 N개의 쿼리 이후 디스크와 동기화되도록 설정할 수 있다.
sync_binlog 옵션으로 1을 설정하는 것이 가장 안정적이지만, 가장 느린 방식이기도 하다.
하지만, sync_binlog를 1로 설정했다 하더라도, 여전히 시스템의 장애가 발생했을 때, 데이터베이스의 내용과 Binary log의 내용이 일치하지(일관되지) 않을 가능성이 있다.
예를 들어서, InnoDB 엔진을 사용하는 테이블에서 COMMIT이 실행되면, MySQL은 모든 트랜잭션 쿼리들을 Binary log에 기록하고 그 이후 InnoDB의 트랜잭션을 Commit하게 되는데,
만약, 이 두 조작 사이에 MySQL 서버에 장애가 발생하게 되면, InnoDB의 트랜잭션은 Rollback되지만, Binary log에서 그 쿼리는 지워지지 않고 그대로 남아 있게 된다.
이러한 문제를 해결하기 위해서는 innodb_support_xa 시스템 변수를 1로 설정해야 한다.
이 시스템 변수는 또한 InnoDB의 XA 트랜잭션과도 연관을 가지게 되며, Binary log와 InnoDB 데이터의 동기화도 보장하는 역할도 한다.
==> 하지만, sync_binlog=1 설정은 상당한 Disk 비용을 지불해야만 한다.
    (자세한 내용은 sysbench로 벤치마킹을 실행해보면 쉽게 알 수 있다)
==> 일반적으로 다들 별로 신경 안써지만, sync_binlog=1인 설정에서는
    Binary log에 트랜잭션 쿼리(또는 레코드)가 기록되고, fsync(파일 동기화)가 되어야지만, 
    비로소 InnoDB의 트랜잭션이 Commit될 수 있다는 것을 명심해야 한다.
==> sync_binlog를 1 이외의 값으로 설정하는 것과, Replication의 delay는 전혀 무관하며,
    sync_binlog 값의 설정은 Binary log의 Disk 동기화만 관리하게 된다.
==> sync_binlog=0으로 설정하게 되면, Binary log의 Disk 동기화는 MySQL이 아닌 운영체제에 의해서
    진행되며(처리되며), 일반적으로 EXT3와 같은 File system은 5초 주기로 Cache를 Flush하는 것으로 알려져 있다.