MySQL 5.5 Configure Replication using Ibbackup
from
1. Ibbackup 을 이용한 Replication 구성
Ibbackup 은 hot backup 이 가능하다. (http://h391106.tistory.com/220) Hot Backup 이라 함은 Service 정지 없이 백업본을 만들 수 있다는 이야기다.
Replication 구성의 간단한 예는 http://h391106.tistory.com/224 에서도 이야기했다.
이중 핵심적인 부분으로는 Server-id 에 대한 셋팅 부분이다. Replication 을 구성하는 장비는 각기 고유한 Server-id 를 가져야 하는데 이를 정의하지 않는 경우 Default 값을 가져간다. 다시말해 Server-id 가 충돌하는 상황이 생긴다.
Server-id 의 Setting 은 my.cnf 에 정의하며 해당 variable 은 Dynamic 하게 변경할 수 없다. 다시 말해 Service 의 Restart 가 필요하다는 의미이며 이는 서비스 다운타임이 생긴다는 이야기이다.
거꾸로 Server-id 가 사전에 정의되어 있으면 이러한 다운타임 없이 Replication 구성이 가능하다.
위에서 이야기 한 server-id 말고도 bin-log 도 동일하다. Master 의 변경사항은 bin-log 를 통해 전파되기 때문에 이 값이 설정되어 있지 않으면 Replication 구성이 되었다고 말할 수 없다. 추가로 이 역시 서버의 재시작이 필요한 값이기 때문에 초기에 반드시 설정해야 한다. (default 는 사용하지 않는다.)
서비스를 온전히 가져가면서(다운타임 없이) 구성하기 위해서는 Ibbackup 을 사용해야 한다. 해당 백업도구를 사용한다는 것은 InnoDB 를 사용한다는 것이다. MyISAM 의 경우 다른 게시물에서 이야기 하겠지만 백업의 과정 중 Table Level 로 Lock 을 걸기 때문에 서비스의 온전한 사용이 불가하다.
여기서는 Ibbackup 을 이용해 Master 의 Service Down 없이 Replication 구성을 해보도록 하겠다.
2. 구성 Scenario
l Master
InnoDB 구성을 위한 Variable 을 명시적으로 정의
n datadir
n innodb_data_home_dir
n innodb_data_file_path
n innodb_log_group_home_dir
n innodb_log_files_in_group
n innodb_log_file_size
Server-id 를 명시적으로 정의
n my.cnf 에 기술한다. Restart 가 필요한 작업
l Slave
Slave 구성은 제로부터 시작한다.
설치 엔진은 Master 와 동일하다.
Master 의 InnoDB 데이터를 Hot Backup 으로 가져온다.
3. 구성진행
A. Master
i. Master Engine 설치
MySQL Binary 를 받아 압축해제하였다.
oracle32@/home/mysql/mysql1>ls
mysql-advanced-5.5.8-linux2.6-i686.tar
oracle32@/home/mysql/mysql1>tar xvf *.tar
압축을 해제하면 tar 의 파일명으로 폴더가 생성되는데 안의 모든 폴더 및 파일을 현재 위치로 이동하였고 tar 파일은 제거하였다.
위 상태의 폴더를 Slave 용으로 복사하였다.
oracle32@/home/mysql>cp -R mysql1 mysql2
ii. Variable 셋팅
base directory 를 /home/mysql/mysql1 로 사용한다.
base directory 밑에 conf 폴더를 생성한다.
support-files 밑의 my-small.cnf 를 conf 밑에 my.cnf 로 복사한다.
conf 밑의 my.cnf 에 다음의 내용을 추가(수정) 한다.
- datadir
- datadir = /home/mysql/mysql1/data
- innodb_data_home_dir = /home/mysql/mysql1/data
- innodb_data_file_path = ibdata1:10m
- innodb_log_group_home_dir = /home/mysql/mysql1/data
- innodb_log_files_in_group = 3
- innodb_log_file_size = 10m
- port = 7000
- socket = /tmp/mysql2.sock
- log-bin=mysql1-bin
iii. Install Script 실행 및 DB 기동
oracle32@/home/mysql/mysql1>./scripts/mysql_install_db --defaults-file=/home/mysql/mysql1/conf/my.cnf --user=mysql
oracle32@/home/mysql/mysql1>./bin/mysqld_safe --defaults-file=/home/mysql/mysql1/conf/my.cnf --user=mysql &
앞에서 InnoDB 에 대해 정의한 대로 해당 디렉토리에 파일이 생성되었음을 확인하였다.
oracle32@/home/mysql/mysql1/data>ls
ibdata1 ib_logfile1 oracle32.test.com.err performance_schema
ib_logfile0 mysql oracle32.test.com.pid test
위의 내용을 보면 ibdata 와 ib_logfile 이 생성되었음을 알 수 있다.
iv. InnoDB 용 Script 수행
Schema innodb_test 를 생성하고 생성된 Schema 를 이용해 world_innodb.sql.gz 를 사용해 InnoDB Storage Engine 을 사용하는 테이블과 데이터를 생성했다.
해당 스크립트는 (http://dev.mysql.com/doc/index-other.html) 에서 다운 받을 수 있다.
oracle32@/home/mysql>gunzip world_innodb.sql.gz
oracle32@/home/mysql>ls
Desktop mysql1 mysql-advanced-5.5.8-linux2.6-i686 world_innodb.sql
mysql mysql2 mysql-advanced-5.5.8-linux2.6-i686.tar
oracle32@/home/mysql>cp *.sql ./mysql1
압축을 해제해 sql 파일을 mysql1 base directory 로 복사한다.
oracle32@/home/mysql/mysql1>./bin/mysql -uroot -S /tmp/mysql1.sock
mysql> create database innodb_test;
Query OK, 1 row affected (0.00 sec)
mysql> use innodb_test;
Database changed
mysql> source world_innodb.sql
v. Ibbackup 수행
mysql1 의 conf 밑에 my.cnf 를 my2.cnf 이름으로 복제본을 만들고 /home/mysql/mysql1 부분의 mysql1 을 mysql1_bak 으로 변경하였다.
my2.cnf 에 InnoDB 와 관련된 Variable 중 File Path 부분을 앞서 이야기 한대로 수정하였다.
oracle32@/home/mysql/mysql1>./ibbackup /home/mysql/mysql1/conf/my.cnf /home/mysql/mysql1/conf/my2.cnf
oracle32@/home/mysql/mysql1/data2>ls
ibbackup_logfile ibdata1
백업이 완료되었다. 추가로 스키마의 구조적 정보가 전혀 없는 상태로 지금의 상황은 불완전한 상태이다. 다음과 같이 frm 파일도 복사를 해야 한다.
oracle32@/home/mysql/mysql1/data>cp -R innodb_test ../data2
위에서 이야기 한 ibbackup 에 대한 추가적인 설명은 아래의 링크를 참조하기 바란다. (http://h391106.tistory.com/220)
B. Slave
i. Slave Engine 설치
Master 구성 때 이미 mysql2 로 복사하였다.
ii. Variable 셋팅
base directory 를 /home/mysql/mysql2 로 사용한다.
base directory 밑에 conf 폴더를 생성한다.
support-files 밑의 my-small.cnf 를 conf 밑에 my.cnf 로 복사한다.
conf 밑의 my.cnf 에 다음의 내용을 추가(수정) 한다.
- server-id = 2
- datadir
- datadir = /home/mysql/mysql2/data
- innodb_data_home_dir = /home/mysql/mysql2/data
- innodb_data_file_path = ibdata1:10m
- innodb_log_group_home_dir = /home/mysql/mysql2/data
- innodb_log_files_in_group = 3
- innodb_log_file_size = 10m
- port = 7001
- socket = /tmp/mysql2.sock
- log-bin=mysql2-bin
iii. Install Script 실행
oracle32@/home/mysql/mysql2>./scripts/mysql_install_db --defaults-file=/home/mysql/mysql2/conf/my.cnf --user=mysql
oracle32@/home/mysql/mysql2>./bin/mysql -uroot -S /tmp/mysql2.sock
DB 에 접속되는 것을 확인하고 Shutdown 한다.
(뒤에 이야기 하겠지만 innodb 용으로 생성된 파일을 삭제해야 한다.)
iv. IbBackup 본 복사
백업본을 복사하기 전에 log 를 로그 적용을 해야 한다.
oracle32@/home/mysql/mysql1>./ibbackup --apply-log /home/mysql/mysql1/conf/my2.cnf
oracle32@/home/mysql/mysql1/data2>ls
ibbackup_logfile ibdata1 ib_logfile0 ib_logfile1 ib_logfile2 innodb_test
앞서의 ibbackup 결과물로
oracle32@/home/mysql/mysql1/data2>cp -R * ../../mysql2/data
oracle32@/home/mysql/mysql2/data>ls
ibbackup_logfile ib_logfile1 mysql test
ibdata1 ib_logfile2 oracle32.test.com.err
ib_logfile0 innodb_test performance_schema
oracle32@/home/mysql/mysql2/data>rm ibbackup_logfile
Slave MySQL 을 시작한다.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| innodb_test |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.01 sec)
앞서 진행한 복사의 결과물로 innodb_test database 가 추가되었음을 알 수 있다.
mysql> show tables;
+-----------------------+
| Tables_in_innodb_test |
+-----------------------+
| City |
| Country |
| CountryLanguage |
+-----------------------+
3 rows in set (0.00 sec)
innodb_test database 의 구성물을 살펴본 결과이다. 테이블들이 정상적으로 들어있음을 알 수 있었다.
DB 가 Open 이 되었고 백업본 데이터가 정상적으로 보이는 걸 확인하였으나 여기서 끝난 것이 아니다.
백업본 데이터를 옮긴 것이기 때문에 해당 시점부터 현재에 이르기까지 Master 의 데이터는 변화했을 가능성이 높다. 아래의 내용은 이를 확인하기 위한 작업이다.
v. Maser - Slave 일관성 맞추기 위한 작업
Slave 측 log 를 최근 발생순으로 확인해 보면 다음과 같은 구문을 확인할 수 있다.
InnoDB: Last MySQL binlog file position 0 1297116, file name ./mysql1-bin.000001
위 정보는 change master 구문을 통해 사용이 가능하다. 이를테면 file name 과 position 정보이다.
vi. Slave 구성
n in Master
Slave 가 접속할 수 있도록 Master 에 User 를 생성한다.
mysql> grant replication client,replication slave on *.*
-> to 'mysql2'@'10.10.10.31' identified by 'mysql2';
Query OK, 0 rows affected (0.01 sec)
n in Slave
mysql> change master to
-> master_host = '10.10.10.31',
-> master_user = 'mysql2',
-> master_password = 'mysql2',
-> master_port = 7000,
-> master_log_file = 'mysql1-bin.000001',
-> master_log_pos = 1297116;
Query OK, 0 rows affected (0.02 sec)
alert 로그를 통해 얻어진 정보를 master_log_file, master_log_pos 에 사용하였다.
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
Slave 를 시작하였다.
mysql> show processlist;
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+
| 2 | root | localhost | NULL | Query | 0 | NULL | show processlist |
| 3 | system user | | NULL | Connect | 6 | Waiting for master to send event | NULL |
| 4 | system user | | NULL | Connect | 304 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL |
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+
3 rows in set (0.01 sec)
Processlist 를 조회한 결과 User Thread (위에서 ID = 2) 를 제외하고 추가적으로 3,4 번의 Thread 가 생성된 것을 알 수 있다. 이 두 프로세스는 Master 의 Binary Log 로 Relay log 를 생성하기 위한 Thread 와 이를 수행하기 위한 Thread 이다.
변경내역이 전파되는가 검증을 위해 testing schema 를 만들어 testing table 에 데이터를 넣어보겠다.
n in Master
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| innodb_test |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
mysql> create database testing;
Query OK, 1 row affected (0.00 sec)
mysql> use testing;
Database changed
mysql> create table testing(num int) engine=innodb;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into testing values(33);
Query OK, 1 row affected (0.01 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> show tables;
+-------------------+
| Tables_in_testing |
+-------------------+
| testing |
+-------------------+
1 row in set (0.00 sec)
n in Slave
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| innodb_test |
| mysql |
| performance_schema |
| test |
| testing |
+--------------------+
6 rows in set (0.01 sec)
mysql> use testing;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-------------------+
| Tables_in_testing |
+-------------------+
| testing |
+-------------------+
1 row in set (0.00 sec)
mysql> select * from testing;
+------+
| num |
+------+
| 33 |
+------+
앞에서의 작업내역이 전파된 것을 알 수 있다. Replication 이 정상 구성 되었다.