방랑로그

[mysql] replication2 본문

IT개발/DBMS

[mysql] replication2

야키다 2017. 12. 15. 16:13

[mysql] replication2 



원본: http://oops.org/?t=lecture&sb=mysql&n=1 안녕리룩스 배포자 김정균님 홈페이지






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 의 권한으로 생성이 되

는 경우가 있다. 이 경우 읽기 권한이 없어 위와 같은 에러가 발생하는 경우가 존재한다.


'IT개발 > DBMS' 카테고리의 다른 글

[mssql] 실행계획  (0) 2017.12.15
[mysql] Explain  (0) 2017.12.15
[oracle] simple 부분범위처리  (0) 2017.12.15
[sql,oracle,informix] sql비교  (0) 2017.12.15
[mysql] replication1  (0) 2017.12.15
Comments