BBUWOO'S [ LIKE UNIX ] WORLD Home > Lecture > Mysql > Mysql-1  

HOME
WHAT's BBUWOO?
LInux AnNyung
Open Source
    GitHUB
    GitHUB (for PHP)
LECTURE
MINI LECTURE
QnA BOARD
ENGLISH POEM


WARNNING

강좌의 모든 권리는 본인 김정균에게 있으며 이 강좌를 상업적 목적 으로 이용
하거나 다른 곳으로 옮길시에는 본인의 허락이 있어야 한다. 이글의 가장 최신글은
http://oops.org 에서 확인할수 있다.



MySQL Replication

아 드디어 내 홈에서 DB 에 관한 부분을 다루게 되었다. 하지만 DB 에 관한 설치 및 튜닝에 대
해서는 논하지는 않는다. 왜냐면 필자는  DB쪽에 지식이 별로 없기 때문이다. 만약 설치 및 튜
닝쪽에 관심이 있다면 http://database.sarang.net 으로 문의하기 바란다. 필자에게 질문을 하
더라도 답변 듣기 힘들테니까..

잡설은 그만두고 그럼 여기서는 우선 MySQL 의 3.23부터 지원이 되는 Replication 기능에 대해
서 논하고자 한다. Load Ballance 등의 장비나 또는 software 적인 방법을 통해 서버를 여러대
운영하다 보면 동기화 문제가 발생하게 된다. Replication 기능은 바로 이것처럼 DB server 를
여러대로 구동을 할때 각 DB서버의 동기화를 지원하기위한 기능으로 사용을 할 수가 있다. 즉,
입력 서버와 출력 서버를 분리해서 운영을 할 수가 있는 것이다.

일단 설정을 논하기 전에 주의 할 것은 MySQL 의 Replication 기능은 3.23버젼 부터 지원을 하
며 현재 MySQL 의 Replication 기능은 테스트 버젼 정도라고 인식을 하고 도입여부를 결정해야
한다는 점이다.





Replication 에서는 Master 와 Slave 라는 말을 사용하게 된다. Master 라는 말은 즉 능동적인
작업을 수행하는 측을 의미한다.  즉 실제로 업데이트가 발생하고, 동기화를 할 서버의 기준이
되는 서버를 의미한다.

일단, Replication 기능을 사용하기 위해서는 Replication 의 기능을 수행 할 유저가 필요하며
이 유저는 모든 DB 에 대해서 file 의 권한을 가지고 있어야 한다.

GRANT file ON *.* TO $repjob_user@'$slave_host_addr' IDENTIFIED BY '$passwd'

명령을 이용하여 file 에 대해서만 모든 DB 에 권한을 가지는 유저를 추가하도록 한다. 여기서
$repjob_user 는 중복되지 않는 유일한 아무 이름의 유저로 지정하면 되며,  $salve_host.addr
은 SLAVE server 로 만들 서버의 주소를 적어 줘야 한다. 그래야 SLAVE 에서 위에서 지정한 유
저로 MASTER server 에 접속이 가능하기 때문이다. 마지막의 $passwd 는 접속할 패스워드를 지
정하는 것이다.

다음 my.cnf 에 아래와 같이 Replication 기능을 위한 MASTER 설정을 한다.

Hanterm - cat /etc/my.cnf

 [root@bbuwoo /etc]$ cat my.cnf

  [mysqld]
  ....
  ....
  log-bin
  binlog-do-db    = test
  binlog-do-db    = test1
  server-id       = 1

 [root@bbuwoo /etc]$

log-bin 은 Replication 을 위한 binary log 를 남기게 한다.  server-id 는 Replication 기능
을 사용하는 서버중 유일값을 가져야 한다. server-id 는 1 에서 2^32-1 까지 지정할 수 있다.

binlog-do-db 는 Replication 을 사용할 database 를 지정한다. binlog-do-db = test,test1 과
같이는 사용이 안된다. 이유는 모르겠지만 하나에 하나씩 적어 줘야 한다. 만약 모든 database
를 동기화 하려한다면 binlog-do-db 를 설정을 안하면 된다. 만약 mysql DB 만 Replication 기
능을 사용하고 싶지 않다면 binlog-ignore-db 를 사용하면 된다.

