DBA공부/MySQL

[MySQL/MariaDB HA (2)] MySQL/MariaDB를 사용한 고가용성 구성 HA 2일차

Kang_hobin 2024. 6. 4. 12:16
더보기

docker exec -it master mysql <- master라는 이름의 컨테이너에 접속하는데 mysql로 접속한다.

docker exec -it slave1 bash <- master라는 이름의 컨테이너에 접속하는데 bash로 접속한다.

 

강사님 왈.. 내가 신입사원에게 써봤냐고 물어보는 것 List
 
OS : Docker
code : git
document : MarkDown 
 
본인이 쓰시는 것
범용 Editor : VsCode
문서 관리 : Obsidian

MarkDown.. 

아래 처럼 코드를 치고 Open Preview 하면 html 형태로 바로 볼 수 있다.

또 ChatGpt도 html 형태 아웃풋이기 때문에 md로 사용하다보면 chatgpt를 이용해서 워드나 pandoc 등등 변환이 너무 간단하단다.

뭐.. 그렇단다. .md(MarkDown) 확장자로 도큐먼트를 많이들 쓴단다. 써버릇 해보자.

 

Git Bash..

일단 설치 고

설치 완. 도커가 wsl 위에 올라가듯이 얜 경량 리눅스 어쩌구(이름까먹) 위에 올라간단다.

이걸 깐 이유... 리눅스 환경으로 만들어 놓은 명령어들 (끝에 \ 붙여서 만들어 놓은 것들)을 쉽게 쓰기 위함 겸사겸사..

근데 얘도 그냥 바로 \를 쓸수 있는건 아니고 winpty를 앞에 붙여야됨. 그게 열받으니

git bash 설치 후에 바로 하는 환경설정을 하자.

## 셋팅
echo "alias docker='winpty docker'" >>~/.bash_profile
## 로그인 하면 실행되는 bash_profile에 docker만 써도 winpty가 붙도록 설정

user@DESKTOP-FSLB27A MINGW64 ~
$ docker run -it -v ${HOME}/df:/df --name u1 --rm ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
49b384cc7b4a: Pull complete
Digest: sha256:3f85b7caad41a95462cf5b787d8a04604c8262cdcdf9a472b8c52ef83375fe15
Status: Downloaded newer image for ubuntu:latest
root@e43d9c1da3aa:/# exit
exit

됬군.. 그냥 나와서 삭제시키고(--rm 옵션이 있으니 나오면 삭제됨)

환경변수 $whoami에 KITRI를 넣어서(그냥 폴더 강사님이랑 맞추려고) 경로를 다시 설정해주자.

user@DESKTOP-FSLB27A MINGW64 ~
$ whoami=KITRI
user@DESKTOP-FSLB27A MINGW64 ~
$ echo $whoami
KITRI

user@DESKTOP-FSLB27A MINGW64 ~
$ docker run -it -v c:\\Users\\$(whoami)\\df:/df --name u1 --rm ubuntu
root@723dbc25d189:/#

짠

 

이젠 git bash에서 윈도우 스크립팅을 연습해보자

생성이 된다.

그럼 스크립트는?

잘 된다! 이렇게 도커 1000개 이미지 생성 같은거도 가능하겠군

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ for i in $(seq 100); do docker run -d --name n$i --rm nginx ; done

요것도 가능하다는 소리.
하지만 여기 피시는 개 똥 컴이니까 눈으로만 보자

개.똥.컴..

