๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
BackEnd๐ŸŒฑ/DB & SQL

[Docker MySQL] Master-Slave Replication(๋ณต์ œ) ๊ตฌ์ถ•ํ•˜๊ธฐ

by ์•ˆ์ฃผํ˜• 2023. 11. 1.

๊ฐœ์š”

MySQL์˜ Master-Slave Replication์€ ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ(Consistency) ๋ฐ ๊ฐ€์šฉ์„ฑ(Availability)์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ๋„๋ฆฌ ์“ฐ์ด๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” Docker๋ผ๋Š” ์ปจํ…Œ์ด๋„ˆ ๋„๊ตฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ MySQL ํ™˜๊ฒฝ์—์„œ Master-Slave Replication์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์€ ํฌ๊ฒŒ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ„์–ด ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

  1. Master-Slave Replication ๊ตฌ์„ฑํ•˜๊ธฐ
  2. Bridge Network์„ ์ด์šฉํ•œ Replication ๊ตฌ์„ฑ

 

Replication ๋™์ž‘ ์›๋ฆฌ

MySQL์˜ ๋ณต์ œ ๊ธฐ๋Šฅ์€ ํด๋ผ์ด์–ธํŠธ์˜ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์—์„œ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„๋กœ ๋ณต์‚ฌํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์€ ํฌ๊ฒŒ 4๋‹จ๊ณ„๋กœ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค.

https://jane096.github.io/project/mysql-master-slave-replication/

  1. ๋ณ€๊ฒฝ์‚ฌํ•ญ์˜ ๊ธฐ๋ก: ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์„ ์š”์ฒญํ•˜๊ณ  ์ด๋ฅผ Commitํ•˜๋ฉด, ์ด ๋ณ€๊ฒฝ์‚ฌํ•ญ์€ ๋จผ์ € ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์— ์กด์žฌํ•˜๋Š” Binary log์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. Binary log๋Š” MySQL ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๋กœ๊ทธ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.
  2. ๋ณ€๊ฒฝ์‚ฌํ•ญ์˜ ์ „์†ก: ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์˜ Master Thread๋Š” Binary log๋ฅผ ์ฝ์–ด ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„๋กœ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์€ ๋ณต์‚ฌ๋˜๋Š” ์‹œ๊ฐ„์„ ๊ธฐ๋‹ค๋ ค์ฃผ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ํฐ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์žˆ๋”๋ผ๋„ ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์˜ ์ž‘์—…์ด ์ง€์—ฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  3. ๋ณ€๊ฒฝ์‚ฌํ•ญ์˜ ์ €์žฅ: ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์˜ I/O Thread๋Š” ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ๋ณ€๊ฒฝ ๋ฐ์ดํ„ฐ๋ฅผ Relay log์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. Relay log๋Š” ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ Binary log๋ฅผ ์ €์žฅํ•˜๋Š” ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์˜ ๋กœ๊ทธ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.
  4. ๋ณ€๊ฒฝ์‚ฌํ•ญ์˜ ์ ์šฉ: ๋งˆ์ง€๋ง‰์œผ๋กœ, ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์˜ SQL Thread๋Š” Relay log์˜ ๊ธฐ๋ก์„ ์ฝ์–ด ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์˜ ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์— ์ตœ์ข…์ ์œผ๋กœ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜์—ฌ ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์˜ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์—๋„ ๋ฐ˜์˜๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ: Amazone Linux

 

1. Master-Slave Replication ๊ตฌ์„ฑํ•˜๊ธฐ

1.1 ๋””๋ ‰ํ† ๋ฆฌ ๋ฐ ํŒŒ์ผ ์„ค์ •

๋จผ์ €, Master์™€ Slave ์„œ๋ฒ„๋ฅผ ์œ„ํ•œ ๋””๋ ‰ํ† ๋ฆฌ์™€ ํŒŒ์ผ์„ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‹จ๊ณ„์—์„œ๋Š” ๋ฐ์ดํ„ฐ, ๋กœ๊ทธ, ์„ค์ • ํŒŒ์ผ์„ ์ €์žฅํ•  ๊ณต๊ฐ„์„ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

mkdir -p /db/db001/data /db/db002/data /db/db003/data

chmod 777 /db/db001 /db/db001/data
chmod 777 /db/db002 /db/db002/data 
chmod 777 /db/db003 /db/db003/data

