개요
- 데이터베이스 변경분을 binarylog에 event로 기록한다.
- inndb 기준, 1개의 event는 1개의 transaction 이다.
- slave는 master의 binarylog를 읽고 slave의 로컬 데이터베이스에서 binarylog의 event를 실행한다.
- 각 slave는 모든 binarycontents를 받는다. 또한 binarylog에서 어떤 구문을 수행할지에 대해서는 slave에서 결정한다.
- slave의 i/o thread는 로컬에 binary log를 저장하며 relay log 라고 한다.
- slave의 sql thread는 relay log 의 내용중에서 약속된 event 만 실행한다.
- event를 특정해서 적용하는것은 불가능 하며 특정 데이터베이스 및 테이블을 선정하는것은 가능하다.
- 각 slave는 현재 진행중인 binarylog의 좌표를 기록한다. 파일이름 위치 등등.
- 하나의 master에 복수개의 slave가 연결될 수 있으며 같은 내용에 대해 서로 다르게 처리될 수 있다. 이것은 slave가 제어하며 master의 작업에는 영향을 주지 않는다.
- 작업이 중단된 경우 추후 재개할때 처리된 부분부터 처리를 재개할 수 있다.
- master와 slave는 unique-id( server-id ) 로 구성되어야 한다.
- master의 정보는 host, log file name, position 등을 파일내에 저장하며 "CHANGE MASTER TO" 구문을 통해 변경이 가능한다.
master 설정
binary log file posiiton basedreplication 을 하기 위해서는 binary logging 을 활성화하고 unique server-id 를 설정해야 한다.
master의 my.cnf 에 아래와 같이 설정을 한다.
[mysqld]
# log file name
log-bin=mysql-bin
server-id=1
# 내구성을 위해 아래 옵션 사용이 추천된다. 단 성능하락이 올 수 있음
# transaction log
innodb_flush_log_at_trx_commit=1
# binary log
sync_binlog=1
# disable, accept connection from only unix socket
# skip-networking
replication 사용자 생성
각 slave 에서는 master 노드에 mysql 계정을 통해 접속을 하며 그 계정은 replication slave 권한을 가지고 있어야 한다.
mysql> CREATE USER 'test'@'%' IDENTIFIED BY 'password';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'test'@'%';
mysql> flush privileges;
master binary log 파일 및 position얻기
slave 에서 replication 을 시작하기 위해서는 master binary log file 및 position 을 얻어야 한다. 두가지 방법을 생각할 수 있다.
첫번째 방법은 데이터에 준비가 이미 끝났다면 'show master status' 쿼리를 실행한다.
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000006 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
두번째 장법은 write session 을 모두 종료하고 mysqldump 등의 백업을 통해 binary log 파일 및 position 정보를 얻고 백업을 이용하여 slave 의 초기 데이터를 적재한 이후 replication 을 시작한다.
$ ./bin/mysqldump --all-databases --opt --triggers --routines --master-data=2 --single-transaction --default-character-set=utf8 --passwd=test --user=test > backup.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
$ cat backup.sql | grep CHANGE
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000006', MASTER_LOG_POS=154;
data snapshot 을 선택하기
replication 을 시작하는 시점에서 schema object 는 전부 생성되어 있지만 데이터가 없다면 skip 해도되는 단계이다. 데이터가 있다면 replication 을 하기 위해서는 초기데이터 적재가 필요하다.
mysqldump
dump 하기에 앞서 mysqldump 를 수행하는 중간에 데이터베이스가 변경되면 안되기 때문에 모든 table 의 데이터를 flush 하고 관련 transaction 을 강제 종료한 이후에 read lock 잡는 과정이 필요하다.
(session1)
mysql> flush tables with read lock;
쿼리 수행이후 session 을 종료하면 lock 이 풀리기 때문에 session 을 유지한다.
다음은 mysqldump 를 이용하여 모든 데이터를 sql 파일에 기록한다.
(session2)
$ mysqldump --all-databases --master-data=2 --user=test --password=test --host=127.0.0.1 \
--single-transaction --flush-privileges \
--add-drop-database --add-drop-table --add-drop-trigger --all-tablespaces --routines --complete-insert --triggers> alldump.sql
(이상하게 '\' 를 이용하여 개행된 명령어 사용이 안됨... 한줄로 고쳐서 실행할 것을 추천)
파일의 내용중 '-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=6604;' 는 별도로 기록해둔다.
혹시 위 내용을 일괄적용하려 한다면 '--master-data=2' 를 '--master-data' 로 변경하면 주석이 없어져 바로 적용가능하다.
dump가 끝나고 생성된 alldump.sql 파일을 slave 서버에 적용한다.
$ mysql --user=root --password=root --host=127.0.0.1 < alldump.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
chlee@dev2:~/mysql
$ mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.27-log MySQL Community Server (GPL)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.00 sec)
mysql> use test
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_test |
+----------------+
| n1 |
| n2 |
| n3 |
| n4 |
| n5 |
| n6 |
+----------------+
6 rows in set (0.00 sec)
mysql>
모두 성공적으로 끝났다면 session1 에서 lock 을 해제한다.
(session1)
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
coldbackup
slave 가 설치되어 있지않고 mysql에 저장된 데이터가 많다면 mysqldump 에 비해 효율적인 방법이다.
mysql 의 '--datadir' 경로의 모든 데이터를 slave 의 '--datadir' 경로에 복사한 후 slave 를 기동한다.
하지만 'server-id' 의 값을 다르게 설정하도록 한다.
mysql master 서버를 shutdown 한다.
$ $MYSQL_HOME/bin/mysqladmin -h 127.0.0.1 -uroot -p shutdown
root 의 password 는 'mysqld --initialize ' 혹은 이후 'alter user root@... ' 에서 확인한다.
# 압축하기
$ tar cvfz $mysql_data.tar.gz $MYSQL_HOME/data
# datadir 은 다음 쿼리로 확인한다.
mysql> show variables like '%datadir%';
+---------------+-------------------------+
| Variable_name | Value |
+---------------+-------------------------+
| datadir | /home/chlee/mysql/data/ |
+---------------+-------------------------+
1 row in set (0.01 sec)
slave 설정
replication 을 위한 slave 설정은 데이터의 초기 적재가 모든 끝나고 master 와 slave 의 데이터가 동일하거나 적어도 schema object 가 같다는 전재한다.
물론 앞서 기술된 과정모두를 성곡적으로 수행 했다고 가정한다. 다음은 my.cnf 설정이다.
[mysqld]
server-id=2
slave 서버를 기동한다.
$ $MYSQL_HOME/bin/mysqld_safe --defaults-file=$MYSQL_HOME/etc/my.cnf --user=chlee &
chlee@dev2:~/mysql
$ 2019-08-06T10:41:28.706317Z mysqld_safe Logging to '/home/chlee/mysql/data/dev2.err'.
2019-08-06T10:41:28.725560Z mysqld_safe Starting mysqld daemon with databases from /home/chlee/mysql/data
slave 에 접속하여 다음 작업을 수행한다.
mysql> CHANGE MASTER TO
-> MASTER_HOST='192.168.56.3',
-> MASTER_USER='test',
-> MASTER_PASSWORD='test',
-> MASTER_LOG_FILE='mysql-bin.000001',
-> MASTER_LOG_POS=6604;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> start slave
-> ;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.56.3
Master_User: test
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 6604
Relay_Log_File: dev2-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
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: 6604
Relay_Log_Space: 526
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: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: dc8b732e-b825-11e9-ab35-080027bb6b82
Master_Info_File: /home/chlee/mysql/data/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
"Slave_IO_Running: Yes" , "Slave_SQL_Running: Yes" 를 확인했다면 일단 성공한 셈이다.
이제 master 에서의 변경이 slave 에서도 반영되는지 확인해 보자.
(master)
mysql> use test;
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> create table t1( i1 int );
Query OK, 0 rows affected (0.01 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql>
(slave)
mysql> use test;
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_test |
+----------------+
| n1 |
| n2 |
| n3 |
| n4 |
| n5 |
| n6 |
| t1 |
+----------------+
7 rows in set (0.00 sec)
mysql>
table t1 을 master 생성했을때 slave 에도 생성되는것을 볼 수 있다.
'Database > MySQL' 카테고리의 다른 글
mysql auto increment 를 포함한 테이블에서 pk 생성시 주의점 (0) | 2020.03.25 |
---|---|
RDS MySQL 로 Procedure 이관 (0) | 2020.03.25 |
SYSBENCH 를 이용하여 RDS MySQL, RDS Aurora, GCP Cloud SQL MySQL OLTP 테스트 2차 (0) | 2019.07.12 |
SYSBENCH 를 이용하여 RDS MySQL, RDS Aurora, GCP Cloud SQL MySQL OLTP 테스트 (0) | 2019.07.12 |
keepalived를 이용한 mysql failover (0) | 2019.07.08 |