Raspberry Pi 5 에 MariaDB Galera Cluster 를 구성해 보았습니다.

Galera Cluster는 기본 노드 3개를 권장하고 있어서 라즈베리파이를 3대 준비 했습니다.

 

1. 사전 준비

1.1 Ubuntu 설치된 서버 3대

서두에서 이야기 한 대로 Galera Cluster는 기본 노드 3개를 권장하고 있어서 라즈베리파이 5를 3대 준비 했습니다.

Raspberri Pi Imager 를 이용해 Ubuntu 64bit 최소 설치 했습니다.

상황에 따라 Virtual Box 를 설치하고 필요한 OS를 설치해도 무방 할 것 같습니다.

 

1.2. IP 고정하기

나중에 Cluster 설정 할 때 노드별 IP를 고정 하도록 되어 있기 때문에 고정 IP를 부여해 주는 것이 좋습니다.

  • db1 : 192.168.2.13
  • db2 : 192.168.2.14
  • db3 : 192.168.2.15

Ubuntu 최신 bookworm 에서 IP를 고정 하는 방법은 아래 링크를 참고 하세요.

https://opensrc.tistory.com/251

 

Raspberry Pi OS bookworm 고정 IP 할당 하기

라즈베리파이 OS가 2023년 하반기에 bookworm 버전이 배포 된것 같습니다.네이밍은 토이스토리에서 따온 것이라고 합니다.https://2youngmaan.tistory.com/7 Docker 이미지 종류: Bullseye, Bookworm, Slim의 차이도커

opensrc.tistory.com

 

1.3. 시간 동기화 서버 chrony 설치

서비스를 운영할 때 서버의 시간을 정확하게 유지하는 것 도 중요한 요소 입니다.

특히 여러대의 DB서버를 클러스터링 하는 경우 서버간의 시간 동기화는 필수 입니다.

아래 글을 참고 하시기 바랍니다.

https://opensrc.tistory.com/278

 

[Ubuntu] 시간 동기화 서버 chrony 설치

서버를 이용해 서비스를 하는 경우 시간 동기화를 반드시 해줘야 합니다.시간 동기화를 하지 않는경우 아주 조금씩 시간이 안맞고 이것이 쌓이면 시간이 지날 수록 초, 분 단위까지 실제 시간과

opensrc.tistory.com

 

1.4. Galera Cluster 에서 사용하는 포트 오픈

방화벽이 설정되어 있는 경우 로컬 네트워크에서 3306, 4567, 4568, 4444 포트의 사용을 허용해야 합니다.

Ubuntu 기본 방화벽 ufw 사용 기준 192.168.2.* 에서만 접근 가능하도록 설정 입니다.

$ sudo ufw allow from 192.168.2.0/24 to any port 3306 proto tcp comment 'MariaDB'
$ sudo ufw allow from 192.168.2.0/24 to any port 4567 proto tcp comment 'MariaDB Galera Custer'
$ sudo ufw allow from 192.168.2.0/24 to any port 4567 proto udp comment 'MariaDB Galera Custer'
$ sudo ufw allow from 192.168.2.0/24 to any port 4568 proto tcp comment 'MariaDB Galera Custer'
$ sudo ufw allow from 192.168.2.0/24 to any port 4444 proto tcp comment 'MariaDB Galera Custer'

 

1.5.  MariaDB 저장소 설정 (모든 노드에서 동일하게 수행)

MariaDB , Galera Cluster 를 다운로드 받을 레포지토리를 지정 하는 작업 입니다.

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install software-properties-common dirmngr -y
$ sudo apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc'
$ sudo add-apt-repository 'deb [arch=amd64] http://mariadb.mirror.globo.tech/repo/10.6/ubuntu focal main'
$ sudo apt update

 

 

2. MariaDB + Galera Cluster 패키지 설치

아래 순서대로 패키지를 설치 합니다.

$ sudo apt install mariadb-server galera-4 rsync -y

 

설치 후 MariaDB 상태 확인

