본문 바로가기
㏈ª By β┖υΕJini/MY-SQL

MY-SQL 복제 방법과 문제 해결 방법을 알아 보자.

by ㏈ª ☞ β┖υΕJini.κR 2008. 12. 12.

사용자 삽입 이미지
금일 MY-SQL DB 의 문제점이 파악 되었다.

통계 데이터를 보는데 이상하게 데이터가 누락 된것... 현재 복제로 구성되어 있는 시스템이기 때문에

Master 과 Slave 의 데이터를 비교해본 결과 복제가 끊어 졌구나... 그래서 복제에 관한 자료와

어떻게 복구 하는지에 대해서 정리해 보았다.


게시자(Master)는 실제로 디비에 내용이 기록되는 게시자이고 , (구독자)Slave는 게시자의 바이너리 로그를 사용해서 해당 디비를 갱신하게 된다.

먼저 게시자에 설치된 mysql의 디렉으로 가서 ./share/mysql로 이동

1. -rw-r--r-- 1 root root 2538 Sep 11 14:47 my-huge.cnf (1G-2G)
2. -rw-r--r-- 1 root root 2516 Sep 11 14:47 my-large.cnf  (512M)
3. -rw-r--r-- 1 root root 2500 Sep 11 14:47 my-medium.cnf (64~256M)
4. -rw-r--r-- 1 root root 2215 Sep 11 14:47 my-small.cnf  (< 64M)

위 파일들 중에서  3번째 파일을 사용 해 보도록 하자.

가정 : 게시자 MYSQL 데몬이 START 상태

cp ./my-medium.cnf /etc/my.cnf 복사

vi /etc/my.cnf해서 열어서 [mysqld]

# vi /etc/my.cnf# Example mysql config file for medium systems.

# This is for a system with little memory (32M - 64M) where MySQL plays

# a important part and systems up to 128M very MySQL is used together with

# other programs (like a web server)

# The following options will be passed to all MySQL clients 

:
:
 The MySQL server

[mysqld]
port = 3306
socket = /tmp/mysql.sock
skip-locking
set-variable = key_buffer=16M
set-variable = max_allowed_packet=1M
set-variable = table_cache=64
set-variable = sort_buffer=512K
set-variable = net_buffer_length=8K
set-variable = myisam_sort_buffer_size=8M
log-bin = /usr/local/mysql/logs/replication.log <--바이너리 로그파일  기록될 경로
binlog-do-db = replTEST1<---(DATABASE NAME) <-- 실시간 백업할 디비
binlog-do-db = replTEST2<---(DATABASE NAME)  <-- 실시간 백업할 디비
server-id = 1 <---복제 통신할 서버ID (1 ~ 8388607까지 가능)


우선 게시자(MASTER) 세팅은 이것으로 끝났다.

그럼 구독자(SLAVE) 를 세팅해 보도록 하자.

게시자와 같은 파일을 열어서

[mysqld]
master-host = 192.168.1.100 <-- 게시자 서버 아이피
master-user = mysql  master 의 최상위 권한 유저
master-password = 비밀번호 
master-port = 3306  <-- 현재 MY-SQL 포트
master-connect-retry = 60  게시자 재접속할 횟수
replicate-do-db= replTEST1 <-- 복제할 DATABASE 명
replicate-ignore-table=replTEST1.replTestTableNot
--> 특정 테이블 복제를 걸지 않고 싶을때 사용
replicate-do-db= replTEST1
server-id = 2


이것으로 MYSQL 기본적인 복제 세팅은 끝이 나게 된다.

그리고

1.master MYSQL 데몬 재시작
2.slave   MYSQL 데몬 재시작
3.master 데이터 입력해본다.
4.slave 데이터가 정상적으로 들어 오는지 확인 한다.

복제에는 별 문제 없을것으로 보인다.

복제 문제 해결 방법

하지만 여기서 MY-SQL 의 단점인지 원래 그런건지 문제점이 있으니 주의 하기 바란다.

예를 들어 보자 .. 게시자 서버의  복제 걸린 테이블의 데이터를 변경 하는데 복제가 걸려 있지 않은 테이블의 데이터를 가지고 쿼리를 날려서 데이터를 업데이터 하게 되면 복제가 끊기게 된다.
ex) use replTEST1;
     delete from BLUEJINI.TEST01; 이런 구문을 실행해 본다고 하자.

   
이건 MYSQL  BINLOG  특성 때문 인듯 하다. 예외로 지정 하면 되겠지만 그렇지 않고 하게 되면

분명히 복제가 끊기게  된다.

구독자 DB 에서

mysql> show slave status;
명령어를 실행 하게 되면 만약 복제가 끊겼다면 Error LOG 가 기록 되고
Slave_SQL_Running No 상태로 변해 있을 것이며 Seconds_Behind_Master 의 경우는
숫자가 변하지 않고 계속 그대로 일 것이다.

이경우는 게시자 DB 의 경우에서는 BLUEJINI.TEST01 테이블을 찾을수 있지만.. 구독자에서는
찾을수 없어 행이 걸리게 된다. 이런 경우 어떻게 처리 해야 할까.

간단하게 이런 쿼리는 SKIP 시키면 된다.

mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)

mysql> set global sql_slave_skip_counter=1;
Query OK, 0 rows affected (0.00 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status;

이렇게 해보면 SKIP 이 되고 동작하는지 하지 않는지 알수 있을 것이다.

이런 에러가 발생하는 몇개이 쿼리가 있다면... 위 명령문의 반복을 통해
복제를 다시 활성화 시킬수 있을 것이다.  단 slave 와 동기화에 문제가 있을수 있으니
master 에 실행한 쿼리를 slave 실행을 톨해 동기화 시키도록 하자.

그리고 만약 락이 걸렸을때 로그를 통해 어디서 락이 걸렸는지 확인 할때는

mysqllog # tail -50 slow-query.logs 확인이 가능 하다.