Changes between Initial Version and Version 1 of MariaDB 복제


Ignore:
Timestamp:
Nov 11, 2025, 10:33:53 AM (4 weeks ago)
Author:
yongwoo
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • MariaDB 복제

    v1 v1  
     1[[PageOutline]]
     2= MariaDB 복제 =
     3복제는 마스터(primary) 서버의 ["MariaDB 바이너리 로그" 바이너리 로그] 파일을 슬레이브(replica) 서버에 전달해서 이루어진다. 이 때 마스터 서버의 ["MariaDB 바이너리 로그" 바이너리 로그] 포맷은 ROW로 지정하는 것이 가장 안전하다.
     4
     5== 1. 복제 설정 ==
     6마스터 서버가 옛날 버전이어야(슬레이브 서버가 최신 버전) 제대로 동작한다.
     7
     8=== 1.1. 마스터 서버 설정 ===
     9MariaDB 설정 파일에 다음과 같이 ["MariaDB 바이너리 로그" 바이너리 로그]를 설정하고 server-id를 지정한 다음 MariaDB 서버를 재시작한다.
     10{{{
     11# incremental 백업을 하거나 복제를 하려면 바이너리 로그를 저장해야 한다.
     12# 로그 파일 기본이름은 명시적으로 지정해주는 것을 권장한다. 생략하면 호스트 이름을
     13# 사용하는데, 호스트 이름이 바뀔 경우에는 따라서 변경되기 때문이다.
     14log-bin=mysqld-bin
     15# ROW 포맷이 가장 안전
     16binlog_format=row
     17# 복제를 하지 않으려면 server-id=0으로 지정하거나
     18# 디폴트 값이 0이므로 server-id를 지정하지 않으면 됨.
     19# 10.2부터는 디폴트 값이 1로 바뀌고 0은 더이상 유효하지 않음.
     20server-id=1
     21# InnoDB 트랜잭션 복제를 하기 위해서 마스터에서
     22# innodb_flush_log_at_trx_commit=1과 sync_binlog=1을 지정.
     23# innodb_flush_log_at_trx_commit의 디폴트 값이 1이므로 그냥 생략해도 무방
     24sync_binlog=1
     25# 바이너리 로그 포맷을 ROW로 지정했기 때문에 함수를 만들 때 실수해도
     26# 복제하는 데 문제가 없다. 따라서 NON DETERMINISTIC 함수도 만들 수 있게끔
     27# log_bin_trust_function_creators를 1로 지정한다. 디폴트는 0.
     28log_bin_trust_function_creators=1
     29}}}
     30
     31=== 1.2. 마스터에 복제 계정 만들기 ===
     32REPLICATION SLAVE 권한을 가진 MariaDB 계정을 마스터 서버에 추가한다. 이 계정의 비밀번호를 master.info 파일에 암호화하지 않고 저장하므로 일반 계정을 사용하지 않고 복제를 위한 별도의 계정을 만드는 것이 좋다.
     33
     34{{{
     35MariaDB> CREATE USER 'repl'@'61.78.63.109' IDENTIFIED BY 'qhrwp!21';
     36MariaDB> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'61.78.63.109';
     37}}}
     38
     39=== 1.3. 슬레이브 서버 설정 ===
     40MariaDB 설정 파일에 다음과 같이 릴레이 로그를 설정하고 server-id를 마스터나 다른 슬레이브와 다르게 지정한 다음 MariaDB 서버를 재시작한다.
     41{{{
     42# 복제를 하지 않으려면 server-id=0으로 지정하거나
     43# 디폴트 값이 0이므로 server-id를 지정하지 않으면 됨.
     44# 10.2부터는 디폴트 값이 1로 바뀌고 0은 더이상 유효하지 않음.
     45server-id=2
     46# 로그 파일 기본이름은 명시적으로 지정해주는 것을 권장한다. 생략하면 호스트 이름을
     47# 사용하는데, 호스트 이름이 바뀔 경우에는 따라서 변경되기 때문이다.
     48relay-log=mysqld-relay-bin
     49# 슬레이브 서버를 읽기 전용으로 만듬. SUPER 권한을 가진 계정과 복제 슬레이브
     50# 쓰레드만 데이터를 변경할 수 있다. 실수로 어플리케이션이 마스터 서버 대신
     51# 슬레이브 서버의 데이터를 수정하는 사고를 막을 수 있다.
     52read_only
     53# 슬레이브 서버를 수정할 일이 없으면 바이너리 로그 파일을 저장할 필요 없음.
     54disable-log-bin
     55# 마스터 서버에서 SHOW SLAVE HOSTS 명령을 내렸을 때 보이는 슬레이브 서버 이름
     56# OS의 이름과 달라도 무방하다.
     57# 지정하지 않으면 SHOW SLAVE HOSTS 명령에서 Host 컬럼에 아무 것도 나오지 않는다.
     58report-host=venus
     59# 슬레이브에서 에러가 발생했을 때 복제를 계속할 것인지 설정. 디폴트는 OFF.
     60;slave_skip_errors=all
     61}}}
     62
     63low-priority-updates=1과 delay-key-write=ALL 옵션을 추가하면 슬레이브 서버의 속도(아마도 읽기 속도) 향상에 도움이 될 수 있다고 하는데, 그럴 필요까지 있는지는 모르겠다.
     64
     65=== 1.4. 바이너리 로그 좌표 포함한 마스터 백업 ===
     66--master-data를 지정하면 ["MariaDB 바이너리 로그" 바이너리 로그] 좌표(파일명과 위치)를 가리키는 CHANGE MASTER TO 문을 백업 파일에 기록하므로 슬레이브를 셋업하는 용도로 쓸 때 편하다. 슬레이브를 셋업하는 용도로 쓰지 않을 거라면 --master-data 대신에 -master-data=2를 지정해야 한다.
     67
     68{{{
     69mysqldump --master-data --flush-logs --delete-master-logs --all-databases --events > fullbackup.sql
     70}}}
     71 * --master-data[=value]
     72  - ["MariaDB 바이너리 로그" 바이너리 로그]가 활성화되어 있어야 한다.
     73  - 마스터에서 백업받은 것을 가지고 슬레이브를 셋업하기 위해서 사용한다. ["MariaDB 바이너리 로그" 바이너리 로그] 좌표(파일명과 위치)를 가리키는 CHANGE MASTER TO 문을 백업 파일에 기록한다.
     74  - 이 옵션을 사용하기 위해선 RELOAD 권한이 필요하다.
     75  - value 값의 디폴트는 1이다. 따라서 1일 때는 값을 생략할 수 있다.
     76  - value가 2이라면 CHANGE MASTER TO 문이 주석으로 삽입된다. 주석으로 삽입하기 때문에 실제 영향은 없다.
     77  - --single-transaction을 명시적으로 적어주지 않는다면 --lock-all-tables 옵션이 자동으로 지정된다.
     78  - --lock-tables 옵션을 자동으로 끈다.
     79 * --single-transaction
     80  - '''쓰기를 막지 않'''고도 일관성있게 데이터베이스를 백업할 수 있다.
     81  -  InnoDB 같은 트랜잭션을 지원하는 테이블에만 유용하다. MyISAM 같은 '''트랜잭션을 지원하지 않는 테이블에서는 논리적인 일관성이 보장되지 않는다'''.
     82  - --lock-tables과 같이 쓸 수 없다.
     83  - MySQL Cluster 테이블에는 사용할 수 없다. (확인 필요)
     84 * --lock-all-tables, -x
     85  - 백업을 하는 동안 모든 데이터베이스를 읽기만 가능하도록 잠근다(READ LOCK).
     86  - 이 옵션을 설정하면 --single-transaction과 --lock-tables 옵션은 자동으로 꺼진다.
     87  - '''데이터베이스의 일관성은 보장되지만 백업이 진행되는 동안 쓰기가 불가능'''해지므로 대용량 데이터베이스인 경우엔 신중하게 해야 한다.
     88  - full 백업 이후의 변경 사항을 복구(point-in-time 복구, roll-forward)하기 위해서라도 --lock-all-tables 명령 대신 --master-data=2 옵션을 주는 것이 좋다.
     89 * --lock-tables, -l
     90  - 백업을 하는 동안 특정 데이터베이스를 잠근다(READ LOCAL lock).
     91  - READ LOCAL LOCK이므로 진행 중인 insert는 허용한다.
     92  - 여러 데이터베이스를 백업할 때는 주의해야 한다. --lock-tables은 각 데이터베이스를 각각 잠근다. 그래서 데이터베이스간에 '''논리적인 일관성이 보장되지 않는다'''.
     93  - '''백업이 진행되는 동안 특정 데이터베이스에 쓰기가 불가능'''해지므로 대용량 데이터베이스인 경우엔 신중하게 해야 한다.
     94  - InnoDB나 BDB 같은 트랜잭션을 지원하는 테이블에는 --single-transaction이 더 나은 옵션이다. 테이블을 전혀 잠글 필요가 없기 때문이다.
     95 * --flush-logs, -F
     96  - 백업을 시작하기 전에 로그를 파일에 저장한다(flush).
     97  - 이 옵션을 사용하기 위해선 RELOAD 권한이 필요하다.
     98  - --all-databases 옵션과 같이 사용하면 각 데이터베이스가 백업될 때마다 각각 그 로그를 저장(flush)한다는 점에 주의한다.
     99  - 그러나 --lock-all-tables, --master-data 옵션이 사용되면 모든 데이터베이스를 잠근 순간에 한꺼번에 로그를 저장(flush)한다.
     100  - 따라서 백업과 로그 저장을 정확히 같은 시각에 하려면 --flush-logs를 --lock-all-tables, --master-data 옵션과 같이 사용해야 한다.
     101 * --delete-master-logs
     102  - ["MariaDB 바이너리 로그" 바이너리 로그]가 활성화되어 있어야 한다.
     103  -  백업 후에 PURGE BINARY LOGS 명령을 내려 ["MariaDB 바이너리 로그" 바이너리 로그]를 지운다.
     104  - --master-data 옵션을 지정하면 자동으로 활성화된다고 나오지만, 실제로는 그러지 않았다.(5.0.77, 10.3.27, 10.5.16에서 확인)
     105  - 슬레이브 서버가 연결되지 않은 상태에서 이 옵션을 지정하면 슬레이브 서버가 미처 ["MariaDB 바이너리 로그" 바이너리 로그] 내용을 동기화하기 전에 지워버리기 때문에 복제가 깨진다. 슬레이브 서버가 연결된 상태라면 슬레이브 서버가 로그 파일을 읽는 중에는 지우지 않고 에러를 내기 때문에 안전하다.
     106 * --events
     107  - 명시적으로 적어줘야 mysql.events 테이블을 백업한다. --all-databases 옵션을 줘도 mysql.events 테이블 스키마만 백업하고 데이터는 다음과 같은 경고를 내면서 백업하지 않는다. Warning: Skipping the data of table mysql.event. Specify the --events option explicitly.
     108  - EVENT 권한이 필요하다.
     109 * --dump-slave[=value]
     110  - 5.5.3 버전 이후부터 사용할 수 있다.
     111  - 슬레이브에서 백업받은 것을 가지고 또다른 슬레이브를 셋업하기 위해서 사용한다. 마스터의 ["MariaDB 바이너리 로그" 바이너리 로그] 좌표(파일명과 위치)를 가리키는 CHANGE MASTER TO 문을 백업 파일에 기록한다.
     112  - 이 옵션을 사용하면 --master-data 옵션을 무시한다.
     113  - 이 옵션을 사용하기 위해선 RELOAD 권한이 필요하다. 그리고 binary log가 활성화되어 있어야 한다.
     114  - value 값의 디폴트는 1이다. 따라서 1일 때는 값을 생략할 수 있다.
     115  - value가 2이라면 CHANGE MASTER TO 문이 주석으로 삽입된다. 주석으로 삽입하기 때문에 실제 영향은 없다.
     116  - --single-transaction을 명시적으로 적어주지 않는다면 --lock-all-tables 옵션이 자동으로 지정된다.
     117  - --lock-tables 옵션을 자동으로 끈다.
     118 * --quick
     119  - 디폴트 값이므로 따로 지정해주지 않아도 된다. 큰 테이블을 백업할 때 유용하다. --skip-quick 옵션을 사용하면 테이블 데이터를 모두 메모리에 불러온 다음에 백업 파일에 쓰기 시작한다.
     120
     121=== 1.5. 슬레이브에 복원 ===
     122{{{
     123$ mysql -u root < fullbackup.sql
     124}}}
     125
     126--master-data 옵션을 지정해서 백업 파일을 만들었기 때문에 이미 ["MariaDB 바이너리 로그" 바이너리 로그] 좌표(파일명과 위치)를 가리키는 CHANGE MASTER TO 문은 실행되었을테니, 나머지만 지정해주면 된다.
     127{{{
     128MariaDB> CHANGE MASTER TO MASTER_HOST='mysql.bookcube.com', MASTER_USER='repl', MASTER_PASSWORD='qhrwp!21';
     129MariaDB> START SLAVE;
     130}}}
     131
     132--master-data 옵션이 아니라 --master-data=2 옵션으로 백업을 했다면 ["MariaDB 바이너리 로그" 바이너리 로그] 좌표(파일명과 위치)가 백업 파일 앞 부분에 주석으로 포함되어 있다. 그 내용에 연결에 필요한 정보를 추가해서 다음과 같이 실행하면 된다. 처음 복제하는 것이기 때문에 STOP SLAVE를 먼저 해줄 필요는 없다.
     133
     134{{{
     135MariaDB> CHANGE MASTER TO MASTER_LOG_FILE='mysqld-bin.001105', MASTER_LOG_POS=107;
     136MariaDB> CHANGE MASTER TO MASTER_HOST='mysql.bookcube.com', MASTER_USER='repl', MASTER_PASSWORD='qhrwp!21';
     137MariaDB> START SLAVE;
     138}}}
     139
     140참고로 복제 진행 중에 CHANGE MASTER TO의 옵션 값을 바꿔야 한다면, 먼저 stop slave 명령으로 복제 스레드를 중지해야 한다. 예를 들어 복제 계정의 비밀번호가 바뀌었다면 다음과 같이 하면 된다.
     141{{{
     142MariaDB> STOP SLAVE; -- if replication was running
     143MariaDB> CHANGE MASTER TO MASTER_PASSWORD='new3cret';
     144MariaDB> START SLAVE; -- if you want to restart replication
     145}}}
     146
     147=== 1.6. 복제 확인 ===
     148슬레이브 서버가 제대로 작동하는지 확인하고 싶다면 SHOW SLAVE STATUS 명령을 내리면 된다. Slave_IO_Running 과 Slave_SQL_Running 컬럼 값이 둘다 Yes라면 제대로 동작하고 있는 것이다. MariaDB 클라이언트를 사용한다면 \G 파라미터를 붙여 사용하면 훨씬 보기 편하다.
     149{{{
     150MariaDB> show slave status\G
     151}}}
     152
     153마스터 서버에 비해서 슬레이브 서버가 얼마나 늦는지 보려면 Seconds_Behind_Master 컬럼을 보면 된다.
     154
     155혹은 다음과 같이 SHOW PROCESSLIST 명령을 내려서 마스터와 연결이 잘 되고 있는지 확인하면 된다. State 컬럼 값이 아래와 달리 'Connecting to master'로 나온다면 문제가 있는 것이다.
     156{{{
     157MariaDB> show processlist;
     158+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+
     159| Id | User        | Host      | db   | Command | Time | State                                                                       | Info             |
     160+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+
     161|  1 | system user |           | NULL | Connect |  124 | Waiting for master to send event                                            | NULL             |
     162|  2 | system user |           | NULL | Connect |   80 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL             |
     163+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+
     164}}}
     165
     166=== 1.7. 특정 데이터베이스 복제 제외 ===
     167예를 들어 mysql 데이터베이스는 복제에서 제외하고 싶다면 다음과 같은 옵션을 사용한다.
     168{{{
     169replicate-wild-ignore-table=mysql.%
     170}}}
     171
     172특정 데이터베이스를 복제에서 제외하려고 마스터 서버에서 binlog-do-db나 binlog-ignore-db 옵션을 사용하는 것은 피해야 한다.
     173
     174슬레이브 서버에서 replicate-do-db나 replicate-ignore-db 옵션을 사용하는 것도 피하는 것이 좋다. 예를 들어 replicate-ignore-db=sales 라고 지정했다고 하자.
     175{{{
     176USE prices;
     177UPDATE sales.january SET amount=amount+1000;
     178}}}
     179
     180이런 SQL문을 cross-database 업데이트라고 하는 것 같은데, STATEMENT 포맷일 때는 현재 데이터베이스가 무엇인가에 따라 복제 여부를 결정하지 실제 어느 데이터베이스가 변경되었는지에 따라 복제 여부를 결정하지 않는다.
     181
     182즉, 위와 같은 SQL 문을 실행하면 sales 데이터베이스가 replicate-ignore-db에 포함되어 있어도 복제가 된다. 현재 데이터베이스가 sales 가 아닌 prices 데이터베이스이기 때문이다.
     183
     184반면에 ROW 포맷일 때는 현재 데이터베이스가 무엇이든 간에 실제 작업 대상이 replicate-ignore-db에 포함되어 있다면 복제가 되지 않는다. 그러나, ["MariaDB 바이너리 로그" 바이너리 로그] 포맷을 ROW로 지정해도 mysql 데이터베이스의 변경이나 DDL 문 등은 STATEMENT 포맷으로 저장이 되므로 현재 데이터베이스의 영향을 받을 수 있다.(실제로 현재 데이터베이스의 영향을 받는지 확인해보진 못했다.)
     185
     186그래서 안전하게 replicate-wild-ignore-table 옵션을 사용하는 것이 좋다.
     187
     188== 2. 바이너리 로그 삭제 ==
     189마스터 서버의 바이너리 로그는 지워주지 않으면 계속 쌓인다.
     190
     191바이너리 로그 파일을 지운 후 full 백업을 새로 받거나, 바이너리 로그 파일을 지우기 전에 full 백업 이후의 모든 바이너리 로그를 백업받아야 한다.
     192
     193=== 2.1. 바이너리 로그 파일 수동 삭제 ===
     194현재 ["MariaDB 바이너리 로그" 바이너리 로그] 파일을 본다.
     195{{{
     196MariaDB> show binary logs;
     197+------------------+-----------+
     198| Log_name         | File_size |
     199+------------------+-----------+
     200| mysql-bin.000334 | 534806337 |
     201+------------------+-----------+
     202| mysql-bin.000335 |       335 |
     203+------------------+-----------+
     204}}}
     205
     206남겨놓을 ["MariaDB 바이너리 로그" 바이너리 로그] 파일을 지정해 다음 명령을 내리면 지정한 ["MariaDB 바이너리 로그" 바이너리 로그] 파일보다 이전 ["MariaDB 바이너리 로그" 바이너리 로그] 파일은 삭제한다.
     207{{{
     208MariaDB> PURGE BINARY LOGS TO 'mysql-bin.000335';
     209}}}
     210
     211이 명령은 복제가 진행 중일 때도 안전하다. 슬레이브 서버가 로그 파일을 읽는 중에는 로그 파일을 지우지 않고 에러를 내기 때문이다. 다만, 슬레이브 서버가 연결되지 않은 상태에서 이 명령을 내리면 복제가 깨진다.
     212
     213복제 중일 때 안전하게 ["MariaDB 바이너리 로그" 바이너리 로그]를 지우려면 모든 슬레이브 서버에서 SHOW SLAVE STATUS 명령을 내려서 마스터의 로그 파일을 잘 읽고 있는지 확인해야 한다.
     214{{{
     215MariaDB> SHOW SLAVE STATUS\G
     216*************************** 1. row ***************************
     217               Slave_IO_State: Waiting for master to send event
     218
     219              Master_Log_File: mysqld-bin.001116
     220          Read_Master_Log_Pos: 107
     221
     222             Slave_IO_Running: Yes
     223            Slave_SQL_Running: Yes
     224}}}
     225
     226=== 2.2. 바이너리 로그 파일 자동 삭제 ===
     227expire_logs_days 값을 지정해서 자동으로 ["MariaDB 바이너리 로그" 바이너리 로그]를 지울 수도 있다. 디폴트는 0으로 ["MariaDB 바이너리 로그" 바이너리 로그]를 지우지 않는 것이다.
     228{{{
     229expire_logs_days=32
     230}}}
     231으로 지정하면 32일이 지난 ["MariaDB 바이너리 로그" 바이너리 로그]는 지운다.
     232
     233다만 슬레이브 서버가 연결되지 않은 상태에서 ["MariaDB 바이너리 로그" 바이너리 로그]가 지워지면 복제가 깨진다.
     234
     235full 백업 이후의 변경 사항을 복구(point-in-time 복구, roll-forward)하기 위해 이렇게 지우기보다는 crontab 등으로 바이너리 로그를 백업한 후 지우는 것이 좋다.
     236
     237=== 2.3. 바이너리 로그를 백업하지 않고 삭제했을 때 ===
     238
     239["MariaDB 바이너리 로그" 바이너리 로그] 파일을 백업받지 않고 삭제했을 때는 반드시 full 백업을 해야 한다. 증분 백업 데이터가 지워졌기 때문이다.
     240
     241{{{
     242mysqldump --master-data=2 --flush-logs --delete-master-logs --all-databases --events > fullbackup.sql
     243}}}
     244* 마스터 서버를 복원할 목적으로 Full 백업을 하는 것이기 때문에 --master-data 대신에 --master-data=2 를 사용해야 한다.
     245* --delete-master-logs 옵션은 PURGE BINARY LOGS 명령을 내리기 때문에 슬레이브 서버가 연결되지 않은 상태에서는 복제가 깨진다.
     246
     247=== 2.4. 더이상 복제하지 않을 때 바이너리 로그 삭제 ===
     248다음은 마스터 서버에서만 가능한 명령인데, 모든 ["MariaDB 바이너리 로그" 바이너리 로그] 파일을 지우고 비어있는 000001 번 ["MariaDB 바이너리 로그" 바이너리 로그] 파일을 만든다. '''복제가 진행중일 때는 하면 안된다.'''
     249{{{
     250RESET MASTER
     251}}}
     252
     253== 3. 릴레이 로그 삭제 ==
     254슬레이브 서버의 릴레이 로그는 자동으로 지워지기 때문에 보통은 신경쓸 필요 없다. 다만 더 이상 복제하지 않을 때 필요없는 릴레이 로그를 삭제하려면 다음과 같이 한다.
     255
     2561. 복제 스레드를 중지한다
     257{{{
     258MariaDB> stop slave;
     259}}}
     2602. master.info와 relay-log.info 파일과 릴레이 로그 파일을 지운다.
     261{{{
     262MariaDB> reset slave all;
     263}}}
     264
     265== 4. Global Transaction ID (GTID) ==
     266http://www.gurubee.net/lecture/4213
     267
     268GTID 사용 이전 버전에서는 마스터 서버의 ["MariaDB 바이너리 로그" 바이너리 로그] 파일 이름과 위치를 전달하는 방법을 사용했으나 여러 슬레이브 서버를 사용할 때는 문제가 있었다.
     269
     270하나의 마스터 서버에 두 개 이상의 슬레이브 서버가 연결 된 상태에서 마스터 서버에 장애 발생 시
     271 - 슬레이브 서버 중 하나를 마스터 서버로 승격시키고
     272 - 다른 슬레이브 서버를 새로 생긴 마스터 서버를 바라보게 전환
     273 - 이 때 장애 발생 전 슬레이브 서버 간 전송 지연등에 의해 시점 차이가 있었을 경우 장애 이후 자동 동기화 불가
     274
     275글로벌 트랜잭션 ID를 사용한다면
     276 - 모든 서버 간 동일한 ID 값을 사용하므로
     277 - 마스터 서버가 바뀌더라도 무관
     278 - 전송 지연이 된 슬레이브 서버라도 새로 승격된 마스터 서버에서 동일한 GTID 값을 이용해 따라잡을 수 있다.
     279
     280MariaDB는 10.0.2부터 Global Transaction ID (GTID)를 이용한 복제를 지원한다.
     281
     282== 5. SLAVE인지 아닌지 확인 ==
     283지금 접속한 서버가 SLAVE인지 아닌지 알아내는 방법은 show slave status 명령을 내리는 것이다. 명령의 결과가 아무 것도 나오지 않는다면 MASTER다.
     284
     285프로시저 등에서 사용하려면 다음과 같은 SQL문을 사용하면 된다. 1을 리턴하면 MASTER, 0을 리턴하면 SLAVE다.
     286{{{
     287select count(1)
     288  from information_schema.global_status
     289  where variable_name = 'SLAVE_RUNNING'
     290    and variable_value = 'OFF';
     291}}}
     292
     293자주 사용한다면 다음과 같이 함수를 만드는 것도 좋은 방법이다.
     294{{{
     295delimiter //
     296create or replace function is_master()
     297  returns tinyint
     298  comment 'MASTER인지 아닌지 리턴하는 함수. 1을 리턴하면 MASTER, 0을 리턴하면 SLAVE다. SLAVE가 중지되면 잘못된 값을 리턴한다.'
     299  deterministic
     300begin
     301
     302  declare v_result tinyint;
     303
     304  select count(1) into v_result
     305    from information_schema.global_status
     306    where variable_name = 'SLAVE_RUNNING'
     307      and variable_value = 'OFF';
     308     
     309  return v_result;
     310   
     311end//
     312delimiter ;
     313
     314select is_master();
     315}}}
     316
     317이 방법의 단점은 SLAVE가 잠시 중지된 상태에서는 잘못된 정보를 준다는 것이다.
     318{{{
     319stop slave;
     320select is_master();
     321
     322start slave;
     323select is_master()
     324}}}
     325
     326위와 같은 문제가 없으면서도 조금 더 간단한 방법은 read_only 글로벌 변수를 사용하는 방법이다.
     327
     328SLAVE 서버의 설정에 read_only 를 추가했다면 SUPER 권한을 가진 사용자를 제외하고는 쓰기 작업이 불가능하기 때문에 SLAVE 서버에 많이 쓰는 설정이다.
     329
     330다음과 같이 그 값을 읽어올 수 있다.
     331{{{
     332select @@global.read_only;
     333}}}
     334
     335이 값이 1이라면 SLAVE, 0이라면 MASTER이다. 다만 이 방법은 SLAVE 설정에서 read_only를 지정하지 않을 수도 있기 때문에 완벽한 방법은 아니다.
     336
     337마지막 방법은 @@global.hostname 변수를 이용하는 방법이다. hostname 값이 MASTER인지 SLAVE인지는 하드코딩을 할 수도 있고 다음과 같이 처리할 수도 있다.
     338{{{
     339create or replace table master_list
     340(
     341    hostname varchar(64),
     342    primary key (hostname)
     343);
     344
     345delimiter //
     346create or replace function is_master()
     347  returns tinyint
     348  comment 'MASTER인지 아닌지 리턴하는 함수. 1을 리턴하면 MASTER, 0을 리턴하면 SLAVE다. MASTER와 SLAVE가 변경되면 master_list 테이블을 먼저 수정해야 한다.'
     349  deterministic
     350begin
     351
     352  declare v_result tinyint;
     353
     354  select count(1) into v_result
     355    from information_schema.global_variables g
     356    join master_list m
     357      on g.variable_value = m.hostname
     358    where variable_name='hostname';
     359     
     360  return v_result;
     361   
     362end//
     363delimiter ;
     364
     365select is_master();
     366
     367insert into master_list values ('local-hems.dasangng.co.kr');
     368
     369select is_master();
     370}}}
     371
     372----
     373[WikiStart 처음으로]