2014년 1월 24일 금요일

high_performance_mysql_3rd_edition 레플리케이션

레플리케이션을
속도로만 생각하지 말자
재해복구, 백업, 통계, 데이터 웨어 하우싱 등으로도 사용가능
싱크 방법
특징
*비동기임
동기화에 얼마나 걸릴지 아무도 보장하지 않음

새로운 버전의 서버는 예전 서버를 복제 할수있음
반대는 안됨~
*마이너 버전끼리는 됨
마스터에는 많은 무리를 안줌

하는법
마스터 binary log 를 enable 하면됨(이건 기본으로 킴)
순서
1.마스터가 데이터의 변경을 바이너리 로그에 저장
(binary log events 라고도함)
트렌젝션이 커밋 되기 바로직전에 저장
여러 트랙잰션이 동시에 일어나서 트랜잭션당 쿼리 순서가 바껴도
트랜잭션 순서대로 저장
저장후 commit ok 하라고 storage engine 에 알림

슬레이브가 연결을 요청하면 슬레이브당 Binlog dump thread 를 만들고 binlog 를 넘겨줌

2.레플리카가 binary log 를 relay log에 복사
레플리카가 I/O slave thread로 마스터에 연결
마스터의 Binlog dump thread에서 데이터를 요청하고 그 후 대기
동기화가 된후 부터는 binlog dump 가 이벤트를 날리면 데이터를 요청하는형식 같음

받아온 데이터를 로컬 relay log에 저장
*4.0이전 버전은 싱크 방법 다름
3.레플리카가 relaoy log 를 재생해서 변경 데이터 적용
sql thread가 relay log를 읽어서 적용
(병행으로 읽어서 데이터 반영 가능)
종류
statement-based replication
row-based replication

레플리카로 풀리는것들
데이타 분산
지역적으로 떨어진 데이터 센터에 위치
로드 벨런싱
백업
하지만 따로 백업도 하는게좋다.
고가용성 및 failover
it prevent single point of failure
새로운 버전 Mysql테스트
슬레이브로 만들고 테스트


레플리케이션 세팅방법
1.replication 계정을 각각의 서버에 생성
I/O thread드가 일반 클라 연결을 맺기 때문에 래플리케이션 전용 유저를 모두에 생성
GRAMNT REPLICATION SALVE, REPLICATION CLITENT ON *.* TO repl@'162.126.0.%' INDETIFID BY '비번'
2.마스터 and 레플리카를 설정
master 변경
my.cnf
log_bin = mysql-bin
server_id = 10(유니크 서버 아이디 10부터 시작하자why default value 가 1이거든)

재시작후
SHOW MASTR STATUS 해서 bin log 켜졌는지 확인
slave 변경
my.cnf
log_bin = mysql-bin
server_id = 12
relay_log = /var/lib/mysql/mysql-relay-bin
log_slave_updates = 1   #to make the replica log
the replicated events to its own binary log
read_only = 1

3.레플리카시작 후  마스터에게 접속해 복재 시작하라고 명령
쿼리 창에서
CHANGE MASTER TO MASTER_HOST='server1',
MASTER_USER='repl',
MASTER_PASSWORD='비번',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS = 0 #0부터 찾기 시작해서 맞추라는뜻

확인
SHOW SLAVE STATUS

시작
START SLAVE;

http://search.cpan.org/~gmax/MySQL-Sandbox-3.0.12/lib/MySQL/Sandbox.pm#Making_a_replication_sandbox
에서 쉽게 할수있다


마스터가 있는 상태에서 레플리케이션 추가
1.마스터 clone 후 init 하는 방법
1.master의 스냅샷을 만든다.
2.마스터의 로그 파일과
스냅샵 시점의 바이트 오프셋을 기록한다.
(이후 logfile coordianates 라고한다)
SHOW MASTER STATUS 로 확인 가능
3.스냅샷 시점으로 부터 마스터의 binary log가 존재해야한다.

2.복사 방법
cold copy
1.마스터 셧다운
2.파일을 레플리카로복사(appendix c에 효율적 복사 방법)
3.new binary log 설정 후 마스터 시작
4.CHANGE MASTER TO 로 레플리카 시작
*순간 서비스 안됨
warmcopy
myisam 만 사용한다면 가능
mysqlhotcopy(rsync)로 가능 chapter 15확인
mysqldump
innoDB만 사용한다면
덤프후 레플리카로 복사
레플리카에게 마스터 쫓아가라고 명령