mkdir -p /db/db001/log /db/db001/conf
mkdir -p /db/db002/log /db/db002/conf
mkdir -p /db/db003/log /db/db003/conf

chmod 777 /db/db001/log /db/db001/conf
chmod 777 /db/db002/log /db/db002/conf
chmod 777 /db/db003/log /db/db003/conf

๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ ํ™•์ธ

์œ„ ๋ช…๋ น๋“ค์„ ์‹คํ–‰ํ•˜๋ฉด, ํ•„์š”ํ•œ ๋””๋ ‰ํ† ๋ฆฌ๋“ค์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

 

1.2 MySQL ์„ค์ •

์ด ๋‹จ๊ณ„์—์„œ๋Š” ๊ฐ๊ฐ์˜ ์„œ๋ฒ„์— ๋Œ€ํ•œ MySQL ์„ค์ • ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ , ๊ฐ ์„œ๋ฒ„๋งˆ๋‹ค ๊ณ ์œ ํ•œ ์„ค์ •์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์š” ์„ค์ •์—๋Š” binlog, gtid, server-id ๋“ฑ์ด ์žˆ์œผ๋ฉฐ, ์ด๋“ค์€ ๋ฐ์ดํ„ฐ ๋ณต์ œ์— ํ•„์š”ํ•œ ์„ค์ •๋“ค์ž…๋‹ˆ๋‹ค. master(db001)๋ฅผ ์ œ์™ธํ•œ slave(db002, db003)์—๋Š” read_only ์„ค์ •์ด ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ด ์„ค์ •๋“ค์˜ ๊ฐ„๋žตํ•œ ์„ค๋ช…์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • log_bin: ๋ฐ”์ด๋„ˆ๋ฆฌ ๋กœ๊น…์„ ํ™œ์„ฑํ™”ํ•œ๋‹ค. ๋ฐ”์ด๋„ˆ๋ฆฌ ๋กœ๊ทธ๋Š” ๋ณต์ œ์™€ ํŠธ๋žœ์žญ์…˜ ๋ณต๊ตฌ์— ํ•„์š”ํ•˜๋ฉฐ, ๋กœ๊ทธ ํŒŒ์ผ์— ๋ชจ๋“  ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์ด ๊ธฐ๋ก๋œ๋‹ค.
  • binlog_format: ๋ฐ”์ด๋„ˆ๋ฆฌ ๋กœ๊ทธ ์ด๋ฒคํŠธ๊ฐ€ ์ €์žฅ๋˜๋Š” ํ˜•์‹์„ ์ง€์ •ํ•œ๋‹ค. ROW๋Š” ๊ฐ ํ–‰ ๋ณ€๊ฒฝ์„ ๋กœ๊ทธ์— ๊ธฐ๋กํ•œ๋‹ค.
  • gtid_mode ๋ฐ enforce-gtid-consistency: GTID(Global Transaction Identifier)๋ฅผ ํ™œ์„ฑํ™”ํ•œ๋‹ค. GTID๋Š” ๊ฐ ํŠธ๋žœ์žญ์…˜์— ๊ณ ์œ ํ•œ ID๋ฅผ ๋ถ€์—ฌํ•˜์—ฌ ๋ณต์ œ๋ฅผ ๋” ์•ˆ์ •์ ์ด๊ณ  ์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•˜๋„๋ก ํ•œ๋‹ค.
  • server-id: ๋ณต์ œ ๊ตฌ์„ฑ์—์„œ ๊ฐ MySQL ์„œ๋ฒ„๋ฅผ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.
  • log_slave_updates:์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„๊ฐ€ ์ž์‹ ์˜ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋กœ๊ทธ์— ๋ณต์ œ๋œ ํŠธ๋žœ์žญ์…˜์„ ๊ธฐ๋กํ•˜๋„๋ก ํ•œ๋‹ค.
  • datadir: MySQL ๋ฐ์ดํ„ฐ ํŒŒ์ผ์ด ์ €์žฅ๋˜๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ง€์ •ํ•œ๋‹ค.
  • socket: MySQL ์„œ๋ฒ„์˜ ์œ ๋‹‰์Šค ์†Œ์ผ“ ํŒŒ์ผ์˜ ์œ„์น˜๋ฅผ ์ง€์ •ํ•œ๋‹ค.
  • read_only: ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋ฉฐ, ์Šฌ๋ ˆ์ด๋ธŒ์—์„œ ๋ชจ๋“  ๋ณ€๊ฒฝ์„ ๊ฑฐ๋ถ€ํ•˜์—ฌ ๋ชจ๋“  ๋ณ€๊ฒฝ์ด ๋งˆ์Šคํ„ฐ์—์„œ๋งŒ ๋ฐœ์ƒํ•˜๋„๋ก ํ•œ๋‹ค.

