<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Mariadb-Galera-Cluster on K-Life Hack | Systems Architecture &amp; DevOps</title><link>https://klifehack.com/en/tags/mariadb-galera-cluster/</link><description>Recent content in Mariadb-Galera-Cluster on K-Life Hack | Systems Architecture &amp; DevOps</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Mon, 29 Jun 2026 11:53:21 +0900</lastBuildDate><atom:link href="https://klifehack.com/en/tags/mariadb-galera-cluster/index.xml" rel="self" type="application/rss+xml"/><item><title>Quorum Design to Prevent Split-Brain by Expanding MariaDB Galera Cluster from 2 to 3 Nodes</title><link>https://klifehack.com/en/p/galera-cluster-three-node-expansion/</link><pubDate>Mon, 29 Jun 2026 11:53:21 +0900</pubDate><guid>https://klifehack.com/en/p/galera-cluster-three-node-expansion/</guid><description>&lt;h1 id="mariadb-galera-cluster-achieving-high-availability-by-expanding-from-2-to-3-nodes"&gt;MariaDB Galera Cluster: Achieving High Availability by Expanding from 2 to 3 Nodes
&lt;/h1&gt;&lt;p&gt;While multi-master configurations are a powerful approach to ensuring database availability, operations sometimes begin with a 2-node configuration due to insufficient consideration during the design phase. However, a 2-node MariaDB Galera Cluster always carries the risk of the entire cluster stopping writes to prevent split-brain, as neither node can maintain a majority (quorum) when a network partition occurs. To eliminate this availability bottleneck and improve fault tolerance, expanding to a 3-node configuration is essential. This article explains the specific procedures for safely expanding from an existing 2-node configuration to a 3-node configuration and considerations for large-capacity State Snapshot Transfer (SST).&lt;/p&gt;
&lt;h2 id="quorum-design-and-selection-of-sst-method"&gt;Quorum Design and Selection of SST Method
&lt;/h2&gt;&lt;p&gt;Quorum (consensus building) in a Galera Cluster is the foundation for maintaining cluster consistency. In a 2-node configuration, if one node stops or leaves the network, the ratio of the remaining node becomes 50%, failing to satisfy the majority (&amp;gt;50%) requirement. As a result, the &amp;ldquo;Primary Component&amp;rdquo; state is lost, and the database stops accepting queries. Conversely, in a 3-node configuration, even if one node stops, the remaining two nodes (66.7%) can maintain a majority, allowing the service to continue without interruption.&lt;/p&gt;
&lt;p&gt;The process of synchronizing data from an existing node (Donor) to a new node (Joiner) when it joins the cluster is called SST (State Snapshot Transfer). While rsync is a standard file synchronization tool, it results in a &amp;ldquo;cold transfer&amp;rdquo; where table locks occur on the Donor node during synchronization, making it unsuitable for production environments. In contrast, mariabackup is an online backup tool provided by MariaDB that allows for asynchronous transfer with minimal blocking of the Donor node. When synchronizing 1.1 TB of data over a 1 Gbps network bandwidth, even with mariabackup, the synchronization takes approximately 3.5 hours, necessitating prior bandwidth design and the reservation of a time window.&lt;/p&gt;
&lt;h2 id="phase-1-storage-preparation-and-environment-setup"&gt;Phase 1: Storage Preparation and Environment Setup
&lt;/h2&gt;&lt;p&gt;To prepare for database growth, mount /var/lib/mysql to a large-capacity partition (/home/mysql).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo mkdir -p /var/lib/mysql
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo chown mysql:mysql /var/lib/mysql
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo chmod &lt;span style="color:#ae81ff"&gt;750&lt;/span&gt; /var/lib/mysql
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo restorecon -Rv /var/lib/mysql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, execute a bind mount and add the configuration to /etc/fstab so that it is maintained after a reboot.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo mount --bind /home/mysql /var/lib/mysql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Append the following line to the end of /etc/fstab.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/home/mysql /var/lib/mysql none bind 0 0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Verify the mount status.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;df -h /var/lib/mysql
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;findmnt /var/lib/mysql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Execute database initialization and enable the service.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo mariadb-install-db --user&lt;span style="color:#f92672"&gt;=&lt;/span&gt;mysql --datadir&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/var/lib/mysql
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl enable mariadb
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl start mariadb
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Open the following ports in the firewall. Communication must be allowed for 3306 (for client connections), 4567 (TCP/UDP for Galera Cluster replication), 4568 (for IST), and 4444 (for SST).&lt;/p&gt;
&lt;h2 id="phase-2-software-installation-and-cluster-configuration"&gt;Phase 2: Software Installation and Cluster Configuration
&lt;/h2&gt;&lt;p&gt;To maintain consistency within the cluster, use the same MariaDB version (10.11.4 in this environment) on all nodes. Create a dedicated user for SST execution on the existing DB1 and DB2 nodes.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;USER&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;sstuser&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt; IDENTIFIED &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;your_secure_password&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;GRANT&lt;/span&gt; RELOAD, PROCESS, &lt;span style="color:#66d9ef"&gt;LOCK&lt;/span&gt; TABLES, REPLICATION CLIENT &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;.&lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TO&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;sstuser&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;FLUSH &lt;span style="color:#66d9ef"&gt;PRIVILEGES&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Edit /etc/my.cnf.d/server.cnf on all nodes and change the SST method to mariabackup.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;[mariadb]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;wsrep_sst_method&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;mariabackup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;wsrep_sst_auth&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;sstuser:your_secure_password&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To apply the settings, restart the existing DB1 and DB2 nodes one by one in order.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl restart mariadb
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="phase-3-adding-the-third-node-db3"&gt;Phase 3: Adding the Third Node (DB3)
&lt;/h2&gt;&lt;p&gt;Since the new node (DB3) must start SST from a clean state, empty the data directory.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl stop mariadb
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo rm -rf /var/lib/mysql/*
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo chown -R mysql:mysql /var/lib/mysql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Before starting synchronization, verify connectivity for port 4444. Wait on the DB3 (Joiner) side.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install -y nmap-ncat
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;nc -l &lt;span style="color:#ae81ff"&gt;4444&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Send test data from the DB2 (Donor) side.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo test | nc -v &amp;lt;db3_ip_address&amp;gt; &lt;span style="color:#ae81ff"&gt;4444&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once connectivity is confirmed, start the MariaDB service on DB3 to begin synchronization.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl start mariadb
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="phase-4-monitoring-and-troubleshooting"&gt;Phase 4: Monitoring and Troubleshooting
&lt;/h2&gt;&lt;p&gt;During the 1.1 TB data synchronization, the terminal may appear to have stopped responding. Monitor the progress from another session using the following commands. Determine if the synchronization is proceeding normally by monitoring logs and checking for disk capacity increases.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo journalctl -u mariadb.service -n &lt;span style="color:#ae81ff"&gt;300&lt;/span&gt; --no-pager -l
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;```&lt;/span&gt;bash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="troubleshooting"&gt;Troubleshooting
&lt;/h2&gt;&lt;p&gt;⚠️ SST実行時にDonor側で認証エラーが発生する場合、&lt;code&gt;sstuser&lt;/code&gt; のホスト制限や権限付与が正しく認識されていない可能性があります。その場合は、一度ユーザーを削除して再作成します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ローカルソケット経由での接続テストを実行し、認証が正常に通るか確認します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="operational-verifications"&gt;Operational Verifications
&lt;/h2&gt;&lt;p&gt;同期完了後、クラスタのステータスおよびポートのリスン状態を確認します。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="lessons-learned"&gt;Lessons Learned
&lt;/h2&gt;&lt;p&gt;2ノード構成から3ノード構成への拡張により、スプリットブレインのリスクを排除し、クォーラムを維持した高可用性データベース基盤が確立されました。大容量データの同期においては、rsyncによるテーブルロックを避け、mariabackupによるノンブロッキングなSSTを選択することが、本番稼働中のサービス影響を最小限に抑えるための鍵となります。また、ネットワーク帯域とディスクI/Oの監視を並行して行うことで、同期プロセスの異常を早期に検知することが可能になります。&amp;lt;/db3_ip_address&amp;gt;&lt;/p&gt;</description></item></channel></rss>