mysqldump --single-transaction --all-databases --masteres --master-data=1 --host=server1 \| mysql --hoset=server2
만약 트랜잭션 지원테이블이 아니라면
--lock-all-table로 대처 가능
from another replica
1.mysqldump 에 --master-data 옵션 안됨
2.show slave status 로 binary log corrdinates 확인가능

*만약 복사대상의 레플리카가 마스터와 싱크가 맞지 않는다면 잘못된 데이터를 복사하게됨

3.추천하는 레플리케이션 설정
마스터
sync_binlog=1
트랜잭션이 일어나면 커밋전에 파일에 남김
서버 crash에도 로그 파일 보존됨
(슬레이브에는 설정하지 말것)

innoDB의 경우
innodb_flush_logs_at_trx_commit=1 # Flush every log write
innodb_support_xa=1 # MySQL 5.0 and newer only

바이너리 로그의 이름을 모든 디비가 같게 설정
log_bin=/var/lib/mysql/mysql-bin
슬레이브
relay_log=/path/to/logs/relay-bin
skip_slave_start
read_only

skip_slave_start 슬레이브가 crash 후에 자동 시작 되는걸 막음
read_only
슈퍼 유저및 레프리카는 쓸수 있음

sync_master_info = 1    # 5.5이상
sync_relay_log = 1 # 5.5이상
sync_relay_log_info = 1 # 5.5이상

만약 마스터랑 너무 차이가 나게 되면 로그 파일이 디스크 용량을 넘어갈수 있음
binlog는 크기 제한 가능함

아래 옵션을 설정하면 한계가 되면 멈추고 디비에 적용 후 지우고 다시 받음
*버그때문에 쓰지 말것
relay_log_space_limit


innoDB테이블 쓸것
myisam의 경우 레플이 crash 될경우 데이터 정합성에 문제 생김


레플리케이션 상세
statement-based replication(logical replication)
마스터에 적용되는 쿼리문을 저장

장점
쉽게 구현가능(복사 자체)
바이너리 로그가 적음(네트워크 트래픽도적음)
*스키마의 데이터 타입이 달라고 복제 가능
슬레이브를 마스터로 상승 할경우 더빠름


단점
*만약 스토어 프로시저를 쓸경우 statment-base 사용말것

CURRENT_USER()등의 특정 함수 복제 불가
store routine, trigger 등에 문제
*NOW()등은 timestamp 로 변경함
가장큰 문제점은
serializable 되서 실행되야 해서
락이 많이 걸림

row-based replication
(5.1이상)
실제로 변경된 데이터를 바이너리 로그에 저장

장점
모든 문장이 정확이 복사가능(쿼리에 따라 빠를수도 있음)
ex)
INSERT INTO summary_table(col1, col2, sum_col3)
-> SELECT col1, col2, sum(col3)
-> FROM enormous_table
-> GROUP BY col1, col2
서버 크래쉬시 복구가 쉬움
쿼리를 파싱하지 않기때문에 cpu 를 상대적으로 덜사용
에러가 날경우(마스터에는 존재 하나 슬레이브에 존재하지 않는 쿼리 업데이트)
바로 정지해서 데이터 정합성 유지하기가 좋음
slave_exec_mode 로 정지하지 않고 지속되게 할수있음

단점
로그를 보고 어떤 쿼리가 실행 되었는지 알기 힘듬
바이너리 로그가 커질수 있음(statment 와 비교)
ex)
UPDATE enormous_table SET col1 = 0;
문제가 생기면 대처하기 매우 힘듬(다큐먼트가 거의 없음)

mysql은 default 로 statment base 를 사용하나 안전하지
않다고 생각하면 row based 로 바꿔서 사용함
*세션당 binlog_format 을 변경함으로 레플리케이션 설정가능

레플리케이션 관련 파일 설명
데이터 디렉토리 또는 서버 디렉토리(버전 마다 다름)
ex) /var/run/mysqld

mysql-bin.index
바이너리 로그와 이름은 같음
바이너리 로그가 하드디스크에 어떻게 기록되어있는지 저장
mysql-realy-bin.index
슬레이브에서 위와 동일하게 동작
master.info
레플리카가 마스터에 접속하기 위한 정보
*text로 되어있음으로 보안상 루트만 보개 해야함

realy-log.info
릴레이로그를 어디까지 재생했는지에 대한 info

설정
expire_logs_days 로 로깅을 얼마나 저장할지 선택가능
설정안하면 디스크 다 채우는 수가 있음 꼭 설정할것

