Rocky9 + MySQL 단방향 리플리케이션 및 xtrabackup
1) 구성 정보• Primary: db1• Replica: db2, db3• Primary IP: db1ip• 리플리케이션 계정: repl• 방식: GTID (SOURCE_AUTO_POSITION=1)───2) MySQL 8.0 설치 (3대 공통)# dnf -y install https://dev.mysql.com/get/mysql80-com
1) 구성 정보
• Primary: db1
• Replica: db2, db3
• Primary IP: db1ip
• 리플리케이션 계정: repl
• 방식: GTID (SOURCE_AUTO_POSITION=1)
───
2) MySQL 8.0 설치 (3대 공통)
# dnf -y install https://dev.mysql.com/get/mysql80-community-release-el9-5.noarch.rpm# dnf clean all# dnf makecache# dnf -y install mysql-community-server# systemctl enable --now mysqldmysql의 레포 설치 및 mysql 커뮤니티 버전 설치 후 실행합니다.
# grep 'temporary password' /var/log/mysqld.logmysql 설치 후 사용 시 초기 비밀번호를 변경해줘야하기 때문에
/var/log/mysqld.log 파일에서 초기 비밀번호를 확인한 후
# mysql_secure_installation명령어를 통해 비밀번호 재설정 및 보안 관련 설정을 진행합니다.
버전 확인:
# mysql --versionxtrabackup 진행할 때 mysql 버전 8.0이상 버전의 방식으로 진행하였기 때문에
버전 확인 필수적 입니다.
───
3) 리플리케이션 설정
3-1) db1 (Primary) 설정
설정 파일(/etc/my.cnf 또는 /etc/my.cnf.d/mysql-server.cnf)에 추가:
[mysqld]
server_id=1
log_bin=mysql-bin
binlog_format=ROW
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON
해당 설정 파일 하단에 있는 [mysqld] 부분에 내용을 추가해 줍니다.
# systemctl restart mysqld설정파일에 추가한 내용을 적용해 주고
# mysql -uroot -p> CREATE USER 'repl'@'db대역' IDENTIFIED BY '비밀번호';
> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'db대역';
> FLUSH PRIVILEGES;
참고: 인증 플러그인 이슈가 있으면 아래처럼 변경해서 적용해 줍니다.
> ALTER USER 'repl'@'db대역' IDENTIFIED WITH mysql_native_password BY '비밀번호';
> FLUSH PRIVILEGES;
레플리케이션을 위한 유저를 생성해 줍니다. db 대역은 테스트 용도의 경우 '%'로 입력해 모두 허용해 줄 수 있습니다.
보안을 위해 해당 대역대를 입력해 주는 것을 권장합니다.
ex) '192.168.0.%'
───
3-2) db2 / db3 (Replica) 설정
db2
[mysqld]
server_id=2
relay_log=relay-bin
log_bin=mysql-bin
binlog_format=ROW
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON
read_only=ON
db3
[mysqld]
server_id=3
relay_log=relay-bin
log_bin=mysql-bin
binlog_format=ROW
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON
read_only=ON
적용(각 서버):
# systemctl restart mysqld연동할 다른 db서버에도 같은 위치에 해당 설정 부분을 넣고
설정을 적용해 줍니다.
───
4) Replica에서 Primary 연결
db2, db3 각각 실행:
> STOP REPLICA;
> RESET REPLICA ALL;
> CHANGE REPLICATION SOURCE TO
> SOURCE_HOST='db1ip',
> SOURCE_PORT=3306,
> SOURCE_USER='repl',
> SOURCE_PASSWORD='비밀번호',
> SOURCE_AUTO_POSITION=1;
> START REPLICA;
> SHOW REPLICA STATUS\G;
정상 기준:
• Replica_IO_Running: Yes
• Replica_SQL_Running: Yes
• Last_IO_Error / Last_SQL_Error 없음
위 부분들이 동일하면 연동은 성공입니다.
───
5) 동기화 테스트
db1(Primary)에서 테스트 데이터 생성:
> CREATE DATABASE IF NOT EXISTS repl_test;
> USE repl_test;
> CREATE TABLE IF NOT EXISTS sync_test (
id INT AUTO_INCREMENT PRIMARY KEY, node_name VARCHAR(20), msg VARCHAR(200),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
> INSERT INTO sync_test (node_name, msg) VALUES ('db1', 'replication first check');
데이터베이스 생성 후에 레플리케이션으로 연동한 db2,3에서도 정상적으로 연동 되었는지 확인해줍니다.
db2/db3(Replica)에서 확인:
SELECT * FROM repl_test.sync_test;
3대에서 동일 데이터가 조회되면 단방향 복제 구성 완료입니다.
6) 장애 발생 시 slave DB Master DB로 승격
# systemctl stop mysqld# systemctl status mysqld먼저 Master DB 서버의 mysqld를 중단시킨 후
db2를 Master 서버로 승격 시키며 db1 서버의 장애 대응을 진행하겠습니다.
# mysql -uroot -p> SHOW REPLICA STATUS\G;
를 입력할 경우 제일 위에 줄인 부분과
Replica_IO_State: Reconnecting after a failed source event read
Last_IO_Errno: 2003
Last_IO_Error: Error reconnecting to source 'repl@db1_ip:3306'. This was attempt 7/86400, with a delay of 60 seconds between attempts. Message: Can't connect to MySQL server on 'db1_ip:3306' (111)
가 뜨게 됩니다. db1의 mysqld를 중단 했기 때문에 해당 서버와 통신이 끊겼다는 것을 의미하며
db2를 마스터 서버로 승격시켜 이를 해결하겠습니다.
> STOP REPLICA;
> SET GLOBAL super_read_only=OFF;
> SET GLOBAL read_only=OFF;
빠른 장애 대응과 추후 복구할 db1을 다시 마스터 서버로 사용하기 위해
/etc/my.cnf를 수정하는 대신 SQL 내부에서 해당 명령어를 실행해 레플리케이션 중단합니다.
> SHOW REPLICA STATUS\G
명령어를 통해 레플리케이션 상태를 확인해보면
Replicate IO가 발생하고 있지 않은 것을 확인할 수 있습니다.
이후 db3에서
> STOP REPLICA;
> RESET REPLICA ALL;
> CHANGE REPLICATION SOURCE TO
> SOURCE_HOST='db2_ip',
> SOURCE_PORT=3306,
> SOURCE_USER='repl',
> SOURCE_PASSWORD='비밀번호',
> SOURCE_AUTO_POSITION=1;
를 통해 복제를 중단하고 이전에 설정한 레플리케이션 설정을 초기화한 후
새롭게 db2와 연결을하기 위한 설정을 진행합니다.
> START REPLICA;
> SHOW REPLICA STATUS\G
서버 ip는 db2로 변경되어서 올라온 점을 확인할 수 있으며, Replica_IO도 정상적으로 이루어지는 것을 확인할 수 있습니다.
db2에서 새로운 데이터 베이스를 생성하고 이후 테이블을 작성하여 정상적으로 db3와 연결이 되었는지 테스트하겠습니다.
> CREATE DATABASE db2_test_db;
> USE db2_test_db;
> CREATE TABLE t1 (
id INT PRIMARY KEY AUTO_INCREMENT,
msg VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
> INSERT INTO t1 (msg) VALUES ('db2 master write test');
> SELECT * FROM t1;
정상적으로 데이터 베이스 및 테이블이 작성되었으며,
db3에서도 정상적으로 읽히는 것을 확인할 수 있습니다.
───
7) 후속 검증: XtraBackup 설치
# dnf -y install https://repo.percona.com/yum/percona-release-latest.noarch.rpm# percona-release enable-only tools release# dnf clean all && sudo dnf makecache# dnf -y install percona-xtrabackup-80# xtrabackup --version* 버전은 mysql 8.0 버전에서 사용 가능한 방법이며 버전 확인이 필수적입니다.
───
8) 후속 검증: 백업/복구
8-1) db1에서 백업 계정 생성
> CREATE USER 'backup'@'localhost' IDENTIFIED BY '비밀번호';
> GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backup'@'localhost';
> FLUSH PRIVILEGES;
운용 편의성을 위해 리플리케이션 유저와 백업 유저를 구분해서 사용할 수 있도록 설정하였습니다.
8-2) db1에서 풀백업
# mkdir -p /backup/mysql/full_날짜시간# BACKUP_DIR=/backup/mysql/full_날짜시간# xtrabackup --backup --target-dir=$BACKUP_DIR --user=backup --password='비밀번호'# xtrabackup --prepare --target-dir=$BACKUP_DIR파일이 정상적으로 생성 되었는지 확인 후에 복원을 진행합니다.
8-3) db2 또는 db3에서 복원 리허설
* db1에서 실행
# scp -r /backup/mysql/full_날짜시간 root@db2ip:/backup/mysql/db1에서 db2로 백업한 파일을 원격으로 보내줍니다.
* db2에서 복원 전 사전 준비
# RESTORE_DIR=/backup/mysql/full_날짜시간변수를 지정해 주고
db2 데이터 디렉토리 교체 후 복원 작업을 진행합니다.
# systemctl stop mysqld# mv /var/lib/mysql /var/lib/mysql.bak_날짜시간기존 디렉토리를 다른 곳으로 옮겨주고
# mkdir -p /var/lib/mysql새로운 기본 디렉토리를 생성해 줍니다.
# xtrabackup --copy-back --target-dir=$RESTORE_DIR# chown -R mysql:mysql /var/lib/mysql디렉토리 복구를 진행한 다음 소유자 변경을 진행해 줍니다.
# systemctl start mysqld다시 mysql 서비스를 실행해준 후 다음 복원이 정상적으로 이루어졌는지 확인합니다.
복원 확인:
> SHOW DATABASES;
repl_test 데이터 베이스가 정상적으로 생성되었는지 확인되면 백업 및 복구가 정상적으로 이루어졌습니다.