1.1์—์„œ ์ƒ์„ฑํ•œ /db/dbxxx/conf ๋””๋ ‰ํ† ๋ฆฌ์— cnf ํ˜•์‹์˜ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ , ์œ„์˜ ์„ค์ • ๋‚ด์šฉ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, db001์˜ MySQL ์„ค์ •์„ ์œ„ํ•ด /db/db001/conf/my.cnf ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  ์•„๋ž˜์˜ ๋‚ด์šฉ์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

db001 MySQL ์„ค์ •

# db001์˜ MySQL ์„ค์ • ์˜ˆ์‹œ
[mysqld]
log_bin                     = mysql-bin
binlog_format               = ROW
gtid_mode                   = ON
enforce-gtid-consistency    = true
server-id                   = 100
log_slave_updates
datadir                     = /var/lib/mysql
socket                      = /var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links              = 0

log-error                   = /var/log/mysql/mysqld.log
pid-file                    = /var/run/mysqld/mysqld.pid

report_host                 = db001

[mysqld_safe]
pid-file                    = /var/run/mysqld/mysqld.pid
socket                      = /var/lib/mysql/mysql.sock
nice                        = 0

์œ„์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋‚˜๋จธ์ง€ ์„œ๋ฒ„(db002, db003)์˜ ์„ค์ • ํŒŒ์ผ๋„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ, ๊ฐ ์„ค์ • ํŒŒ์ผ์˜ server-id๋Š” ๊ณ ์œ ํ•ด์•ผ ํ•˜๋ฉฐ, ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์˜ ๊ฒฝ์šฐ read_only ์„ค์ •์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

db002 MySQL ์„ค์ •

# db002์˜ MySQL ์„ค์ • ์˜ˆ์‹œ

[mysqld]
log_bin                     = mysql-bin
binlog_format               = ROW
gtid_mode                   = ON
enforce-gtid-consistency    = true
server-id                   = 200
log_slave_updates
datadir                     = /var/lib/mysql
socket                      = /var/lib/mysql/mysql.sock
read_only

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links              = 0

log-error                   = /var/log/mysql/mysqld.log
pid-file                    = /var/run/mysqld/mysqld.pid

report_host                 = db002

[mysqld_safe]
pid-file                    = /var/run/mysqld/mysqld.pid
socket                      = /var/lib/mysql/mysql.sock
nice                        = 0

db003 MySQL ์„ค์ •

# db003์˜ MySQL ์„ค์ • ์˜ˆ์‹œ

[mysqld]
log_bin                     = mysql-bin
binlog_format               = ROW
gtid_mode                   = ON
enforce-gtid-consistency    = true
server-id                   = 300
log_slave_updates
datadir                     = /var/lib/mysql
socket                      = /var/lib/mysql/mysql.sock
read_only

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links              = 0

log-error                   = /var/log/mysql/mysqld.log
pid-file                    = /var/run/mysqld/mysqld.pid

report_host                 = db003

[mysqld_safe]
pid-file                    = /var/run/mysqld/mysqld.pid
socket                      = /var/lib/mysql/mysql.sock
nice                        = 0

 

1.3 Docker ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰

์ด์ œ ๊ฐ MySQL ์„œ๋ฒ„๋ฅผ Docker ์ปจํ…Œ์ด๋„ˆ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. db001, db002, db003์˜ ์ด๋ฆ„์œผ๋กœ ๊ฐ๊ฐ์˜ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. 

docker run -i -t --name db001 -h db001 -p 3306:3306 \
-v /db/db001/data:/var/lib/mysql \
-v /db/db001/log:/var/log/mysql \
-v /db/db001/conf:/etc/percona-server.conf.d \
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30
docker run -i -t --name db002 -h db002 -p 3307:3306 \
-v /db/db002/data:/var/lib/mysql \
-v /db/db002/log:/var/log/mysql \
-v /db/db002/conf:/etc/percona-server.conf.d \
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30
docker run -i -t --name db003 -h db003 -p 3308:3306 \
-v /db/db003/data:/var/lib/mysql \
-v /db/db003/log:/var/log/mysql \
-v /db/db003/conf:/etc/percona-server.conf.d \
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30

๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ƒ์„ฑ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด docker ps ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ช…๋ น์–ด๋Š” ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ์˜ ๋ชฉ๋ก์„ ๋ณด์—ฌ์ฃผ๋ฉฐ,  --format ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์ถœ๋ ฅ ํ˜•์‹์„ ์ง€์ •ํ•˜๋ฉด, ID, ์ด๋ฆ„, ์ƒํƒœ ๋“ฑ ํ•„์š”ํ•œ ์ •๋ณด๋งŒ ๋ณด๋‹ค ํŽธ๋ฆฌํ•˜๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"

docker ps ํ™•์ธ

 

1.4 ๋ณต์ œ ์‚ฌ์šฉ์ž ์ƒ์„ฑ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌ

์ด ๋‹จ๊ณ„์—์„œ๋Š” ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์—์„œ ๋ณต์ œ๋ฅผ ์œ„ํ•œ ์‚ฌ์šฉ์ž๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ํ•„์š”ํ•œ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

# Docker ์ปจํ…Œ์ด๋„ˆ ์ ‘์†
docker exec -it -uroot db001 /bin/bash

# MySQL ์ ‘์†
mysql -uroot -p

# ๋ณต์ œ ์‚ฌ์šฉ์ž ์ƒ์„ฑ
CREATE USER 'repl'@'%' IDENTIFIED BY 'repl';

# ๋ณต์ œ ๊ถŒํ•œ ๋ถ€์—ฌ(์—ฌ๊ธฐ์„œ 'REPLICATION SLAVE'๋Š” ๋ณต์ œ ์Šฌ๋ ˆ์ด๋ธŒ ๊ถŒํ•œ์„ ์˜๋ฏธ)
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';

# ๊ถŒํ•œ ์ฆ‰์‹œ ์ ์šฉ
FLUSH PRIVILEGES;

 

1.5 Slave ์„œ๋ฒ„ ์„ค์ •(db002 ๋ฐ db003 Replication ์„ค์ •)

์ด์ œ ๊ฐ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์— ๋Œ€ํ•ด ๋ณต์ œ ์„ค์ •์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ db002์™€ db003์€ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์˜ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ๊ฐ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์— ๋Œ€ํ•ด ๋™์ผํ•œ ์„ค์ •์„ ์ง„ํ–‰ํ•˜๋ฉฐ, ๊ฐ ์„ค์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

# Docker ์ปจํ…Œ์ด๋„ˆ ์ ‘์†
docker exec -it -uroot db002 /bin/bash
# ๋˜๋Š”
docker exec -it -uroot db003 /bin/bash

# MySQL ์ ‘์†
mysql -uroot -p

# ์ด์ „ ๋ณต์ œ ์„ค์ • ์ดˆ๊ธฐํ™”
reset master;

# Master ์„œ๋ฒ„ ์ •๋ณด ์„ค์ •
CHANGE MASTER TO MASTER_HOST='172.17.0.1', \
        MASTER_USER='repl', MASTER_PASSWORD='repl',  \
        MASTER_AUTO_POSITION=1;

# ๋ณต์ œ ์‹œ์ž‘
START SLAVE;

์—ฌ๊ธฐ์„œ MASTER_HOST๋Š” ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์˜ IP ์ฃผ์†Œ๋‚˜ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์ด๋ฉฐ, MASTER_USER์™€ MASTER_PASSWORD๋Š” ์•ž์„œ ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์—์„œ ์ƒ์„ฑํ•œ ๋ณต์ œ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด์ž…๋‹ˆ๋‹ค. MASTER_AUTO_POSITION=1์€ GTID ๊ธฐ๋ฐ˜ ๋ณต์ œ๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋Š” ์„ค์ •์ž…๋‹ˆ๋‹ค.

๋ณต์ œ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ง„ํ–‰๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ž˜์˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ Slave_IO_Running์™€ Slave_SQL_Running ์ƒํƒœ๊ฐ€ ๋ชจ๋‘ 'Yes'๋กœ ์ถœ๋ ฅ๋˜๋Š”์ง€ ํ™•์ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. 'Yes'๋กœ ์ถœ๋ ฅ๋˜๋ฉด ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„๊ฐ€ ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ •์ƒ์ ์œผ๋กœ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๊ณ , ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