레플리카를 마스터로 사용하기
레플리카의 log_slave_updates 기능을 사용하여
슬레이브를 다른 슬레이브의 마스터로 사용가능

*server a unique server ID 신경 쓰지 않으면 제대로 동작안함
@@server_id 로확인가능

왜 재대로 동작안하는가?
SQL thread reads the relay log, it discards
any event whose server ID matches its own.

레플리케이션 filters
왠만하면 사용말자 뻑하면 레플께짐
P466 10-3 그림 확인

마스터 설정
binlog_do_db and binlog_ignore_db.
절대 설정하지 말것
만약 사용한다면
USE test;
mysql> DELETE FROM sakila.film;
아래 사용할경우 걍 테이블 명으로만 필터링함


레플 설정
replicate_*
테이블에 like 문 걸수 있음

특정 쿼리가 실행 안되게도 할수있음
SET SQL_LOG_BIN=0,

레플리케이션 Topologies
mysql replication rule
1.슬레이브는 하나의 마스터만 가직수 있다
2.모든 슬레이브는 각각의 unique server id 를 가져야한다.
3.마스터는 여러 슬레이브를 가질수있다
4.슬레이브는 다른 슬레이브의 마스터가 될수있다

1.Master and Multiple replications
장점
쓰기가 적고
읽기가 만을때

전략
1.레플리카 마다 다른역활을 정해라
다른 인덱스를 걸고
다른 스토리지 엔진을 사용해라
2.레플리카 1대를 stand by 서버로 활용해라
3.레플리카 1대를 다른 데이터서버에 넣어라
재난복구
4.레플리카 1대 에 time delay 를 걸어 백업용으로 사용
5.레플리카 1대를 백업 또는 개발용 으로 사용해라

2.master-master in active-active mode
서로에게 마스터및 슬레이브 설정이 되어있음

문제
1.데이터가양쪽에어 업데이트 될때 가장 문제
ex)
서버1
mysql> UPDATE tbl SET col=col + 1;
서버2
mysql> UPDATE tbl SET col=col * 2;

데이터도 다르지만 문제는 에러도 안남
2.acive-active 모드에서 한쪽이 죽어버리고 어플리케이션에서 양쪽에 쓴다면...


autoincrement 는 아래 설정으로 충돌대비가능
한쪽은 홀수 한쪽은 짝수 사용
auto_increment_increment
auto_increment_offset

3.master-slave in active-passive mode
마스터 마스터 모드에서
한쪽으로 쓰고 한쪽은 오직 읽기만 가능

한쪽이 죽어버리면 바로 복구됨

좋을 경우
1.스키마를 변경하는대 오래 걸릴경우
active 쪽에서 stop the replication threads
엑티브 로그가 passive에 적용안됨
passive 모드에서 스키마 변경

스키마 변경 완료되면

active->passive
passive->active로

acive는 변경 완료 되었으며 그동안의 로깅을 따라간다.
passive는 오래 걸려도 live 쿼리가 들어오지 않기 때문에 빠르다

master-master 할때 반드시 확인 해야할 사항들
1. Ensure that the servers have exactly the same data.
2. Enable binary logging, choose unique server IDs, and add replication accounts.
3. Enable logging replica updates. This is crucial for failover and failback, as we’ll see
later.
4. Optionally configure the passive server to be read-only to prevent changes that
might conflict with changes on the active server.
5. Start each server’s MySQL instance.
6. Configure each server as a replica of the other, beginning with the newly created
binary log.


만약 log_slave_updates 를 킬경우
1.엑티브에서 이벤트 발생
2.인엑티스가 복사후 실행
3.인엑티스 서버의 log_slvae_duptate 설정때문에
binary_log에 변경사항 넘김
4.엑티브가 데이터를 읽어감
하나 적용할때 자기와 동일한 serverid 기 때문에 제외함

ring 형식
링으로 만들어 쓸수있으나
한대 죽으면 다죽음
물런 백업replication 각각 한대더 넣으면 조금더 좋아지긴함

master, distribution masdter and replicas
마스터에 어느 정도 이상의 replication 이 걸릴 경우 부담이 될수 있음으로
레플리케이션을 마스터로 만듬

데이터가 매우 많을 경우에 사용하는 전략

커스텀 topology

하나의 마스터에서 데이터를 쪼개서 각각의 데이터를 들고 있게 꾸미는 방법
데이터 베이스 단위로 설정가능
레플리카에
replicate_wild_do_table = sales.%
처럼 설정하면 sales 디비만 복사함