본문 바로가기

DB/MySQL

MySQL Replication

1. Rsync

1-1. 버전 정보 확인

[irteamsu@new_server ~]$ rpm -qa | grep rsync
rsync-3.0.6-12.el6.x86_64

[irteamsu@new_server ~]$ rpm -qa | grep xinetd
xinetd-2.3.14-40.el6.x86_64

 

1-2. 환경설정 및 재시작

[irteamsu@new_server ~]$ sudo cat /etc/xinetd.d/rsync

# default: off
# description: The rsync server is a good addition to an ftp server, as it \
#       allows crc checksumming etc.
service rsync
{
        disable = no
        flags           = IPv6
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/bin/rsync
        server_args     = --daemon
        log_on_failure  += USERID
}



[irteamsu@new_server ~]$ sudo vi /etc/rsyncd.conf

...

[dump_transfer_from_old]
path=/home1/irteam
uid=irteam
gid=irteam
use chroot=yes
read only=no
hosts allow=구서버IP
hosts deny=*
log file = /var/log/rsync/rsync_transfer_from_old.log



[irteamsu@new_server ~]$ sudo /etc/init.d/xinetd restart

 

1-3. 스크립트 파일 복사

1) rsync 옵션 (Ref. http://gyus.me/?p=214)

  • -r | –recursive : 재귀적으로 디렉토리를 카피함. 해당 옵션을 지정하지 않으면, rsync명령어로는 디렉토리를 동기화 하지 않음.
  • -a | –archive : 아카이브 모드로 실행함.
  • [-rlptgoD]옵션을 지정하면 같은 동작을 하나, 해당 옵션 하나로 대부분의 디렉토리, 파일의 정보를 유지하며 동기화가 가능하므로 편리함.
  • -z | –compress 동기파일을 압축함.
[irteamsu@old_server irteam]$ rsync -razv --progress /home1/irteam/scripts/* 신규서버IP::dump_transfer_from_old/scripts

 

2. DB 데이터 이관

2-1. DB 확인

  • <중요!!> 데이터 백업 전, master position 정보를 미리 꼭 확인 한다.
[irteam@old_server ~]$ /home1/irteam/db/mysql/bin/mysql -u '계정ID' -p'비밀번호' -S /home1/irteam/db/mysql/tmp/mysql.sock

...

mysql> show master status\G;
*************************** 1. row ***************************
             File: mysql-bin.000018
         Position: 49843
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)

ERROR:
No query specified

 

2-2. 데이터 이관 

1) 데이터 백업 (ref : http://intomysql.blogspot.kr/2010/12/mysqldump.html)

  • --single-transaction :
    • dump를 하나의 트랜잭션을 이용해서 실행함 (InnoDB 스토리지 엔진을 사용하는 테이블에 대해서는 Lock없이 일관된 덤프를 받을 수 있음). 자세한 내용은 아래 "일관된 데이터 덤프 받기” 참조
  • --quick :
    • 일반적으로 mysqldump는 테이블의 데이터들을 모두 Client의 메모리에 모두 로딩한 후, 파일에 쓰기를 시작하게 되는데, 이 옵션이 활성화되면 Client의 메모리에 버퍼링하지 않고 바로 파일로 쓰거나 화면으로 출력하게 된다. 이 옵션은 opt 옵션에 포함되어서 자동으로 활성화되기 때문에, (큰 테이블이 있는 경우) skip-opt를 사용하는 경우에는 quick 옵션을 별도로 명시해줘야 한다.
  • --routines :
    • 덤프시에 스토어드 프로시져와 함수를 출력하도록 한다.
  • --master-data
    • 이 옵션이 명시되면, dump 파일의 헤더 부분에 CHANGE MASTER TO 구문을 포함시키며, 이 구문에는 덤프 시작 시점의 Binary log 파일명과 위치 정보 및 호스트 정보를 포함하고 있다. 이 값을 1로 설정하면 CHANGE MASTER TO 구문이 실제 실행 가능한 형태로 포함되며, 2로 설정되면 SQL 코멘트 형태로 참조만 할 수 있도록 포함된다. 가끔 Binary log가 활성화되지 않은 서버에서 실행 시 에러를 유발하기도 하므로 반드시 먼저 테스트를 해볼 것을 권장한다.
  • --all-databases :
    • 이 옵션을 명시하면 현재 서버의 모든 데이터베이스를 덤프하게 된다. 이 옵션으로 덤프를 받게 되면 기본적으로 "USE <데이터베이스명>;" 명령이 덤프 내용에 포함된다.
# replication을 위해 옵션 추가하여 전체 데이터 백업
[irteam@old_server ~]$ /home1/irteam/db/mysql/bin/mysqldump -u'계정ID' -p'비밀번호' --single-transaction -Q -R --master-data=2 --all-databases -S /home1/irteam/db/mysql/tmp/mysql.sock > /home1/irteam/db_backup_20170623/alpha_db_backup.sql

 

2) 백업 데이터 확인 (replication 정보)

[irteam@old_server ~]$ head -n 30 /home1/irteam/db_backup_20170623/alpha_db_backup.sql

...

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000018', MASTER_LOG_POS=49843;

...

 

3) 백업 파일 Rsync로 전송

[irteam@old_server ~]$ rsync -razv --progress /home1/irteam/db_backup_20170623/* 신규서버IP::dump_transfer_from_old/db_backup_20170623

 

4) 백업 데이터 Import

[irteam@new_server ~]$ /home1/irteam/db/mysql/bin/mysql -u'계정ID' -p'비밀번호' -S /home1/irteam/db/mysql/tmp/mysql.sock < /home1/irteam/db_backup_20170623/alpha_db_backup.sql

 

2-3. 데이터 확인

  • <중요!!> 신 장비 mysql 로그인 시 계정 정보가 아직 flush 안 된 상태이므로… 이전의 계정 정보로 로그인 해야 한다.
[irteam@new_server ~]$ /home1/irteam/db/mysql/bin/mysql -u'계정ID' -p'비밀번호' -S /home1/irteam/db/mysql/tmp/mysql.sock

...

mysql> flush privileges;

mysql> quit

 

3. DB Replication

3-1. repl 유저 확인

  • 없으면 유저 생성해야 함.
  • 현재는 repl@%로 생성하지만… repl@SlaveIP 이렇게 slave로 허락된 장비만 접근 가능하게 만드는 것이 좋다!!!
mysql> use mysql;

mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'%' IDENTIFIED BY '비밀번호';

mysql> flush privileges;

mysql> select user from user where user = 'repl';
+------+
| user |
+------+
| repl |
+------+
1 row in set (0.00 sec)

 

3-2. Slave 설정

  • 현재 마스터 DB 상태가 변하더라도… 백업 파일에 기록된 그 포지션으로 설정한다.
  • 포지션을 현 상태로 바꾸면… 그 사이는 누락된 채 진행되며… 누락된 곳에 테이블 Create가 있다면.. 에러 발생하며 멈추가 된다.
mysql> reset slave;
Query OK, 0 rows affected (0.02 sec)

# 마스터 DB 로그파일 mysql-bin.000018에서 49843 위치부터 시작하여 복제하겠다.
mysql> CHANGE MASTER TO MASTER_HOST='구서버IP', MASTER_USER='repl', MASTER_PASSWORD='비밀번호', MASTER_LOG_FILE='mysql-bin.000018', MASTER_LOG_POS=49843;

mysql> start slave;

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Connecting to master
                  Master_Host: 구서버IP
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000018
          Read_Master_Log_Pos: 49843
               Relay_Log_File: relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000018
             Slave_IO_Running: Connecting
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 49843
              Relay_Log_Space: 120
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 2003
                Last_IO_Error: error connecting to master 'repl@구서버IP:3306' - retry-time: 60  retries: 1
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 0
                  Master_UUID:
             Master_Info_File: /home1/irteam/db/mysql/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp: 170623 17:44:59
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
1 row in set (0.00 sec)

ERROR:
No query specified

 

3-3. Slave read_only 설정

  • <중요!!!> 다른 곳에서 접근해서 데이터를 넣을 수 있으므로… 꼭 read_only 값을 on 으로 변경해야 한다.
mysql> show variables like 'read_only%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only     | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

mysql> set global read_only='ON';
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'read_only%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only     | ON    |
+---------------+-------+
1 row in set (0.00 sec)