$ suso systemctl status mariadb
-bash: suso: command not found
basscraft@db1:~ $ sudo systemctl status mariadb
● mariadb.service - MariaDB 10.11.11 database server
     Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; preset: enabled)
     Active: active (running) since Sun 2025-07-20 12:28:32 BST; 9min ago
       Docs: man:mariadbd(8)
             https://mariadb.com/kb/en/library/systemd/
   Main PID: 18565 (mariadbd)
     Status: "Taking your SQL requests now..."
      Tasks: 8 (limit: 63261)
        CPU: 342ms
     CGroup: /system.slice/mariadb.service
             └─18565 /usr/sbin/mariadbd

Jul 20 12:28:32 db1 mariadbd[18565]: 2025-07-20 12:28:32 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
Jul 20 12:28:32 db1 mariadbd[18565]: 2025-07-20 12:28:32 0 [Note] Plugin 'FEEDBACK' is disabled.
Jul 20 12:28:32 db1 mariadbd[18565]: 2025-07-20 12:28:32 0 [Warning] You need to use --log-bin to make --expire-logs-days or --binlog-expire-logs-seconds work.
Jul 20 12:28:32 db1 mariadbd[18565]: 2025-07-20 12:28:32 0 [Note] Server socket created on IP: '127.0.0.1'.
Jul 20 12:28:32 db1 mariadbd[18565]: 2025-07-20 12:28:32 0 [Note] InnoDB: Buffer pool(s) load completed at 250720 12:28:32
Jul 20 12:28:32 db1 mariadbd[18565]: 2025-07-20 12:28:32 0 [Note] /usr/sbin/mariadbd: ready for connections.
Jul 20 12:28:32 db1 mariadbd[18565]: Version: '10.11.11-MariaDB-0+deb12u1'  socket: '/run/mysqld/mysqld.sock'  port: 3306  Debian 12
Jul 20 12:28:32 db1 systemd[1]: Started mariadb.service - MariaDB 10.11.11 database server.
Jul 20 12:28:32 db1 /etc/mysql/debian-start[18593]: Checking for insecure root accounts.
Jul 20 12:28:32 db1 /etc/mysql/debian-start[18597]: Triggering myisam-recover for all MyISAM tables and aria-recover for all Aria tables
$

 

MariaDB 접속 확인

$ sudo mysql -uroot
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 31
Server version: 10.11.11-MariaDB-0+deb12u1 Debian 12

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> exit
Bye
$

 

3. MariaDB Galera Cluster 설정

Ubuntu 의 경우 root 권한으로 /etc/mysql/mariadb.conf.d/50-server.cnf 에 내용을 수정합니다.

 

노드 별로 모두 수정을 해줘야 합니다.

  • wsrep_cluster_address : 노드에 참여하는 IP 나열
  • wsrep_cluster_name : 클러스터 이름
  • wsrep_node_address : 자기 IP
  • wsrep_node_name : 자기 노드명
$ sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf
... 생략 ...

[mysqld]
... 생략 ...
#bind-address            = 127.0.0.1  # 기존 bind-address 주석 처리
bind-address = 0.0.0.0
binlog_format = row
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
query_cache_size = 0
query_cache_type = 0

# Galera settings
wsrep_on = ON
wsrep_provider = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_address = "gcomm://192.168.2.13,192.168.2.14,192.168.2.15"    # 사용할 노드의 IP를 모두 기술
wsrep_cluster_name = "dev_cluster" # 클러스터 명 지정
wsrep_node_address = "192.168.2.13" # 이 노드의 IP 기입
wsrep_node_name = "node1" # 이 노드의 이름 기입
wsrep_sst_method = rsync

 

4. 클러스터 시작

4.1. 모든 노드가 다운되어 있는 경우

galera cluster 는 첫번째 시작하는 노드는 systemctl start mariadb가 아닌 galera_new_cluster 로 시작해야 합니다.

나머지 노드 들은 systemctl start mariadb 로 시작 하면 됩니다.

mariadb 를 설치하면  재부팅시 systemctl start mariadb 명령으로 자동 실행되게 되어 있기 때문에 모든 노드에서 마리아DB를 수동으로 시작하도록 하는 것이 좋습니다.

 

