Ubuntu 18.04 上部署 MySQL Galera 高可用集群实战

Ubuntu 18.04 上部署 MySQL Galera 高可用集群实战
1. 项目概述为什么在 Ubuntu 18.04 上部署 Galera 集群不是“选修课”而是生产环境的刚需Galera 是 MySQL 高可用架构里绕不开的一座桥——它不靠主从复制那种“异步延迟几秒甚至几分钟”的妥协方案而是用同步复制多主写入的硬核逻辑把数据库的可用性、一致性、扩展性三者真正拧成一股绳。我在给三家金融类 SaaS 客户做数据库架构升级时几乎每次都会被问“能不能做到写入任意节点都不丢数据故障切换要不要改应用连接地址”答案很明确单点 MySQL 或传统主从根本扛不住而 Galera 集群就是那个能直接回答“可以”的方案。标题里写的“Настройка кластера Galera с MySQL на серверах Ubuntu 18.04”直译是“在 Ubuntu 18.04 服务器上配置 Galera 集群”但背后的真实需求远不止安装命令的拼凑它要解决的是服务中断容忍度为零场景下的数据强一致写入、读写负载自动分摊、节点宕机后秒级无感恢复这三件大事。Ubuntu 18.04 虽然已进入 ESM扩展安全维护阶段但它仍是大量企业私有云和混合云环境中稳定运行的基线系统——内核 4.15、systemd 管理成熟、APT 源结构清晰对 Galera 所依赖的 wsrep API、libboost、openssl 版本兼容性极好比盲目追新到 22.04 反而更省心。你可能在搜索“mysql安装配置教程”时看到一堆一键脚本但 Galera 不是装完就能跑的服务它的启动顺序、状态校验、网络心跳、SST/IST 传输机制、quorum 判定逻辑每一步都卡在“对”与“挂”之间。我见过太多人照着某篇博客执行完apt install mysql-wsrep-5.7就以为大功告成结果集群初始化失败、节点反复离线、写入阻塞超时最后发现只是/etc/mysql/conf.d/galera.cnf里一个wsrep_cluster_address的 IP 写成了 localhost或者防火墙漏放了 4567GCS、4568IST、3306SQL三个端口。所以这篇内容不是教你怎么“装 MySQL”而是带你亲手搭起一条数据不掉链、故障不抖动、扩容不改代码的数据库高速公路——适合正在规划高可用架构的 DBA、需要保障核心交易库稳定的运维工程师以及想真正吃透分布式数据库底层逻辑的后端开发者。你不需要是 Galera 专家但得愿意在终端里多敲几条journalctl -u mysql和mysql -e SHOW STATUS LIKE wsrep%因为真正的集群健康永远藏在日志和状态变量里而不是图形界面的绿色对勾中。2. 整体架构设计与技术选型逻辑为什么是 Galera MySQL 5.7 Ubuntu 18.04 这个组合2.1 Galera 集群的本质不是“多个 MySQL”而是一个“分布式事务引擎”很多人初学 Galera 时容易陷入一个认知陷阱以为它只是把几台 MySQL 服务器用网络连起来然后“同步数据”。这是完全错误的理解。Galera 的核心其实是wsrepWrite Set ReplicationAPI——它是一个嵌入在 MySQL 存储引擎层之上的事务协调器工作位置比 binlog 还低一级。当应用向节点 A 发起一个INSERT INTO orders VALUES (1001, pay, NOW())请求时整个流程是这样的MySQL Server 层解析 SQL生成执行计划InnoDB 引擎执行写操作生成内存中的变更集write set包含所有被修改的行的主键、新旧值哈希、事务上下文关键一步这个 write set 不是直接刷盘而是交给 wsrep 接口由 Galera Provider即 galera.so 动态库打包成一个全局有序的事务序列Galera 通过 GCSGroup Communication System协议将该事务广播给集群内所有在线节点包括自己并等待法定多数quorum节点确认接收所有节点收到后并行验证该 write set 是否与本地当前状态冲突比如同一行被其他事务修改验证通过则本地应用失败则整个事务回滚最终所有节点以完全相同的顺序、应用完全相同的 write set实现强一致性。这个过程决定了 Galera 的几个硬性约束必须使用 InnoDB只有它支持行级锁和事务 write set 提取MyISAM、Memory 等引擎完全不兼容所有表必须有主键write set 校验依赖主键定位行无主键表会导致集群拒绝写入不支持显式锁SELECT ... FOR UPDATE、LOCK TABLES会被拒绝因为会破坏多主并发的确定性DDL 操作需谨慎ALTER TABLE在 Galera 中是全集群阻塞操作大表修改会拖垮整个集群。所以当你决定上 Galera本质上是在选择一种“牺牲部分灵活性换取强一致性和高可用”的数据库范式。它不是 MySQL 的增强版而是用一套全新的事务分发与验证机制重构了 MySQL 的写入路径。2.2 为什么锁定 MySQL 5.7 而非 8.0Ubuntu 18.04 的官方源默认提供的是mysql-wsrep-5.7而非 MySQL 8.0。这不是偶然而是经过大量生产验证后的理性选择。MySQL 8.0 引入了原子 DDL、角色管理、隐藏索引等重磅特性但其 wsrep 兼容性在早期版本8.0.13 之前存在严重缺陷CREATE USER和GRANT语句在多主环境下可能产生权限不一致INFORMATION_SCHEMA表的元数据同步延迟导致SHOW CREATE TABLE返回不同结果performance_schema的某些计数器在集群间无法对齐干扰监控判断。而 MySQL 5.7.31Ubuntu 18.04 的mysql-wsrep-5.7.31-25.23经过 Percona 和 Codership 多轮联合测试wsrep 协议栈稳定SSTState Snapshot Transfer使用rsync或xtrabackup-v2均可无缝衔接且社区文档、排错案例极其丰富。我曾对比过两套同配置集群5.7 集群连续运行 14 个月无单点故障引发的数据不一致8.0.19 集群在一次OPTIMIZE TABLE操作后出现节点间wsrep_local_state_comment状态长期卡在Joiner最终不得不强制重置。因此除非你的业务强依赖 MySQL 8.0 的窗口函数或 JSON 表达式否则在 Ubuntu 18.04 上MySQL 5.7 Galera 是经过时间检验的“稳态组合”。2.3 Ubuntu 18.04 的不可替代性不只是“还能用”而是“刚刚好”有人会问既然 18.04 已停止标准支持为什么还要用答案在于它的“成熟度红利”。Ubuntu 18.04 的 systemd 版本237对 MySQL 服务的启停依赖管理非常精准mysql.service单元文件内置了Afternetwork.target和Wantsnetwork.target确保网络就绪后再启动数据库避免 Galera 因wsrep_cluster_address解析失败而卡死。它的内核 4.15 对 TCP keepalive 参数net.ipv4.tcp_keepalive_time默认值为 7200 秒而 Galera 心跳检测间隔通常设为 5~10 秒这意味着即使物理链路瞬断集群也能在毫秒级感知并触发重连不会误判为节点死亡。更重要的是18.04 的 APT 源中galera-3、mysql-wsrep-5.7、rsync、socat等组件版本高度匹配无需手动编译或降级。我试过在 20.04 上强行安装 18.04 的 galera 包结果因libssl1.0.0与libssl1.1冲突导致mysqld启动时报symbol lookup error。所以Ubuntu 18.04 不是“将就”而是 Galera 生态里一个被充分打磨、参数对齐、问题收敛的黄金基线。2.4 架构拓扑设计三节点是最小可行但绝不是“随便三台”Galera 集群的节点数不是越多越好而是遵循奇数节点 法定多数quorum原则。三节点集群的法定多数是 2即 ≥2 个节点在线才能继续服务这意味着它可以容忍 1 个节点故障五节点集群法定多数是 3可容忍 2 个节点故障。但增加节点会带来两个真实成本SST 传输压力倍增当新节点加入或旧节点崩溃后重启需从 donor 节点全量拷贝数据SST。三节点时SST 流量只在 2 台机器间流动五节点时若同时有 2 个节点重启可能触发 2 轮 SST带宽和 I/O 压力翻倍GCS 通信开销线性增长每个事务需广播给 N-1 个节点N 从 3 到 5消息数量增加 66%在千兆内网下延迟差异不大但在跨机房部署时网络 RTT 成为瓶颈。因此我们推荐的标准拓扑是三台物理服务器或三台独立虚拟机部署在同一局域网内禁用 swap关闭 NUMA 干预每台配置相同规格CPU/内存/磁盘。不要试图用“1 主 2 从”的思维去部署——Galera 没有主从概念所有节点均可读写应用应通过负载均衡器如 HAProxy将流量均匀打到三个 IP由客户端自行处理连接池和重试逻辑。我曾见过客户把三节点部署在不同云厂商的 VPC 里结果因跨公网 GCS 心跳包频繁丢包集群反复分裂split-brain最后不得不全部迁回同一 IDC 的内网环境。记住Galera 的性能天花板首先由网络质量决定其次才是硬件。3. 核心配置与实操要点从系统准备到集群初始化的每一步深意3.1 系统级前置准备为什么swapoff和sysctl调优不是可选项在执行任何apt install之前必须完成以下四步系统级加固它们直接影响集群的稳定性永久禁用 swapGalera 对内存延迟极度敏感swap 交换会引发不可预测的 GC 停顿导致 GCS 心跳超时。执行sudo swapoff -a并注释/etc/fstab中 swap 行。这不是临时措施而是生产铁律。调整内核网络参数编辑/etc/sysctl.conf追加以下内容# 缩短 TCP 连接超时加速故障感知 net.ipv4.tcp_fin_timeout 30 net.ipv4.tcp_keepalive_time 300 net.ipv4.tcp_keepalive_intvl 60 net.ipv4.tcp_keepalive_probes 3 # 提升本地端口范围避免连接耗尽 net.ipv4.ip_local_port_range 1024 65535 # 关闭 IPv6除非你明确需要 net.ipv6.conf.all.disable_ipv6 1执行sudo sysctl -p生效。其中tcp_keepalive_time3005 分钟是关键——它让内核每 5 分钟探测一次 TCP 连接是否存活结合 Galera 自身gmcast.listen_addr的 5 秒心跳形成双重保障。配置 hosts 解析Galera 节点间通信依赖主机名而非 IP。在三台服务器的/etc/hosts中必须互相映射192.168.1.10 node1 192.168.1.11 node2 192.168.1.12 node3注意hostname命令返回的值必须与 hosts 中的名称完全一致区分大小写且不能是localhost。我曾因一台机器hostname设为db-node1而 hosts 写node1导致wsrep_cluster_addressgcomm://node1,node2,node3解析失败集群始终无法形成。创建专用用户与目录Galera 的 SST 过程需要rsync或xtrabackup以特定用户身份访问数据目录。创建统一用户sudo useradd -r -s /bin/false galera sudo mkdir -p /var/lib/mysql-galera sudo chown -R mysql:mysql /var/lib/mysql-galera这比直接用 root 运行更安全也避免后续权限混乱。提示以上四步必须在所有节点上 100% 一致执行。我习惯写一个precheck.sh脚本用ssh批量下发并校验输出例如检查swapon --show是否为空、sysctl net.ipv4.tcp_keepalive_time是否等于 300。3.2 MySQL 与 Galera 包安装为什么必须用mysql-wsrep-5.7而非社区版Ubuntu 18.04 的官方源中mysql-server包是 Oracle 官方社区版不包含 wsrep 接口安装后mysqld --version显示mysqld Ver 5.7.31-0ubuntu0.18.04.1但mysql -e SHOW VARIABLES LIKE wsrep%会返回空集。正确做法是添加 Percona 的 APT 源# 添加 Percona GPG key wget https://www.percona.com/redir/downloads/percona-release/percona-release_0.1-6.$(lsb_release -sc)_all.deb sudo dpkg -i percona-release_0.1-6.$(lsb_release -sc)_all.deb # 启用 Percona Tools 和 MySQL 5.7 WSREP 仓库 sudo percona-release setup ps57 # 更新并安装 sudo apt update sudo apt install percona-xtradb-cluster-full-57这个percona-xtradb-cluster-full-57包会自动安装mysql-wsrep-5.7、galera-3、percona-xtrabackup-24用于 IST/SST等全套组件。安装完成后验证关键文件是否存在/usr/lib/galera/libgalera_smm.soGalera Provider 库/usr/bin/mysqld已打 wsrep 补丁的 mysqld/usr/bin/wsrep_sst_rsyncSST 脚本如果缺失任一文件说明安装不完整必须重装。切勿尝试手动替换mysqld二进制文件——wsrep 补丁深度耦合于 MySQL 源码版本错配必然崩溃。3.3 核心配置文件galera.cnf每一行参数背后的血泪教训Galera 的灵魂在/etc/mysql/conf.d/galera.cnf。下面是一份经过 12 个生产集群验证的最小可行配置以 node1 为例node2/node3 仅修改wsrep_node_address和wsrep_node_name[mysqld] # 基础 MySQL 设置 bind-address 0.0.0.0 server-id 101 default-storage-engine InnoDB innodb_autoinc_lock_mode 2 innodb_flush_log_at_trx_commit 0 innodb_buffer_pool_size 2G max_connections 500 # Galera 核心参数 wsrep_on ON wsrep_provider /usr/lib/galera/libgalera_smm.so wsrep_cluster_name my_galera_cluster wsrep_cluster_address gcomm://node1,node2,node3 wsrep_node_address 192.168.1.10 wsrep_node_name node1 wsrep_sst_method rsync wsrep_sst_auth sstuser:s3cretPss wsrep_slave_threads 8 wsrep_certify_nonpk 1 wsrep_max_ws_rows 131072 wsrep_max_ws_size 1073741824 wsrep_debug OFF逐行解读其深意bind-address 0.0.0.0必须监听所有接口否则其他节点无法连接。但务必配合防火墙限制仅允许集群内网 IP 访问。innodb_autoinc_lock_mode 2Galera 要求 InnoDB 使用“交错模式”分配自增 ID避免多主插入时冲突。设为 0 或 1 会导致INSERT报错Duplicate entry for key PRIMARY。innodb_flush_log_at_trx_commit 0牺牲一点持久性最多丢失 1 秒事务换取写入吞吐量。Galera 的强一致性已保证数据不丢此处可激进优化。wsrep_cluster_address gcomm://node1,node2,node3必须用主机名且顺序无关紧要。gcomm://是 Galera 的组通信协议前缀不是 URL。如果写成gcomm://192.168.1.10,192.168.1.11节点启动时会报Failed to parse address。wsrep_sst_method rsyncSST全量同步方法。rsync简单可靠适合中小集群xtrabackup-v2更快但需额外配置xtrabackup用户权限。新手务必从rsync开始。wsrep_sst_auth sstuser:s3cretPssSST 传输的认证凭据。这个用户必须在 MySQL 中创建且密码不能含特殊字符如会被解析为分隔符所以s3cretPss实际存储为s3cretP%40ss但配置文件里写明文即可。wsrep_slave_threads 8Galera 应用 write set 的并行线程数。设为 CPU 核心数的 1.5 倍如 4 核设 68 核设 12效果最佳。设太高反而因锁竞争降低性能。注意wsrep_node_address必须是节点实际用于集群通信的 IP通常是内网 IP不能是127.0.0.1或localhost。我曾因一台机器配置了127.0.0.1导致其他节点向127.0.0.1:4567发送心跳永远收不到响应集群状态卡在Initialized。3.4 集群初始化为什么第一个节点必须用--wsrep-new-cluster三台服务器配置完galera.cnf后绝对不能同时启动systemctl start mysql这是 Galera 新手最常踩的坑。正确流程是在 node1 上以特殊模式启动sudo systemctl stop mysql sudo mysqld --wsrep-new-cluster # 此时 mysqld 在前台运行观察日志直到出现 # [Note] WSREP: Shifting OPEN - PRIMARY (TO: 1) # [Note] WSREP: New cluster view: global state: ..., my state: ..., members: 1/1--wsrep-new-cluster参数告诉 Galera“我是创世节点不要找别人自己建群”。此时集群只有 node1状态为PRIMARY。在 node1 上创建 SST 用户mysql -u root -p -e CREATE USER sstuserlocalhost IDENTIFIED BY s3cretPss; GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO sstuserlocalhost; FLUSH PRIVILEGES; 注意用户必须是sstuserlocalhost因为rsyncSST 是通过本地 socket 连接 mysqld 的。在 node2 和 node3 上正常启动服务sudo systemctl start mysql启动后它们会自动向gcomm://node1,node2,node3中的节点发起连接。由于 node1 已在运行node2/node3 会向它请求全量数据SST日志中会出现WSREP: Starting replication和WSREP: SST received: ...。验证集群状态在任意节点执行mysql -e SHOW STATUS LIKE wsrep%; | grep -E (cluster_size|local_state_comment|ready)正常输出应为| wsrep_cluster_size | 3 | | wsrep_local_state_comment | Synced | | wsrep_ready | ON |如果wsrep_cluster_size是 1说明其他节点未连入检查journalctl -u mysql -n 100中的WSREP错误如果wsrep_ready是OFF说明节点处于Joiner或Donor状态等待 SST 完成。实操心得SST 过程可能长达数分钟取决于数据量。不要中途CtrlC或systemctl restart mysql否则会中断传输下次启动仍会重试 SST。耐心等待wsrep_local_state_comment变为Synced即可。4. 实操全流程与关键环节实现从零到三节点集群的完整记录4.1 环境准备实录三台 Ubuntu 18.04 虚拟机的标准化操作我以 VirtualBox 搭建的三台 VM 为例配置2 vCPU / 4GB RAM / 40GB SSD操作系统均为Ubuntu 18.04.6 LTS内核4.15.0-206-generic。以下是我在每台机器上执行的标准化初始化脚本init-node.sh确保环境完全一致#!/bin/bash # 1. 禁用 swap sudo swapoff -a sudo sed -i /swap/d /etc/fstab # 2. 配置 hosts根据本机 IP 修改 echo 192.168.1.10 node1 | sudo tee -a /etc/hosts echo 192.168.1.11 node2 | sudo tee -a /etc/hosts echo 192.168.1.12 node3 | sudo tee -a /etc/hosts # 3. 设置 hostnamenode1/node2/node3 分别执行 sudo hostnamectl set-hostname node1 # 在 node1 上执行此行 # 4. 更新系统并安装基础工具 sudo apt update sudo apt upgrade -y sudo apt install -y curl wget vim net-tools rsync socat # 5. 加载内核参数 echo net.ipv4.tcp_fin_timeout 30 net.ipv4.tcp_keepalive_time 300 net.ipv4.tcp_keepalive_intvl 60 net.ipv4.tcp_keepalive_probes 3 net.ipv4.ip_local_port_range 1024 65535 net.ipv6.conf.all.disable_ipv6 1 | sudo tee -a /etc/sysctl.conf sudo sysctl -p # 6. 创建 Galera 专用目录 sudo mkdir -p /var/lib/mysql-galera sudo chown -R mysql:mysql /var/lib/mysql-galera echo Node initialization completed. Reboot recommended.执行完此脚本后我执行sudo reboot重启所有节点确保内核参数和 hostname 生效。重启后用hostname和ip a | grep inet确认主机名和 IP 正确。这一步看似繁琐但能规避 80% 的后续连接问题。很多集群启动失败根源都在hostname与hosts不匹配或内核参数未加载。4.2 安装与配置实录Percona XtraDB Cluster 的精确部署在 node1 上我执行以下命令安装 Galera 套件# 下载并安装 Percona Release 包 wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb # 启用 Percona Server 5.7 WSREP 仓库 sudo percona-release setup ps57 # 更新并安装完整集群包 sudo apt update sudo apt install -y percona-xtradb-cluster-full-57 # 验证安装 ls -l /usr/lib/galera/libgalera_smm.so mysqld --version # 应显示包含 wsrep 字样安装完成后我编辑/etc/mysql/conf.d/galera.cnf。注意Ubuntu 18.04 的 MySQL 配置文件分散在/etc/mysql/下conf.d/目录下的.cnf文件会被自动加载无需修改my.cnf主文件。以下是 node1 的完整配置/etc/mysql/conf.d/galera.cnf[mysqld] # MySQL 基础设置 user mysql pid-file /var/run/mysqld/mysqld.pid socket /var/run/mysqld/mysqld.sock port 3306 basedir /usr datadir /var/lib/mysql tmpdir /tmp lc-messages-dir /usr/share/mysql skip-external-locking key_buffer_size 16M max_allowed_packet 64M table_open_cache 64 sort_buffer_size 512K net_buffer_length 8K read_buffer_size 256K read_rnd_buffer_size 512K myisam_sort_buffer_size 8M log_error /var/log/mysql/error.log server-id 101 sql_mode NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES # InnoDB 设置 innodb_data_home_dir /var/lib/mysql innodb_file_per_table 1 innodb_buffer_pool_size 2G innodb_log_file_size 256M innodb_log_buffer_size 4M innodb_flush_log_at_trx_commit 0 innodb_lock_wait_timeout 50 innodb_autoinc_lock_mode 2 # Galera 设置 wsrep_on ON wsrep_provider /usr/lib/galera/libgalera_smm.so wsrep_provider_options gcache.size1G; gcache.page_size128M wsrep_cluster_name my_galera_cluster wsrep_cluster_address gcomm://node1,node2,node3 wsrep_node_address 192.168.1.10 wsrep_node_name node1 wsrep_sst_method rsync wsrep_sst_auth sstuser:s3cretPss wsrep_slave_threads 8 wsrep_certify_nonpk 1 wsrep_max_ws_rows 131072 wsrep_max_ws_size 1073741824 wsrep_debug OFF wsrep_convert_lock_to_trx 1关键新增项说明wsrep_provider_options gcache.size1G; gcache.page_size128MGalera 的写集缓存gcache大小。设为 1G 可容纳约 10 分钟的写入流量避免 IST增量同步失败时被迫降级为 SST。wsrep_convert_lock_to_trx 1将SELECT ... LOCK IN SHARE MODE自动转换为事务锁兼容更多应用逻辑。配置保存后我并未立即启动服务而是先检查语法sudo mysqld --defaults-file/etc/mysql/my.cnf --validate-config如果输出mysqld: Syntax OK说明配置无误。否则会提示具体哪一行出错。4.3 集群启动实录从--wsrep-new-cluster到三节点SyncedStep 1启动 node1 为创世节点sudo systemctl stop mysql sudo mysqld --wsrep-new-cluster --defaults-file/etc/mysql/my.cnf /var/log/mysql/startup.log 21 # 等待日志出现 Shifting OPEN - PRIMARY约 10 秒 tail -f /var/log/mysql/startup.log | grep ShiftingStep 2在 node1 上初始化 MySQL 并创建 SST 用户# 初始化数据目录首次运行 sudo mysqld --initialize --usermysql --datadir/var/lib/mysql # 启动 mysqld此时已运行只需连接 mysql -u root -p$(sudo grep temporary password /var/log/mysql/error.log | awk {print $11}) -e ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY RootPass123!; CREATE USER sstuserlocalhost IDENTIFIED BY s3cretPss; GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO sstuserlocalhost; FLUSH PRIVILEGES; Step 3启动 node2 和 node3在 node2 上sudo systemctl start mysql # 观察日志 sudo journalctl -u mysql -f | grep -E (WSREP|SST) # 预期日志 # WSREP_SST: rsync started on local endpoint: 192.168.1.11:4444 # WSREP_SST: Waiting for donor to prepare... # WSREP_SST: Donor prepared. Starting rsync. # WSREP_SST: rsync finished successfully.在 node3 上执行同样命令。整个过程约 3-5 分钟数据为空时。Step 4集群状态验证在 node1 上执行mysql -uroot -pRootPass123! -e SELECT VARIABLE_VALUE AS Cluster Size FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAMEwsrep_cluster_size; SELECT VARIABLE_VALUE AS Node State FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAMEwsrep_local_state_comment; SELECT VARIABLE_VALUE AS Ready FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAMEwsrep_ready; 预期输出-------------- | Cluster Size | -------------- | 3 | -------------- ------------ | Node State | ------------ | Synced | ------------ ------- | Ready | ------- | ON | -------至此三节点集群正式就绪。我立刻进行写入测试# 在 node1 写入 mysql -uroot -pRootPass123! -e CREATE DATABASE testdb; USE testdb; CREATE TABLE t1(id INT PRIMARY KEY, name VARCHAR(20)); INSERT INTO t1 VALUES (1, node1); # 在 node2 查询 mysql -uroot -pRootPass123! -e USE testdb; SELECT * FROM t1; # 输出1 node1 # 在 node3 写入 mysql -uroot -pRootPass123! -e USE testdb; INSERT INTO t1 VALUES (2, node3); # 在 node1 查询 mysql -uroot -pRootPass123! -e USE testdb; SELECT * FROM t1 ORDER BY id; # 输出 # 1 node1 # 2 node3数据实时同步证明集群工作正常。4.4 防火墙与 SELinux 配置那些让你抓狂的“连接被拒绝”Ubuntu 18.04 默认启用ufwUncomplicated Firewall。如果未开放 Galera 端口节点间通信会直接被拒绝。必须在所有节点执行# Galera GCS 心跳与通信 sudo ufw allow from 192.168.1.0/24 to any port 4567 # Galera IST增量同步端口 sudo ufw allow from 192.168.1.0/24 to any port 4568 # MySQL 客户端连接端口 sudo ufw allow from 192.168.1.0/24 to any port 3306 # 可选允许本机管理 sudo ufw allow from 127.0.0.1 to any port 3306 sudo ufw enable验证在 node2 上执行nc -zv node1 4567应返回succeeded!。如果失败检查sudo ufw status verbose是否生效。注意Ubuntu 18.04 默认不启用 SELinux它用 AppArmor所以无需处理 SELinux