본문 바로가기

Technical/DBMS

MySQL 5.5(Percona 5.5.15-21.0 stable) Master-Master replication


* 2011/09/22에 update됨
* MySQL이 MySQL 5.5 부터는 SemiSync 라는 쓸만한 기능으로 Availability가 더 향상되었다.
즉, M-S1S2 형태의 Replication에서 M의 Transaction과 S로의 binlog write가 병렬로 처리되며(Master가 Slave의 binlog로의 전송을 보장, 동기=sync), S의 binlog에서 Storage 로의 write 는 비동기(async)로 처리된다(==> 반동기=SemiSync)
[참조] http://www.mysqlkorea.co.kr/gnuboard4/bbs/board.php?bo_table=develop_03&wr_id=73

* 기존의 5.1.x 대에 비해서 script의 위치나 Replication 설정 방식에서 약간의 차이를 보이고 있다.

* M1=Master1, M2=Master2

* 선행 패키지 설치

# zypper in -y cmake ncurses-devel readline-devel bison



* 다운로드 & 빌드

wget http://www.percona.com/redir/downloads/Percona-Server-5.5/Percona-Server-5.5.15-21.0/source/Percona-Server-5.5.15-rel21.0.tar.gz
#  tar xvzf Percona-Server-5.5.15-rel21.0.tar.gz
# cd Percona-Server-5.5.15-rel21.0/
# groupadd mysql 
# useradd -g mysql -s /bin/false mysql
# sh BUILD/autorun.sh
./configure --prefix=/user/service/mysql --with-mysqld-user=mysql --sysconfdir=/user/service/mysql/conf --with-unix-socket-path=/tmp/mysqld/mysql.sock --with-charset=utf8 --with-extra-charsets=all --with-plugins=innobase,innodb_plugin,myisam,partition
# make && make install



* 디렉토리, my.cnf 설정

# cd /user/service/mysql
# export PATH=$PATH:/user/service/mysql/bin (.bashrc 에도 추가) 
# mkdir conf



# vi conf/my.cnf
[client]

port                                    = 3306
socket                                  = /tmp/mysql.sock
[mysqld_safe]
socket                                  = /tmp/mysql.sock
nice                                    = 0
# TimeZone
#default-time-zone                       = 'Asia/Seoul'

[mysqld]
# TimeZone
#default-time-zone                       = 'Asia/Seoul'

# UTF8
init_connect=SET collation_connection   = utf8_general_ci
init_connect                            = SET NAMES utf8
character-set-server                    = utf8
collation-server                        = utf8_general_ci
# Storage engine
default-storage-engine                  = innodb
# no difference between upper and lowercases
lower_case_table_names                  = 1
# General settings
user                                    = mysql
pid-file                                = /tmp/mysqld/mysql.pid
socket                                  = /tmp/mysqld/mysql.sock
port                                    = 3306
# Directory settings
basedir                                 = /user/service/mysql
datadir                                 = /user/service/mysql/data
tmpdir                                  = /tmp
# ETC
skip-external-locking
# Tunnig options
key_buffer_size                         = 384M
max_allowed_packet                      = 16M
table_open_cache                        = 512
sort_buffer_size                        = 2M
read_buffer_size                        = 2M
read_rnd_buffer_size                    = 8M
myisam_sort_buffer_size                 = 64M
thread_cache_size                       = 8
# for MyIsam
myisam-recover                          = BACKUP
max_connections                         = 250
max_user_connections                    = 200
# Try number of CPU's*2 for thread_concurrency, 5.5.3+ ignored
# thread_concurrency                    = 8
# Important for bulk loading
query_cache_size                        = 32M
# * Logging and Replication
slow_query_log                          = /user/service/mysql/data/mysql-slow.log
long_query_time                         = 2

# Replication Master Server (default)
server-id                               = 1

log-bin                                = mysql-bin
log-warnings
log-slave-updates
replicate-same-server-id                 = 0
auto-increment-increment               = 1
relay-log                               = mysql-relay-bin

expire_logs_days                        = 10
max_binlog_size                         = 100M
binlog_format                           = ROW
# * InnoDB
innodb_data_home_dir                    = /user/service/mysql/data
innodb_data_file_path                   = ibdata1:2000M;ibdata2:10M:autoextend
innodb_log_group_home_dir               = /user/service/mysql/data

# buffer_pool_size up to 50 - 80 % of RAM
#innodb_buffer_pool_size                 = 1536M # 사용 가능 memory 에 맞게 설정
innodb_buffer_pool_size                 = 256M
innodb_additional_mem_pool_size         = 20M
# log_file_size to 25 % of buffer pool size
innodb_log_file_size                    = 384M
innodb_log_buffer_size                  = 8M
innodb_flush_log_at_trx_commit          = 1
innodb_lock_wait_timeout                = 10
innodb_file_per_table
innodb_file_format                      = barracuda

[mysqldump]
quick
max_allowed_packet                      = 32M
[mysql]
no-auto-rehash # faster start of mysql but no tab completition
[myisamchk]
key_buffer_size                         = 256M
sort_buffer_size                        = 256M
read_buffer                             = 2M
write_buffer                            = 2M
[mysqlhotcopy]
interactive-timeout