부팅시 자동 시작 비활성화

$ sudo systemctl disable mariadb

 

재부팅 후 마리아 DB가 자동 시작 되지 않았는지 확인 필요 합니다.

$ sudo systemctl status mariadb
○ mariadb.service - MariaDB 10.11.11 database server
     Loaded: loaded (/lib/systemd/system/mariadb.service; disabled; preset: enabled)
     Active: inactive (dead)
       Docs: man:mariadbd(8)
             https://mariadb.com/kb/en/library/systemd/
$

 

첫번째 노드에서는 sudo galera_new_cluster 로 마리아 DB를 시작 합니다.

$ sudo galera_new_cluster
$ sudo systemctl status mariadb
● mariadb.service - MariaDB 10.11.11 database server
     Loaded: loaded (/lib/systemd/system/mariadb.service; disabled; preset: enabled)
     Active: active (running) since Sun 2025-07-20 13:07:27 BST; 9s ago
       Docs: man:mariadbd(8)
             https://mariadb.com/kb/en/library/systemd/
    Process: 1012 ExecStartPre=/usr/bin/install -m 755 -o mysql -g root -d /var/run/mysqld (code=exited, status=0/SUCCESS)
    Process: 1013 ExecStartPre=/bin/sh -c systemctl unset-environment _WSREP_START_POSITION (code=exited, status=0/SUCCESS)
    Process: 1015 ExecStartPre=/bin/sh -c [ ! -e /usr/bin/galera_recovery ] && VAR= ||   VAR=`/usr/bin/galera_recovery`; [ $? -eq 0 ]   && systemctl set-environment _WSREP_START_POSITION=$VAR || exit 1 (code=>
    Process: 1146 ExecStartPost=/bin/sh -c systemctl unset-environment _WSREP_START_POSITION (code=exited, status=0/SUCCESS)
    Process: 1148 ExecStartPost=/etc/mysql/debian-start (code=exited, status=0/SUCCESS)
   Main PID: 1130 (mariadbd)
     Status: "Taking your SQL requests now..."
      Tasks: 19 (limit: 63261)
        CPU: 537ms
     CGroup: /system.slice/mariadb.service
             └─1130 /usr/sbin/mariadbd --wsrep-new-cluster --wsrep_start_position=00000000-0000-0000-0000-000000000000:-1

Jul 20 13:07:27 db1 mariadbd[1130]: 2025-07-20 13:07:27 0 [Note] /usr/sbin/mariadbd: ready for connections.
Jul 20 13:07:27 db1 mariadbd[1130]: Version: '10.11.11-MariaDB-0+deb12u1'  socket: '/run/mysqld/mysqld.sock'  port: 3306  Debian 12
Jul 20 13:07:27 db1 mariadbd[1130]: 2025-07-20 13:07:27 2 [Note] WSREP: Lowest cert index boundary for CC from group: 1
Jul 20 13:07:27 db1 mariadbd[1130]: 2025-07-20 13:07:27 2 [Note] WSREP: Min available from gcache for CC from group: 1
Jul 20 13:07:27 db1 mariadbd[1130]: 2025-07-20 13:07:27 2 [Note] WSREP: Server node1 synced with group
Jul 20 13:07:27 db1 mariadbd[1130]: 2025-07-20 13:07:27 2 [Note] WSREP: Server status change joined -> synced
Jul 20 13:07:27 db1 mariadbd[1130]: 2025-07-20 13:07:27 2 [Note] WSREP: Synchronized with group, ready for connections
Jul 20 13:07:27 db1 mariadbd[1130]: 2025-07-20 13:07:27 2 [Note] WSREP: wsrep_notify_cmd is not defined, skipping notification.
Jul 20 13:07:27 db1 systemd[1]: Started mariadb.service - MariaDB 10.11.11 database server.
Jul 20 13:07:27 db1 /etc/mysql/debian-start[1150]: Upgrading MySQL tables if necessary.

 

잘 실행 되었으면 두번째 노드 부터는 systemctl start mariadb 로 DB를 시작 합니다.

$ sudo systemctl start mariadb
$ sudo systemctl status mariadb
● mariadb.service - MariaDB 10.11.11 database server
     Loaded: loaded (/lib/systemd/system/mariadb.service; disabled; preset: enabled)
     Active: active (running) since Sun 2025-07-20 13:10:43 BST; 21s ago
       Docs: man:mariadbd(8)
             https://mariadb.com/kb/en/library/systemd/
    Process: 964 ExecStartPre=/usr/bin/install -m 755 -o mysql -g root -d /var/run/mysqld (code=exited, status=0/SUCCESS)
    Process: 965 ExecStartPre=/bin/sh -c systemctl unset-environment _WSREP_START_POSITION (code=exited, status=0/SUCCESS)
    Process: 967 ExecStartPre=/bin/sh -c [ ! -e /usr/bin/galera_recovery ] && VAR= ||   VAR=`/usr/bin/galera_recovery`; [ $? -eq 0 ]   && systemctl set-environment _WSREP_START_POSITION=$VAR || exit 1 (code=exited, status=0/SUCCES>
    Process: 1364 ExecStartPost=/bin/sh -c systemctl unset-environment _WSREP_START_POSITION (code=exited, status=0/SUCCESS)
    Process: 1366 ExecStartPost=/etc/mysql/debian-start (code=exited, status=0/SUCCESS)
   Main PID: 1083 (mariadbd)
     Status: "Taking your SQL requests now..."
      Tasks: 18 (limit: 63261)
        CPU: 1.304s
     CGroup: /system.slice/mariadb.service
             └─1083 /usr/sbin/mariadbd --wsrep_start_position=00000000-0000-0000-0000-000000000000:-1

Jul 20 13:10:52 db2 mariadbd[1083]:   members(3):
Jul 20 13:10:52 db2 mariadbd[1083]:         0: 1a3de79f-6562-11f0-ac2c-265ed7e58674, node1
Jul 20 13:10:52 db2 mariadbd[1083]:         1: 86a8c7dd-6562-11f0-9f4f-dad249e5f6a1, node2
Jul 20 13:10:52 db2 mariadbd[1083]:         2: 944d1a2e-6562-11f0-a120-7302ab878736, node3
Jul 20 13:10:52 db2 mariadbd[1083]: =================================================
Jul 20 13:10:52 db2 mariadbd[1083]: 2025-07-20 13:10:52 2 [Note] WSREP: wsrep_notify_cmd is not defined, skipping notification.
Jul 20 13:10:52 db2 mariadbd[1083]: 2025-07-20 13:10:52 2 [Note] WSREP: Lowest cert index boundary for CC from group: 3
Jul 20 13:10:52 db2 mariadbd[1083]: 2025-07-20 13:10:52 2 [Note] WSREP: Min available from gcache for CC from group: 2
Jul 20 13:10:53 db2 mariadbd[1083]: 2025-07-20 13:10:53 0 [Note] WSREP: Member 2.0 (node3) requested state transfer from '*any*'. Selected 0.0 (node1)(SYNCED) as donor.
Jul 20 13:10:54 db2 mariadbd[1083]: 2025-07-20 13:10:54 0 [Note] WSREP: (86a8c7dd-9f4f, 'tcp://0.0.0.0:4567') turning message relay requesting off
lines 1-27/27 (END)

 

cluster에 싱크를 맞추기 우해 start 명령에 시간이 조금 걸리는 점 참고 하세요.

4.2. 클러스터에 참여하는 노드가 하나라도 실행되고 있는 경우

하나라도 실행되고 있고 노드 하나씩 재시작 하는 경우는 systemctl start/restart mariadb 로 실행하시면 됩니다.

재시작 하고 나면 모든 노드의 클러스터 상태가 정상인지 확인이 필요 합니다.

5. 클러스터 상태 확인

클러스터의 상태를 체크 하는 몇가지 방법이 있지만 마리아DB 콘솔에서 wsrep_로 시작하는 변수의 상태값을 확인해 보는 것이 가장 일반적 입니다.

$ sudo mysql -uroot
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 36
Server version: 10.11.11-MariaDB-0+deb12u1 Debian 12

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show status like 'wsrep_%';
+-------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name                 | Value                                                                                                                                          |
+-------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
... 생략 ...
| wsrep_cluster_size            | 3                                                                                                                                              |
| wsrep_cluster_state_uuid      | 1a3f9a6d-6562-11f0-a28e-c759a5c18b53                                                                                                           |
| wsrep_cluster_status          | Primary                                                                                                                                        |
| wsrep_connected               | ON                                                                                                                                             |
| wsrep_local_bf_aborts         | 0                                                                                                                                              |
| wsrep_local_index             | 0                                                                                                                                              |
| wsrep_provider_capabilities   | :MULTI_MASTER:CERTIFICATION:PARALLEL_APPLYING:TRX_REPLAY:ISOLATION:PAUSE:CAUSAL_READS:INCREMENTAL_WRITESET:UNORDERED:PREORDERED:STREAMING:NBO: |
| wsrep_provider_name           | Galera                                                                                                                                         |
| wsrep_provider_vendor         | Codership Oy <info@codership.com>                                                                                                              |
| wsrep_provider_version        | 4.20(rfed86127)                                                                                                                                |
| wsrep_ready                   | ON                                                                                                                                             |
| wsrep_rollbacker_thread_count | 1                                                                                                                                              |
| wsrep_thread_count            | 2                                                                                                                                              |
+-------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
69 rows in set (0.001 sec)

MariaDB [(none)]>

 

주요 상태 값 입니다.

 

6. 클러스터 동작 확인

node1 에 test 데이터 베이스를 만들고 node2, node3에 제대로 전파가 되는지 확인해 보겠습니다.

node1 콘솔에서 test 데이터베이스 생성

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.000 sec)

MariaDB [(none)]> create database test;
Query OK, 1 row affected (0.022 sec)

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.000 sec)