show slave status\G

 

2. Bridge Network์„ ์ด์šฉํ•œ Replication ๊ตฌ์„ฑ

Docker์˜ Bridge Network๋Š” Docker ์ปจํ…Œ์ด๋„ˆ ๊ฐ„์˜ ํ†ต์‹ ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ๋„คํŠธ์›Œํฌ ๋ชจ๋“œ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐ ์ปจํ…Œ์ด๋„ˆ์— ๋Œ€ํ•ด ๊ฒฉ๋ฆฌ๋œ ๋„คํŠธ์›Œํฌ ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•˜๋ฉฐ, ์ปจํ…Œ์ด๋„ˆ ๊ฐ„์—๋Š” ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์„ ํ†ตํ•ด ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Docker ์ปจํ…Œ์ด๋„ˆ๋Š” ์–ธ์ œ๋“ ์ง€ ์žฌ์‹œ์ž‘๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์žฌ์‹œ์ž‘๋˜๋ฉด ํ•ด๋‹น ์ปจํ…Œ์ด๋„ˆ์˜ IP ์ฃผ์†Œ๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋Š” MySQL์˜ ๋ณต์ œ ์„ค์ •์ด๋‚˜ ๊ณ ๊ฐ€์šฉ์„ฑ(High Availability, HA) ์„ค์ •์— ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ด๋Ÿฌํ•œ ์„ค์ •๋“ค์€ ํŠน์ • IP ์ฃผ์†Œ๋ฅผ ์ฐธ์กฐํ•˜๊ธฐ ๋•Œ๋ฌธ์—, IP ์ฃผ์†Œ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ๋ณต์ œ๋‚˜ HA ์„ค์ •์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด Docker์˜ Bridge Network๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ net alias๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. net alias๋Š” ํŠน์ • ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์ถ”๊ฐ€์ ์ธ DNS ์ด๋ฆ„์œผ๋กœ, ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปจํ…Œ์ด๋„ˆ์˜ IP ์ฃผ์†Œ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ net alias๋Š” ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋˜์–ด ๋ณต์ œ๋‚˜ HA ์„ค์ •์ด ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Bridge Network๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  net alias๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

2.1 Bridge Network ์ƒ์„ฑ

๋จผ์ € docker network create ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Bridge Network๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

# ์ƒ์„ฑ
docker network create --driver bridge mybridge

# ํ™•์ธ
docker network ls

bridge network ์ƒ์„ฑ ํ™•์ธ

 

2.2 ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ ๋ฐ Bridge Network ์—ฐ๊ฒฐ

์ด์ œ ์ƒ์„ฑ๋œ Bridge Network๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ MySQL ์„œ๋ฒ„์˜ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์ปจํ…Œ์ด๋„ˆ๋Š” 'mybridge'๋ผ๋Š” ์ด๋ฆ„์˜ ๋„คํŠธ์›Œํฌ์— ์—ฐ๊ฒฐ๋˜๋ฉฐ, 'db001', 'db002', 'db003'๋ผ๋Š” net alias๋ฅผ ๊ฐ๊ฐ ๋ถ€์—ฌ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐ ์ปจํ…Œ์ด๋„ˆ๋Š” ์„œ๋กœ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

docker run -i -t --name db001 -h db001 -p 3306:3306 \
--net mybridge --net-alias=db001 \
-v /db/db001/data:/var/lib/mysql \
-v /db/db001/log:/var/log/mysql \
-v /db/db001/conf:/etc/percona-server.conf.d \
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30
docker run -i -t --name db002 -h db002 -p 3307:3306 \
--net mybridge --net-alias=db002 \
-v /db/db002/data:/var/lib/mysql \
-v /db/db002/log:/var/log/mysql \
-v /db/db002/conf:/etc/percona-server.conf.d \
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30
docker run -i -t --name db003 -h db003 -p 3308:3306 \
--net mybridge --net-alias=db003 \
-v /db/db003/data:/var/lib/mysql \
-v /db/db003/log:/var/log/mysql \
-v /db/db003/conf:/etc/percona-server.conf.d \
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30