* 기본 데이터베이스 스키마 생성 & Grant 설정

# ./scripts/mysql_install_db --defaults-file=/user/service/mysql/conf/my.cnf --user=mysql

# mysqld_safe --defaults-file=/user/service/mysql/conf/my.cnf --log-bin-trust-function-creators=1 &

# mysqladmin -u root password 'password'
# mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -uroot -ppassword mysql 
## Database에서 Timezone 을 사용할 경우, my.cnf 에서 comment 로 막아 둔 default-time-zone 의 comment 를 해제
# mysqladmin  -uroot -ppassword shutdown
# mysqld_safe --defaults-file=/user/service/mysql/conf/my.cnf --log-bin-trust-function-creators=1 --skip-slave --relay-log=mysql-relay-bin &
# mysql -uroot -ppassword
M1> use mysql;
M1> grant all privileges on *.* to 'root'@'%' identified by 'password' with grant option;
M1> grant all privileges on *.* to 'root'@'localhost' identified by 'password' with grant option;
M1> flush privileges; 

root 권한 설정/ 확인
M1> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO root@"%" IDENTIFIED by 'password';
M1> flush privileges; 

사용하려고 하는 database명이 mydb 라고 가정하고, 데이터베이스 생성과 개발자(사용자) 계정을 생성하고 권한을 아래과 같이 설정한다
M1>  insert into mySql.User (host, User, Password) values ('%', 'devuser', password('dev_passwd'));
M1> insert into mySql.User (host, User, Password) values ('localhost', 'devuser', password('dev_passwd'));
M1> flush privileges; 
M1> create database mydb;
M1> GRANT ALL PRIVILEGES ON mydb.* TO 'devuser'@'localhost' IDENTIFIED BY 'dev_passwd';
M1> GRANT ALL PRIVILEGES ON mydb.* TO 'devuser'@'%' IDENTIFIED BY 'dev_passwd'; 
M1> REVOKE ALTER, DROP ON mydb.* FROM 'devuser'@'localhost';
M1> REVOKE ALTER, DROP ON mydb.* FROM 'devuser'@'%'; 
M1> flush privileges; 
M1> GRANT ALL PRIVILEGES ON mysql.func TO 'devuser'@'localhost' IDENTIFIED BY 'dev_passwd';
M1> GRANT ALL PRIVILEGES ON mysql.func TO 'devuser'@'%' IDENTIFIED BY 'dev_passwd'; 
M1> GRANT ALL PRIVILEGES ON mysql.proc TO 'devuser'@'localhost' IDENTIFIED BY 'dev_passwd';
M1> GRANT ALL PRIVILEGES ON mysql.proc TO 'devuser'@'%' IDENTIFIED BY 'dev_passwd'; 
M1> GRANT ALL PRIVILEGES ON mysql.procs_priv TO 'devuser'@'localhost' IDENTIFIED BY 'dev_passwd';
M1> GRANT ALL PRIVILEGES ON mysql.procs_priv TO 'devuser'@'%' IDENTIFIED BY 'dev_passwd'; 
M1> flush privileges; 



* M1의 DB를 source로 하여 M2 로 동기화 후 Master-Master 설정하기
   M1, M2 의 DB shutdown(또는 M1을 down 시키기 곤란한 경우 flush logs; flush tables wih read lock 으로 lock 설정, M2는 down)

# rsync -rpv root@M1_ip_addr:/user/service/mysql/data /user/service/mysql/
## Default port 22가 아닌 sshd  접속의 경우
# rsync -rpv -e "ssh -p 55000" root@M1_ip_addr:/user/service/mysql/data /user/service/mysql/ 
## CloudN, EC2 등과 같은 Cloud Platform의 pem 보안 키 접속일 경우
# rsync -rpv -e "ssh -i XXXX,pem" root@M1_ip_addr:/user/service/mysql/data /user/service/mysql/ 
# chown -R mysql.mysql ./data

* M1, conf/my.cnf 에서 server_id = 1 임을 확인
* M2, conf/my.cnf 에서 server_id = 2(또는 2보다 큰 정수) 임을 확인

* M1, M2 Database start
# mysqld_safe --defaults-file=/user/service/mysql/conf/my.cnf --log-bin-trust-function-creators=1 --skip-slave --relay-log=mysql-relay-bin &



* M1에서
# mysql -uroot -ppassword
M1> show master status;

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
| mysql-bin.000010 |      107 |              |                  |
1 row in set (0.00 sec)

* M2에서
# mysql -uroot -ppassword
M2> change master to master_host='M1_ip_addr', master_user='root', master_password='password', master_log_file='mysql-bin.000010', master_log_pos=107;
M2> slave start;
M2> show slave status;

* M1에서 M2 를 source로 하여 마찬가지로 change master to 로 Replication 을 설정하고 slave start 로 복제를 시작시킨다



* MySQL 5.5 에서는, 5.1.X 에서 적용되던 my.cnf 에서의 master_host, master_user, master-password 변수를 통한 Replication 설정은 더 이상 사용되지 않게 바뀌었다.