my.cnf 에서 사용할 수 있는 MASTER 에 관한 옵션은 다음과 같다

log-bin=filename

Replication 기능에 필요한 binary log 를 남기게 한다.  filename 을 지정하지 않을 경우에는
mysql 의 lib directory 에 $host-bin.001 과 같이 남게 된다.  RPM으로 설치했을 경우에는 보
통 /var/lib/rpm 에 남게되며, prefix 를 지정하지 않은 채 소스 컴파일을 했을 경우에는 보통
/usr/local/mysql/lib/ 에 남게 된다.

log-bin-index=filename

binary file 의 index 파일을 생성한다. 지정하지 않으면 $host-bin.index 로 남게 된다. 지정
하나 하지 않으나 별 상관은 없다.

sql-bin-update-same

If set, setting SQL_LOG_BIN to a value will automatically set SQL_LOG_UPDATE to the same
value and vice versa. 

binlog-do-db=database_name

MASTER 의 여러 DB 중 Replication 기능으로 동기화를 할 Database를 선택한다. 이것이 지정이
되어 있으면 지정되지 않은 Database 들은 동기화에서 빠진다.

binlog-ignore-db=database_name

MASTER 의 여러 DB 중 Replication 기능으로 동기화를 하지 않을  Database 를 선택한다. 이것
이 지정이 되어 있으면 지정되지 않은 Database 들만 동기화를 한다. 만약 binlog-do-db 가 설
정이 되어 있을 경우 에는 binlog-do-db 를 먼저 적용하고나서 binlog-ignore-db 를 적용한다.

좀 더 자세한것을 알고 싶다면 http://www.mysql.com/doc/R/e/Replication_Options.html 를 참
고 하도록 한다.




SLAVE 측의 설정에서는 별다른 유저 추가가 필요 없으며 MASTER 측의 추가한 유저 정보를 이용
하여 my.cnf 에서 SLAVE 설정만 해 주는 것으로 설정이 끝난다.

Hanterm - cat /etc/my.cnf

 [root@bbuwoo /etc]$ cat my.cnf

  [mysqld]
  ....
  ....
  server-id       = 2
  master-host     = mater_ipaddres
  master-user     = $repjob_user
  master-password = $passwd
  replicate-do-db = test
  master-port     = 3306

 [root@bbuwoo /etc]$

server-id 는 역시 유일값 이어야 한다. MASTER 에서 1 을 사용했으니 SLAVE 에서는 2 를 사용
한다.

master-host 는 MASTER server 의 ip address 를 지정해 준다. master-user 는 Replication 작
업을 할 유저를 지정한다. 위의 MASTER 에서 등록해 준 유저를 적도록 한다.

master-passwd 는 Replication 작업을 할 유저의 패스워드를 지정한다.

master-port 는 MASTER server 가 사용하는 포트를 지정한다. 기본값으로 3306 이다.

만약 MASTER server 의 특정 DB만 Replication 기능을 사용하고 싶다면 replicate-do-db 를 이
용한다.  하지만 이 기능은 MASTER 에서 binlog-ignore-db 로 제한을 하고 있다면 적용이 되지
않는다. 즉 SLAVE level 에서는 MASTER 가 허락 하는 database 중에서 선택을 할 수 있을 뿐이
다. SLAVE 에서 사용할 수 있는 옵션들은

http://www.mysql.com/doc/R/e/Replication_Options.html

를 참고 하도록 한다.

위의 작업을 간단히 설명을 하자면 MASTER 에서는 Replication 을 위한 유저에게 file 에 대해
서는 모든 권한을 준 상태로 추가 했으며, test, test1 database 에 대해서 Replication 을 하
도록 설정을 한 것이다.  SLAVE 에서는 replicate-do-db 가 설정이 되어 있으므로 test1 DB 만
동기화를 하게 설정한 것이다.