MariaDB [(none)]>

 

node2, node3 콘솔에서 제대로 전파가 되었는지 확인

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.000 sec)

MariaDB [(none)]>

정상으로 동작하고 있습니다.

 

7. 참고 사항

7.1. DB 접속 분산

Galera Cluster는 참여하는 노드 모두가 Active 상태로 읽기 쓰기를 할 수 있습니다.

다만 Oracle RAC 처럼 대표 IP를 통해 자동으로 분산 시켜주는 기능은 앞단에 ProxySQL 또는 HAProxy + Keepalived 같은 구성이 필요 합니다. 이 부분은 차후에 테스트 해보도록 하겠습니다.

 

7.2. 자동증가 컬럼 충돌 가능성

멀티 마스터로 모든 노드가 Active 상태이기 때문에 자동증가(auto_increment) 컬럼을 사용하는 경우 여러 노드에서 동시에  인서트 하는 순간 충돌이 발생할 가능성이 있습니다.

이를 방지하기 위해 auto_increment_increment + auto_increment_offset 설정을 이용 할 수 있습니다.

노드의 갯수를 지정하고 각 노드별로 offset 값을 노드 번호로 지정하면 됩니다.

 

/etc/mysql/mariadb.conf.d/50-server.conf 에 설정합니다.

[mysqld]
# 공통
auto_increment_increment = 3

# 노드마다 다르게
auto_increment_offset = 1  # Node1
# auto_increment_offset = 2  # Node2
# auto_increment_offset = 3  # Node3

 

설정 후 서버 재시작이 필요 합니다.

 

다만, 이렇게 하는 경우 노드별로 각 배수로 자동 증가값이 설정 되기 때문에  자동증가 값에 이가 빠질 수 밖에 없습니다.

 

다른 방법으로 datasource를 읽기 전용 하나의 노드로 생성해서 INSERT 는 한곳의 노드에서만 하도록 하는 방법도 있습니다.

 

차후에 ProxySQL 과 자동 증가값에 대한 테스트를 진행해 보겠습니다.

 

끝.

 

+ Recent posts