์—ฌ๊ธฐ์„œ --net mybridge ์˜ต์…˜์€ ์ปจํ…Œ์ด๋„ˆ๋ฅผ 'mybridge' ๋„คํŠธ์›Œํฌ์— ์—ฐ๊ฒฐํ•˜๋ผ๋Š” ์˜๋ฏธ์ด๊ณ , --net-alias=db001 ๊ฐ™์€ ์˜ต์…˜์€ ์ปจํ…Œ์ด๋„ˆ์— 'db001'์ด๋ผ๋Š” net alias๋ฅผ ๋ถ€์—ฌํ•˜๋ผ๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ์ด net alias๋ฅผ ํ†ตํ•ด ์ปจํ…Œ์ด๋„ˆ์˜ IP ์ฃผ์†Œ๊ฐ€ ๋ฐ”๋€Œ๋”๋ผ๋„, ์ด alias๋ฅผ ํ†ตํ•ด ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด, ์ปจํ…Œ์ด๋„ˆ์˜ IP ์ฃผ์†Œ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ ๋ณต์ œ ์„ค์ •์ด ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

2. 3 Slave ์„œ๋ฒ„ ์„ค์ •(db002 ๋ฐ db003 Replication ์„ค์ •)

์ด์ „๊ณผ ๋‹ค๋ฅด๊ฒŒ ์ด๋ฒˆ์—๋Š” MASTER_HOST์— IP ์ฃผ์†Œ ๋Œ€์‹  ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์˜ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด, ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์˜ IP ์ฃผ์†Œ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ ์„ค์ •์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

# Docker ์ปจํ…Œ์ด๋„ˆ ์ ‘์†
docker exec -it -uroot db002 /bin/bash
# ๋˜๋Š”
docker exec -it -uroot db003 /bin/bash

# MySQL ์ ‘์†
mysql -uroot -p

# ์ด์ „ ๋ณต์ œ ์„ค์ • ์ดˆ๊ธฐํ™”
reset master;

# Master ์„œ๋ฒ„์— ๋Œ€ํ•œ ๋ณต์ œ ์„ค์ •
CHANGE MASTER TO MASTER_HOST='db001', \
        MASTER_USER='repl', MASTER_PASSWORD='repl',  \
        MASTER_AUTO_POSITION=1;

# ๋ณต์ œ ์‹œ์ž‘
START SLAVE;

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์„ฑ๊ณต ์—ฌ๋ถ€๋Š” ์•„๋ž˜์˜ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

show slave status\G

 

 

Replication ํ…Œ์ŠคํŠธ

๋ณต์ œ ํ™•์ธ ํ…Œ์ŠคํŠธ

๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์˜ MySQL์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์„ ๋•Œ, ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์˜ MySQL์—์„œ๋„ ์ •์ƒ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์กฐํšŒ๋˜๋Š”๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

์ •๋ฆฌ

์—ฌ๊ธฐ๊นŒ์ง€ MySQL์˜ Master-Slave ๋ณต์ œ ๊ตฌ์„ฑ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์œ„ ๊ตฌ์„ฑ์€ ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์˜ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ž๋™์œผ๋กœ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์— ๋™๊ธฐํ™”๋˜๊ฒŒ ๋˜๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์˜ ๋ถ€ํ•˜๋ฅผ ํ˜ธ์œจ์ ์œผ๋กœ ๋ถ„์‚ฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ, ํ˜„์žฌ ๊ตฌ์„ฑ์—์„œ๋Š” ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์ค‘๋‹จ๋˜๋ฉด, ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„๊ฐ€ ์žˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์šด์˜์ž๊ฐ€ ์ง์ ‘ ์กฐ์น˜๋ฅผ ์ทจํ•˜๊ธฐ ์ „๊นŒ์ง€๋Š” ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„๋ฅผ ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„๋กœ ๋Œ€์ฒดํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, ๋‹ค์Œ ๊ธ€์—์„œ๋Š” ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์— ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„๋ฅผ ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„๋กœ ์Šน๊ฒฉ์‹œํ‚ค๋Š” ๊ณผ์ •์„ ์ž๋™ํ™”ํ•˜๋Š” Orchestrator๋ฅผ ํ™œ์šฉํ•œ ๊ณ ๊ฐ€์šฉ์„ฑ(High Availability, HA) ๊ตฌ์„ฑ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. 

๋Œ“๊ธ€