MASTER 와 SLAVE 의 설정을 마쳤으면 Replication 기능을 사용하기 전에 두대간의 동기화 작업
을 먼저 해 놓아야 한다. 먼저 동기화 할 database 를 SLAVE 로 옮긴다. (만약 MASTER 에서 아
무것도 없는 상태에서 시작한다면 이 작업은 필요없다. MASTER에서 운영중인 것을 Replication
기능을 이용하여 동기화 하기 위해 필요한 작업이다.)  위에서는 test1 DB 만 동기화를 하도록
설정을 했으니 MASTER 의 test1 DB를 압축해서 SLAVE 로 옮긴다 (mysql 의 경우에는 data file
만 옮겨도 그냥 적용을 할 수 있다.)

master) cd /var/lib/mysql
master) tar cvfpz test1.tgz test1
master) chmod 777 test1.tgz

slave) cd /var/lib/mysql
slave) ncftp -u user master_server
slave) (Afer login) cd /var/lib/mysql
slave) get test1.tgz
slave) delete test1.tgz (ftp 상의 파일을 삭제)
slave) quit (ftp logout)
slave) tar xvfpz test1.tgz
slave) chown -R mysql.mysql test1




여기 까지의 작업이 완료 되었다면 이제 MASTER 와 SLAVE 의 mysql 을 구동하고 다음을 확인한
다. 여기서의 결과값은 3.23.42 를 기준으로 한다. 버젼 마다 결과값이 다른 형태로 나올 수가
있다.


MASTER Server
Hanterm - mysql -e "show process"

 [root@bbuwoo /etc]$ /etc/rc.d/init.d/mysql restart

  Shutting down MySQL:                                       [  OK  ]
  Starting MySQL:                                            [  OK  ]

 [root@bbuwoo /etc]$ mysql -uroot -p -e "show processlist"

  +----+-------+--------+------+-------------+------+
  | Id | User  | Host   | db   | Command     | Time |
  +----+-------+--------+------+-------------+------+
  |  7 | $user | $slave | NULL | Binlog Dump | 2865 |
  +----+-------+--------+------+-------------+------+
  +---------------------------------------------+------+ 
  | State                                       | Info | 
  +---------------------------------------------+------+ 
  | Slave connection: waiting for binlog update | NULL | 
  +---------------------------------------------+------+ 

 [root@bbuwoo /etc]$ mysql -uroot -p -e "show master status"

  +---------------+----------+------------------+------------------+
  | File          | Position | Binlog_do_db     | Binlog_ignore_db |
  +---------------+----------+------------------+------------------+
  | $host-bin.001 | 729      | test,test1       |                  |
  +---------------+----------+------------------+------------------+

 [root@bbuwoo /etc]$


SLAVE Server
Hanterm - mysql -e "show process"

 [root@bbuwoo /etc]$ /etc/rc.d/init.d/mysql restart

  Shutting down MySQL:                                       [  OK  ]
  Starting MySQL:                                            [  OK  ]

 [root@bbuwoo /etc]$ mysql -uroot -p -e "show processlist"

  +----+-------------+------+------+---------+------+-----------------------+------+
  | Id | User        | Host | db   | Command | Time | State                 | Info |
  +----+-------------+------+------+---------+------+-----------------------+------+
  |  1 | system user | none | NULL | Connect | 2847 | Reading master update | NULL |
  +----+-------------+------+------+---------+------+-----------------------+------+

 [root@bbuwoo /etc]$ mysql -uroot -p -e "show slave status"

  +-------------+-------------+-------------+---------------+---------------+-----+
  | Master_Host | Master_User | Master_Port | Connect_retry | Log_File      | Pos |
  +-------------+-------------+-------------+---------------+---------------+-----+
  | $master_ip  | $rejob_user | 3306        | 60            | $host-bin.001 | 729 |
  +-------------+-------------+-------------+---------------+---------------+-----+
  +---------------+-----------------+---------------------+------------+
  | Slave_Running | Replicate_do_db | Replicate_ignore_db | Last_errno |
  +---------------+-----------------+---------------------+------------+
  | Yes           | test            |                     | 0          |
  +---------------+-----------------+---------------------+------------+
  +------------+--------------+
  | Last_error | Skip_counter |
  +------------+--------------+
  |            | 0            |
  +------------+--------------+

 [root@bbuwoo /etc]$