그럼 이제 리눅스용 커맨드를 날려볼까

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ mkdir -p ~/df/Mysql/data
mkdir -p ~/df/Mysql/work
rm  -rf ~/df/Mysql/data/*
docker run                           \
    -d                               \
    --rm                             \
    --name mysql                     \
    -p 8081:8080                     \
    -p 3307:3306                     \
    -v ~/df/Mysql/data:/var/lib/mysql/   \
    -v ~/df/Mysql/work:/root/work        \
    -e MYSQL_ROOT_PASSWORD=mypass    \
    mysql
5c7a603cf731c5ad2ea9d576af919163e3a2ba5a29063cfd2e45fe048fc4648c

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$

된다링

 

MySQL Replication 사용목적

뭐 이런거처럼 조회용을 따로 slave로 만들어 놓는 등등 부하분산~!

 

오.. 만약 마스터와 슬레이브의 버전이 다르면 Slave 서버가 상위 버전이어야 한다네.. 반대일줄 알았다.

하지만 그냥 동일하게 맞추는 걸 권장한다.

 

MySql Replication : 비동기

 

MySQL Replication 실습4. MySql 컨테이너 생성

MySQL Replication 실습4. MySql 컨테이너 생성
아래 명령어로 할건데..

docker run -d --rm --name=master --net=replicanet --hostname=master \
-e MYSQL_ROOT_PASSWORD=mypass \
mysql/mysql-server:5.7 \
--server-id=1 \
--log-bin=
'mysql-bin-1.log'

이 중에 mtsql/mysql-server:5.7 ~~~~ 등등 부분은 원래 my.cnf에 있어야 되는데 지금은 그냥 파라미터로 넘기는 거다.

 

이제 Master와 Slave1, Slave2를 만들어서 복제가 잘 되는지 까지 테스트 해볼거다!

 2.MySQL_Replication/3.MySQL_ReplicationWorkShop 참고

먼저 서로 간의 network 통신을 위해 network를 replicanet라는 이름으로 생성한다.

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ docker network create replicanet
6fb7c0b457707845a0b2493a0d4c9210af721abc03961c3dda8d3d20cf1cfda4

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ docker network ls
NETWORK ID     NAME         DRIVER    SCOPE
868f56f4fe0e   bridge       bridge    local
42fdc7890ac2   host         host      local
73f1b70b6934   net1         bridge    local
830f1a6b86e0   none         null      local
6fb7c0b45770   replicanet   bridge    local

짠

그리고 master, slave1,2를 생성한다. 여기서 net은 동일한 replicanet! 으로 설정.

server-id만 1,2,3으로 다르다는 것 확인하자. 저건 원래 my.cnf에 들어갈 내용들이다.

docker run -d --rm --name=master --net=replicanet --hostname=master \
 -e MYSQL_ROOT_PASSWORD=mypass \
  mysql:5.7 \
  --server-id=1 \
  --log-bin='mysql-bin-1.log'

docker run -d --rm --name=slave1 --net=replicanet --hostname=slave1 \
   -e MYSQL_ROOT_PASSWORD=mypass \
  mysql:5.7 \
  --server-id=2

docker run -d --rm --name=slave2 --net=replicanet --hostname=slave2 \
 -e MYSQL_ROOT_PASSWORD=mypass \
  mysql:5.7 \
  --server-id=3
  
   실행해보자.
   
user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ docker run -d --rm --name=master --net=replicanet --hostname=master \
 -e MYSQL_ROOT_PASSWORD=mypass \
  mysql:5.7 \
  --server-id=1 \
  --log-bin='mysql-bin-1.log'

docker run -d --rm --name=slave1 --net=replicanet --hostname=slave1 \
   -e MYSQL_ROOT_PASSWORD=mypass \
  mysql:5.7 \
  --server-id=2

docker run -d --rm --name=slave2 --net=replicanet --hostname=slave2 \
 -e MYSQL_ROOT_PASSWORD=mypass \
  mysql:5.7 \
  --server-id=3
Unable to find image 'mysql:5.7' locally
5.7: Pulling from library/mysql
20e4dcae4c69: Pull complete
1c56c3d4ce74: Pull complete
e9f03a1c24ce: Pull complete
68c3898c2015: Pull complete
6b95a940e7b6: Pull complete
90986bb8de6e: Pull complete
ae71319cb779: Pull complete
ffc89e9dfd88: Pull complete
43d05e938198: Pull complete
064b2d298fba: Pull complete
df9a4d85569b: Pull complete
Digest: sha256:4bc6bc963e6d8443453676cae56536f4b8156d78bae03c0145cbe47c2aad73bb
Status: Downloaded newer image for mysql:5.7
7b1c089516147fbe1aaa9cce2ea9f26a549a7e19647f88d07397c5477eae166a
bc14222248f84ff33763255780a81d69d229c559d3329e64c67d247ee3792241
4737840081eb6f2879e41f33f4624238a828aac251404d59b9ac4db243bbf7d5

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test

개!!!!!!!!! 느리네
user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ docker ps -a
CONTAINER ID   IMAGE       COMMAND                   CREATED              STATUS          PORTS                 NAMES
4737840081eb   mysql:5.7   "docker-entrypoint.s…"   24 seconds ago       Up 18 seconds   3306/tcp, 33060/tcp   slave2
bc14222248f8   mysql:5.7   "docker-entrypoint.s…"   31 seconds ago       Up 24 seconds   3306/tcp, 33060/tcp   slave1
7b1c08951614   mysql:5.7   "docker-entrypoint.s…"   About a minute ago   Up 31 seconds   3306/tcp, 33060/tcp   master

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test

오케 떳고

 

요기서!!!! 

Let's configure the master node.
Configuring master node replication user and get the initial replication co-ordinates
마스터 노드를 구성합시다. 마스터 노드 복제 사용자를 구성하고 초기 복제 좌표를 얻습니다.

이걸 할거다.. 사실 mysql 문법이라 나중에 봐야겠따.. 

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ docker exec -it master mysql -uroot -pmypass
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.44-log MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

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> CREATE USER 'repl'@'%' IDENTIFIED BY 'slavepass';
Query OK, 0 rows affected (0.12 sec)

mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
Query OK, 0 rows affected (0.05 sec)

mysql> SHOW MASTER STATUS;
+--------------------+----------+--------------+------------------+-------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------------+----------+--------------+------------------+-------------------+
| mysql-bin-1.000003 |      595 |              |                  |                   |
+--------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql>

 

아오 진도 너무 빨라 내 컴은 개 느 린 데 !! 십..

여기서!!!

slave가 master에 붙는다!

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ for N in 1 2
  do docker exec -it slave$N mysql -uroot -pmypass \
    -e "CHANGE MASTER TO MASTER_HOST='master', MASTER_USER='repl', \
      MASTER_PASSWORD='slavepass', MASTER_LOG_FILE='mysql-bin-1.000003';"

  docker exec -it slave$N mysql -uroot -pmypass -e "START SLAVE;"
done
mysql: [Warning] Using a password on the command line interface can be insecure.

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug slave1
  Learn more at https://docs.docker.com/go/debug-cli/
mysql: [Warning] Using a password on the command line interface can be insecure.

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug slave1
  Learn more at https://docs.docker.com/go/debug-cli/
mysql: [Warning] Using a password on the command line interface can be insecure.

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug slave2
  Learn more at https://docs.docker.com/go/debug-cli/
mysql: [Warning] Using a password on the command line interface can be insecure.

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug slave2
  Learn more at https://docs.docker.com/go/debug-cli/

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$


흠 메시지는 무시하란다.
이제 뭘 했는지 좀 확인해보자

slave1한테 상태를 물어보자
user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ docker exec -it slave1 mysql -uroot -pmypass -e "SHOW SLAVE STATUS\G"
mysql: [Warning] Using a password on the command line interface can be insecure.
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: master
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin-1.000003
          Read_Master_Log_Pos: 595
               Relay_Log_File: slave1-relay-bin.000002
                Relay_Log_Pos: 812
        Relay_Master_Log_File: mysql-bin-1.000003
             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: 595
              Relay_Log_Space: 1020
              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: a7fbc60f-2218-11ef-9bf3-0242ac130002
             Master_Info_File: /var/lib/mysql/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:

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug slave1
  Learn more at https://docs.docker.com/go/debug-cli/

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$

제대로 동작하는 중임을 보여주는 것이라한다.
사실 봐도 모르겠다. 동작 안하는 것 같긴 한데 뭐 ... 허허
slave2도 해봐도 되는데 귀찮으니 패스

그럼 이제 Master에 데이터를 입력 했을 때!!!!!!!!!!!!

Slave에도 데이터가 들어가는 지를 보면 되는 거다.

해보자.

master의 Test DB에 x(id int)라는 테이블을 만들고 insert하고, slave에서 x테이블 select 해서 값이 전달 됐는지 확인 해보자.

먼저 master에 TEST database를 만들자

user@DESKTOP-FSLB27A MINGW64 /
$ docker exec -it master mysql -uroot -pmypass
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.44-log MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

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>

마스터에 접속했다.
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

엥 TEST DB가 없네 만들자
mysql> CREATE DATABASE TEST;
Query OK, 1 row affected (0.05 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| TEST               |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)


됬따.

그리고 테이블을 만들자

mysql> create table TEST.x(id int);
Query OK, 0 rows affected (0.89 sec)

mysql> select * from TEST.x;
Empty set (0.01 sec)

됬따.
이제 데이터를 넣어볼까
mysql> insert into TEST.x values(924);
Query OK, 1 row affected (0.19 sec)

mysql> select * from TEST.x;
+------+
| id   |
+------+
|  924 |
+------+
1 row in set (0.00 sec)

mysql>
굳 이제 slave1과 slave2에도 들어갔는지 확인해보자.

깃 배시를 새로 열어서 slave1,2에 접속해보자

잘 들어가있네. 굳..

 

이제 slave3을 생성해보자.

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ docker run -d --rm --name=slave3 --net=replicanet --hostname=slave3 \
 -e MYSQL_ROOT_PASSWORD=mypass \
  mysql:5.7 \
  --server-id=4
488c43e1581b0acef4b33b2a4c51e55c72f92bb1b594b2478849e870c08a5c9e

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test

만들었고..

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$   docker exec -it slave3 mysql -uroot -pmypass \
    -e "CHANGE MASTER TO MASTER_HOST='master', MASTER_USER='repl', \
      MASTER_PASSWORD='slavepass', MASTER_LOG_FILE='mysql-bin-1.000003';"

  docker exec -it slave3 mysql -uroot -pmypass -e "START SLAVE;"
mysql: [Warning] Using a password on the command line interface can be insecure.

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug slave3
  Learn more at https://docs.docker.com/go/debug-cli/
mysql: [Warning] Using a password on the command line interface can be insecure.

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug slave3
  Learn more at https://docs.docker.com/go/debug-cli/

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test

위에서 for문 돌렸던 부분을 빼서 slave3로 만든다

짠.. 완료..

복제의 핵심은 여기인 듯..

-- 마스터에서
docker exec -it master mysql -uroot -pmypass \
  -e "CREATE USER 'repl'@'%' IDENTIFIED BY 'slavepass';" \
  -e "GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';" \
  -e "SHOW MASTER STATUS;"
  
-- 각 슬레이브에서
docker exec -it slave3 mysql -uroot -pmypass \
  -e "CHANGE MASTER TO MASTER_HOST='master', MASTER_USER='repl', \
      MASTER_PASSWORD='slavepass', MASTER_LOG_FILE='mysql-bin-1.000003';"
-- 각 슬레이브에서
docker exec -it slave3 mysql -uroot -pmypass -e "START SLAVE;"

여기서 MASTER_LOG_FILE='mysql-bin-1.000003' 부분은

아래 쿼리해서 나온 결과 file 명을 그대로 가져온거다. 참고해라..!!

mysql> SHOW MASTER STATUS;
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+----------+--------------+------------------+-------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------------+----------+--------------+------------------+-------------------+
| mysql-bin-1.000003 |      595 |              |                  |                   |
+--------------------+----------+--------------+------------------+-------------------+

 

아참.. 실전에서 저렇게 exec -uroot -pmypass 이지랄 하면 로그에 비번 다 남는다. 절대 이렇게 하지 마셈.

그럼 어케하냐?

변수를 환경변수로 등록하고 로그인. 당연 컨테이너에 bash로 접속해서 해야겠지.

read -p "pass=" p

> pass=mypass

mysql -uroot -p$p

이렇게 해라..

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ docker exec -it master bash
bash-4.2# read -p "pass=" p
pass=mypass
bash-4.2# mysql -uroot -p$p
~~~
mysql>

 

이제 청소하래.. 

-- 컨테이너 삭제
user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ docker stop master slave1 slave2 slave3
master
slave1
slave2
slave3

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

-- 네트웤 삭제
user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ docker network rm replicanet
replicanet

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
868f56f4fe0e   bridge    bridge    local
42fdc7890ac2   host      host      local
73f1b70b6934   net1      bridge    local
830f1a6b86e0   none      null      local

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$

-- mysql 이미지는 걍 냅두자

 

2.MySQL_Replication/4.MySQL_ReplicationWithDockerCompose

여러개 한번에 만드는 일이 많아서 보통 compose로 생성하니 잘 봐두자.

## docker-compose 쳐보자

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ docker-compose
~~~
  rm          Removes stopped service containers
~~
  up          Create and start containers
~~
user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$

rm, up 정도만 보지 뭐

그래서 주신 스크립트가 아래다

cat >docker-compose.yml<<EOF
version: '3.8'
services:
  t1:
    image: ubuntu
    command: tail -f /dev/null
    profiles:
      - donotstart
EOF

docker-compose --profile donotstart up

docker-compose down
docker-compose rm -f

올리고, 내리고, 삭제하고..

해당 폴더에 yml 파일을 만드는 예제란다.

간단 설명
user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ echo "asd
> bb\"b" > c.txt

## " 넣을라면 \" 해야하는데 귀찮으니
## 그냥 EOF 구문으로 그 사이를 그냥 모두 문자로 취급하는 것. 별거아니였네.

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ cat > b.txt<<EOF
> aaa
> bb"b
> EOF

 

위 비동기 방식 이론..

slave에서 log_slave_updates 파라미터가 활성화(ON) 하게 되면 자신의 Binlog 에도 기록하게되어 A->B->C 형태로 중간의 B 인 Slave 서버가 C의 Master 역할도 수행가능..

= 2단,,3단으로 slave를 구성할 수 있다는 뜻임.

 

 

MySql Replication : 반동기

 

semi-sync : slave에 전달만 되면 Commit 하는 방식

동기는 이해했지? 까지 기다린다면 반동기는 들었지? 까지만 하니까 좀 더 빠르다

 

참고!

캐리지리턴이 window와 linux가 다른데, 이걸 git clone 시 자동으로 바꾸기도 함. 이걸 설정하는 방법이 있음.

git config --global core.autocrlf false
git config --global core.eol lf

LF 로 지정했음.

요런식~
user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test
$ git config --global core.autocrlf false
git config --global core.eol lf

 

강사님 깃을 clone 받았다 내 로컬로..

user@DESKTOP-FSLB27A MINGW64 ~/Desktop/test/MySqlHaCourse/2.MySQL_Replication/4.MySQL_ReplicationWithDockerCompose (main)
$ ls
docker-compose.yml  share/

 

docker 		-> 		docker-compose 		-> 		kubernetes

1개의 container 1대의 서버 -> 여러개 container 1대의 서버 -> 여러개 container 여러대의 서버

 

파워쉘에서 강사님 코드를 받은 후 docker-compose.yml 파일이 있는 경로로 가서 docker-compose up  하면 실행 끜!

 

Transaction..

Master의 TEST 스키마에 x 테이블 생성하고..

데이터를 막 복사해봤다.

그리고 transaction을 열어서 slave와의 동기화 시간 등을 체크해본다.

 

데이터를 마스터에서 막 넣어보고 동시 시간에 master와 slave에서 count(*) 해보자

좌측이 master, 우측이 slave 동시에 카운트를 해봤으나 아직! slave에는 동기화가 안됬따.

 

 

3.MySQL_ReplicationAdvanced/2.MySqlReplication_Semi-sync 실습

 

기존것 다 지우고..
user@DESKTOP-FSLB27A MINGW64 ~
$ docker rm -f slave1 slave2 master
slave1
slave2
master

## mysql 이미지 풀은 생략..
## docker pull mysql/mysql-server:tag 

## 네트워크도 이미 있으니 생략..
## docker network create replicanet

## master slave1 slave2 컨테이너 생성
user@DESKTOP-FSLB27A MINGW64 ~
$ docker run -d --rm --name=master --net=replicanet --hostname=master \
 -e MYSQL_ROOT_PASSWORD=mypass \
  mysql:5.7 \
  --server-id=1 \
  --log-bin='mysql-bin-1.log'

docker run -d --rm --name=slave1 --net=replicanet --hostname=slave1 \
   -e MYSQL_ROOT_PASSWORD=mypass \
  mysql:5.7 \
  --server-id=2

docker run -d --rm --name=slave2 --net=replicanet --hostname=slave2 \
 -e MYSQL_ROOT_PASSWORD=mypass \
  mysql:5.7 \
  --server-id=3
7c9e80b1f3f9221237a13b8a3227aef4b2ca2cd1b8f2fb20b27d1042446288e5
f028839743cac3cccffab04b34368fffc5ab39b8a014c94b6eb8e927daf9c6c7
875f59ca7b2ca0956e23b07a0abf3fe70d53da40494bc736af0553787da944ac

user@DESKTOP-FSLB27A MINGW64 ~
$ docker ps -a
CONTAINER ID   IMAGE       COMMAND                   CREATED          STATUS          PORTS                 NAMES
875f59ca7b2c   mysql:5.7   "docker-entrypoint.s…"   13 seconds ago   Up 8 seconds    3306/tcp, 33060/tcp   slave2
f028839743ca   mysql:5.7   "docker-entrypoint.s…"   17 seconds ago   Up 14 seconds   3306/tcp, 33060/tcp   slave1
7c9e80b1f3f9   mysql:5.7   "docker-entrypoint.s…"   20 seconds ago   Up 18 seconds   3306/tcp, 33060/tcp   master

## Master mysql에 semi-sync 생성하기
user@DESKTOP-FSLB27A MINGW64 ~
$ docker exec -it master mysql -uroot -pmypass \
  -e "INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';" \
  -e "SET GLOBAL rpl_semi_sync_master_enabled = 1;" \
  -e "SET GLOBAL rpl_semi_sync_master_wait_for_slave_count = 2;" \
  -e "SHOW VARIABLES LIKE 'rpl_semi_sync%';"
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug master
  Learn more at https://docs.docker.com/go/debug-cli/

## 아직 mysql 설치가 덜됬네 이 똥 . 컴 . 기다리자
user@DESKTOP-FSLB27A MINGW64 ~
$ docker exec -it master mysql -uroot -pmypass \
  -e "INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';" \
  -e "SET GLOBAL rpl_semi_sync_master_enabled = 1;" \
  -e "SET GLOBAL rpl_semi_sync_master_wait_for_slave_count = 2;" \
  -e "SHOW VARIABLES LIKE 'rpl_semi_sync%';"
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug master
  Learn more at https://docs.docker.com/go/debug-cli/
user@DESKTOP-FSLB27A MINGW64 ~
$ docker exec -it master mysql -uroot -pmypass \
  -e "CREATE USER 'repl'@'%' IDENTIFIED BY 'slavepass';" \
  -e "GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';" \
  -e "SHOW MASTER STATUS;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+----------+--------------+------------------+-------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------------+----------+--------------+------------------+-------------------+
| mysql-bin-1.000003 |      595 |              |                  |                   |
+--------------------+----------+--------------+------------------+-------------------+

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug master
  Learn more at https://docs.docker.com/go/debug-cli/


## slave 노드에도 지정
user@DESKTOP-FSLB27A MINGW64 ~
$ for N in 1 2
  do docker exec -it slave$N mysql -uroot -pmypass \
    -e "INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';" \
    -e "SET GLOBAL rpl_semi_sync_slave_enabled = 1;" \
    -e "SHOW VARIABLES LIKE 'rpl_semi_sync%';"
done
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug slave1
  Learn more at https://docs.docker.com/go/debug-cli/
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug slave2
  Learn more at https://docs.docker.com/go/debug-cli/


## replication co-ordinate를 변경
user@DESKTOP-FSLB27A MINGW64 ~
$ for N in 1 2
  do docker exec -it slave$N mysql -uroot -pmypass \
    -e "CHANGE MASTER TO MASTER_HOST='master', MASTER_USER='repl', \
      MASTER_PASSWORD='slavepass', MASTER_LOG_FILE='mysql-bin-1.000003';"

  docker exec -it slave$N mysql -uroot -pmypass -e "START SLAVE;"
done
mysql: [Warning] Using a password on the command line interface can be insecure.

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug slave1
  Learn more at https://docs.docker.com/go/debug-cli/
mysql: [Warning] Using a password on the command line interface can be insecure.

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug slave1
  Learn more at https://docs.docker.com/go/debug-cli/
mysql: [Warning] Using a password on the command line interface can be insecure.

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug slave2
  Learn more at https://docs.docker.com/go/debug-cli/
mysql: [Warning] Using a password on the command line interface can be insecure.

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug slave2
  Learn more at https://docs.docker.com/go/debug-cli/


## TEST 스키마 생성
user@DESKTOP-FSLB27A MINGW64 ~
$ docker exec -it master mysql -uroot -pmypass -e "CREATE DATABASE TEST; SHOW DATABASES;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database           |
+--------------------+
| information_schema |
| TEST               |
| mysql              |
| performance_schema |
| sys                |
+--------------------+


## slave에도 생성됬는지 확인
user@DESKTOP-FSLB27A MINGW64 ~
$ for N in 1 2
  do docker exec -it slave$N mysql -uroot -pmypass \
  -e "SHOW VARIABLES WHERE Variable_name = 'hostname';" \
  -e "SHOW DATABASES;"
done
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| hostname      | slave1 |
+---------------+--------+
+--------------------+
| Database           |
+--------------------+
| information_schema |
| TEST               |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

What's next?
  Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug slave1
  Learn more at https://docs.docker.com/go/debug-cli/
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| hostname      | slave2 |
+---------------+--------+
+--------------------+
| Database           |
+--------------------+
| information_schema |
| TEST               |
| mysql              |
| performance_schema |
| sys                |
+--------------------+


## master에 100만개 정도 입력해보고 응답 얼마나 늦는지 확인.
## 은 알아서~

 

응답시간 테스트

## 마스터에선 start transaction; 이후 insert 갈기자

## 마스터
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into x select * from x;
Query OK, 524288 rows affected (2.98 sec)
Records: 524288  Duplicates: 0  Warnings: 0

mysql> insert into x select * from x;
Query OK, 1048576 rows affected (4.68 sec)
Records: 1048576  Duplicates: 0  Warnings: 0

## 대략 200만개 있겠군

## 그시각 slave
mysql> select count(*) from x;
+----------+
| count(*) |
+----------+
|   524288 |
+----------+
1 row in set (0.12 sec)

## slave는 아직 마스터의 transaction이 끝나기 전이니까 그전 undo를 보고있다.

 

mysql 기본 플러그인 설치된 것을 한번 볼까

user@DESKTOP-FSLB27A MINGW64 ~
$ docker exec -it master bash
bash-4.2# ls /usr/lib64/mysql/plugin/
adt_null.so                         group_replication.so  libmemcached.so     mysqlx.so           semisync_slave.so
auth_socket.so                      innodb_engine.so      locking_service.so  rewrite_example.so  validate_password.so
authentication_ldap_sasl_client.so  keyring_file.so       mypluglib.so        rewriter.so         version_token.so
connection_control.so               keyring_udf.so        mysql_no_login.so   semisync_master.so

만약 플러그인을 추가하고 싶으면 여기에 넣어주면 되는 것이다.

 

 

Chap 4. MySql Log Format

로그 복제의 종류!!

 

Statement-based Log

Row-based Log

Mixed replication Log

각각의 차이가 있음.

특히 Statement-based log 방식의 경우 master와 slave의 데이터가 다르면 오작동 발생함.(삭제될 때 삭제되는 대상 데이터가 달라지는 등) : 100만줄 삭제시 slave에는 100만줄삭제 명령 1줄 전달

Row-based log의 경우 오작동은 안하나.. 부담됨. : 100만줄 삭제시 100만줄 전달

따라서 그걸 섞어쓰자가 Mixed replication log~

 

내가 아까 설치한 master DB의 log format은 뭐였을까..

row 였군

 

Statement log방식을 체험해보자

 

 --binlog_format='STATEMENT'; 옵션으로 statement log 방식으로 생성해보자

user@DESKTOP-FSLB27A MINGW64 ~
$ docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=mypass mysql:5.7 --binlog_format='STATEMENT';
f9d3aebdb8d6f0dfab4a0c65aa6025a4c1f37d797e54582f964a8fd2d513c5e8

diff 문을 사용해서(두 파일간의 차이를 출력해주는 리눅스 명령어) 로그파일을 직접 까보고 어떻게 쌓이는 지 보자.

-> (다하고 추가)할려 했는데 뭐 딱히 제대로 볼 수는 없었다.. 그냥 패스..

## binlog_format             | STATEMENT 확인
mysql> show variables like '%format%';
+---------------------------+-------------------+
| Variable_name             | Value             |
+---------------------------+-------------------+
| binlog_format             | STATEMENT         |
| date_format               | %Y-%m-%d          |
| datetime_format           | %Y-%m-%d %H:%i:%s |
| default_week_format       | 0                 |
| innodb_default_row_format | dynamic           |
| innodb_file_format        | Barracuda         |
| innodb_file_format_check  | ON                |
| innodb_file_format_max    | Barracuda         |
| time_format               | %H:%i:%s          |
+---------------------------+-------------------+
9 rows in set (0.01 sec)

데이터 파일이 어딨는지 my.cnf를 뒤져서 찾아보자

## 데이터 파일 위치 찾기

bash-4.2# cat /etc/my.cnf | grep data
# Remove leading # and set to the amount of RAM for the most important data
# Remove leading # to turn on a very important data integrity option: logging
datadir=/var/lib/mysql

## datadir=/var/lib/mysql 요기군

bash-4.2# ls /var/lib/mysql > /a.txt
bash-4.2# ls
a.txt  boot  docker-entrypoint-initdb.d  etc   lib    media  opt   root  sbin  sys  usr
bin    dev   entrypoint.sh               home  lib64  mnt    proc  run   srv   tmp  var
bash-4.2# cat a.txt
auto.cnf
ca-key.pem
ca.pem
client-cert.pem
client-key.pem
ib_buffer_pool
ib_logfile0
ib_logfile1
ibdata1
ibtmp1
mysql
mysql.sock
performance_schema
private_key.pem
public_key.pem
server-cert.pem
server-key.pem
sys
bash-4.2#

##으흠. 일단 a.txt에 복사해놨다.
## 그럼 database TEST를 생성해보고 diff 해볼까
## mysql
mysql> create database TEST;
Query OK, 1 row affected (0.00 sec)

## mysql 설치된 bash
bash-4.2# ls /var/lib/mysql > /b.txt
bash-4.2# diff a.txt b.txt
0a1
> TEST

## TEST가 보이는군. 폴더로.
## 그럼 테이블을 만들어보고 확인해볼까
mysql> create table TEST.x (id int, name varchar(30), date1 date);
Query OK, 0 rows affected (0.51 sec)

bash-4.2# pwd
/var/lib/mysql/TEST
bash-4.2# ls
db.opt  x.frm  x.ibd

## 오호 뭔가 생겼다. x. 어쩌구..
## Database를 생성하면 그게 폴더구만.

 

결론.. HA 모드에서는 무조건 row 모드로 세팅한다. why? 데이터가 다른 문제가 생기는걸 방지!