와 같이 나와 있음을 확인하면 된다.




Replication 이 잘 되다가 갑자기 slave 에서 master 가 반영이 되어 있지 않을 경우 slave 의
error log 를 보도록 한다. error log 를 보고 문제점을 fix 한 다음

shell> mysqladmin -uroot -p slave-start

명령을 실행하면 반영되지 않았던 master 의 자료가 하나씩 반영되는 것을 볼 수 있을 것이다.

또 한가지 주의할 점은 replication 을 구현할때 master 에서 

mysql> create database DB명;

명령은 slave 에 반영이 되지를 않는다. 그러므로 slave 의 설정에

replicate-do-db = DB명

을 명확하게 밝혀 놓아야지 에러가 발생하는 것을 막을 수 있다. 그럼 Master 에서 DB 를 추가
할 때는 귀찮더라도 slave 에서 수동으로 create database 를 한 다음 추가된 db 를 my.cnf 에
서 replicate-do-db 를 설정한 다음 slave 를 재시작 하는 것을 권장한다.

database 추가가 반영이 되지 않는 것은 필자가 그 방법을 찾지 못한 것인지 아니면 원래 구현
이 안되어 있는 것인지를 모르겠다. 혹시 아는 사람이 있으면 필자에게 포스팅을 해 주면 감사
하겠다.




  mysql> show processlist;

  +----+-------------+------+------+---------+------+-----------------------+------+
  | Id | User        | Host | db   | Command | Time | State                 | Info |
  +----+-------------+------+------+---------+------+-----------------------+------+
  |  1 | system user | none | NULL | Connect | 2847 | Waiting to reconnect  | NULL |
  |    |             |      |      |         |      | after a failed read   |      |
  +----+-------------+------+------+---------+------+-----------------------+------+
  2 rows in set (0.00 sec)

  mysql> show slave status;
  +-------------+-------------+-------------+---------------+---------------+-----+
  | Master_Host | Master_User | Master_Port | Connect_retry | Log_File      | Pos |
  +-------------+-------------+-------------+---------------+---------------+-----+
  | $master_ip  | $rejob_user | 3306        | 60            | $host-bin.101 | 729 |
  +-------------+-------------+-------------+---------------+---------------+-----+
  +---------------+-----------------+---------------------+------------+
  | Slave_Running | Replicate_do_db | Replicate_ignore_db | Last_errno |
  +---------------+-----------------+---------------------+------------+
  | Yes           | test            |                     | 0          |
  +---------------+-----------------+---------------------+------------+
  +------------+--------------+
  | Last_error | Skip_counter |
  +------------+--------------+
  |            | 0            |
  +------------+--------------+

이 경우를 보도록 하자.  processlist 에서는 읽기 실패후에 재접속을 기다리고 있다고 상황을
출력하고 있고, slave status 에서는 host-bin.101 에서 멈춰있다. 그리고 master 에서는 로그
파일이 host-bin.130 번을 생성하고 있을 경우이다. 즉 로그 101 에서 slave 는 멈춰진 상태이
다. 그리고 slave 의 에러로그 파일에는 다음과 같은 내용이 있다.

020312 17:52:37  Error reading packet from server: Could not open log file
                 (read_errno 0,server_errno=13)
020312 17:53:37  Slave: Failed reading log event, reconnecting to retry, log
                        '$host-bin.101' position 729
020312 17:53:37  Slave: reconnected to master '$rejob_user@$master_ip:3306',
                        replication resumed in log '$host-bin.101' at position 729

이런 경우에는, master 의 바이너리 로그 파일의 소유권을 잘 살펴보기 바란다. 보통 mysql 은
mysql 유저로서 구동을 하는 경우가 많은데 이때 로그파일이 간혹 root 의 권한으로 생성이 되
는 경우가 있다. 이 경우 읽기 권한이 없어 위와 같은 에러가 발생하는 경우가 존재한다.


>> 다음 : Forgotten MySQL Password



    



 Home > Lecture > Mysql > Mysql-1

Copyright 1997-2017 JoungKyun Kim 
LAST MODIFIED: 2017/01/18