点击上方“IT那活儿”公众号,关注后了解更多内容,不管IT什么活儿,干就完了!!!
Galera是一个MySQL(也支持MariaDB,Percona)的同步多主集群软件。
优点:
1)真正的多主模式(True Multi-master) 意味着你可以在任意节点读写,适度的规模可以提高集群整体的性能。不会出现主从模式的故障转移(Master-Slave Failover)操作,也不需要 VIP。 2)同步复制(Synchronous Replication) 意味着没有 slave lag,没有节点 crash 的时候出现的丢数据现象(Hot Standby)。 并且是 Multi-threaded Slave,性能也不错。 紧耦合(Tightly Coupled)所有节点数据和状态一致。 3)自动节点管理(Automatic Node Provisioning) 不需要人工去备份数据库恢复到新节点。
缺点:
1)只支持 InnoDB 对 MyISAM,只支持 DDL 语句,就是说,创建了表可以在其他节点看到,但 插入的数据各是各的。 为什么是 InnoDB? 多主进行更新的时候,每个节点执行的是乐观策略(假定没有冲突),然后开 始更新数据,等到要 commit 的时候,再问大家是不是有冲突,这样一来, 如果有冲突,执行的语句是不是得回滚,而你知道的 MyISAM 它不支持事务, 所以需要支持事务的引擎,而当前 MySQL 就 InnoDB 支持事务。 2)表里面需要有 PK 如果没有 Primary Key,那不同节点 DELETE 后,可能顺序不一致,表现在 select limit 语句在不同节点可能返回不一致。 3)不 支 持 lock/unlock tables, lock functions (GET_LOCK(), RELEASE_LOCK()... ) 当两个 transaction 从不同节点更新同一行数据的时候,只有一个 transaction 会成功,另外一个会返回 ER_LOCK_DEADLOCK。这其实也没啥大问题,因为逻辑设计上也有问题,不应该将事同一时刻的 一 个写重定向到两个节点的情况,最好的解决方法是,只有一个节点写。 当然,这是一件极掉逼格的一件事,人家的多主模式一下子被干成了单主,说出去不好听。 4)查询日志不能存到表里,只能存文件。log_output=FILE,这个一般也不用,特别是对我来说没啥影响。 5)最大transactionsize受 wsrep_max_ws_rows,wsrep_max_ws_size 两变量控制。 超出会被 reject。准确的说,不是一个缺点。
原 理 图
1)先提交到当前节点的 write-set 内。
2)将 write-set 改变复制到其他节点。
3)到其他节点后,最关键的一步,用 Primary key 探测是否有冲突,有冲突就rollback,没有就 commit,如果有问题的几点怎么办,把它踢出去。

无论采用哪种方法,都会短暂锁表,如果对这个比较敏感,那么可以采用专用的“仲裁节点”,即该节点不对用户开放,也不执行任何SQL操作。
1. 安装环境
2. 准备工作
2.1 软件包
galera-3-25.3.37-1.el7.x86_64.rpm mysql-wsrep-5.7-5.7.37-25.29.el7.x86_64.rpm mysql-wsrep-client-5.7-5.7.37-25.29.el7.x86_64.rpm mysql-wsrep-common-5.7-5.7.37-25.29.el7.x86_64.rpm mysql-wsrep-devel-5.7-5.7.37-25.29.el7.x86_64.rpm mysql-wsrep-libs-5.7-5.7.37-25.29.el7.x86_64.rpm mysql-wsrep-libs-compat-5.7-5.7.37-25.29.el7.x86_64.rpm mysql-wsrep-server-5.7-5.7.37-25.29.el7.x86_64.rpm mysql-wsrep-test-5.7-5.7.37-25.29.el7.x86_64.rpm
2.2 防火墙和SELinux
systemctl disable firewalld
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
2.3 设置yum的repo
/etc/yum.repos.d/local.repo
[local]
name=CentOS 7
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
baseurl=http://yum.wang6237.com/centos/7/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
2.4 安装rpm包
yum install -y *.rpm
2.5 通过⼆进制包安装
1)解压
tar -xf galera-3-25.3.37-Linux-x86_64.tar.gz -C ~/app/
mv ~/app/galera-3-25.3.37-Linux-x86_64 ~/app/galera
tar -xf mysql-wsrep-5.7.37-25.29-linux-x86_64.tar.gz -C ~/app/
mv ~/app/mysql-wsrep-5.7.37-25.29-linux-x86_64 ~/app/mysql
2)配置

2.6 启动集群
1)my.cnf的配置
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
skip-host-cache
skip-name-resolve
wsrep_on=on
performance_schema=on
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
#使用galera一定要是ROW格式而不能是SQL格式,不然会影响性能和一致性
binlog_format=ROW
##不要bind到本地地址,例如127.0.0.1,这样其他机器无法访问
bind-address=0.0.0.0
##galera在非事务性的存储引擎,例如MyISAM上无法工作
default_storage_engine=innodb
innodb_buffer_pool_size=122M
##AUTO_INCREMENT字段,全部使用interleaved lock mode,此种方式不适用于SQL模式的日志复制,但是比较适合ROW模式,由于insert语句不使用表级auto-inc lock,所以速度比较快
innodb_autoinc_lock_mode=2
##为了提高性能,galera官方建议使用1s刷一次日志的方式,但是同时也是不安全的方式,如果有备用电源,我认为设置为2比较好
innodb_flush_log_at_trx_commit=0
#
# #几台机器的必须一样,用来区分不同的集群
wsrep_cluster_name=ProdCluster
# 这个插件位置最关键,没有的话运行不起来, 根据实际清空修改。
wsrep_provider=/usr/lib64/galera-3/libgalera_smm.so
# #这个就是从谁那儿同步,后面可以是用逗号分隔开来的IP或者域名
wsrep_cluster_address="gcomm://mysql02,mysql03"
# #本地连出去的时候用的地址
wsrep_node_address="192.168.56.8"
# 其余节点只需要修改 wsrep_cluster_address 和 wsrep_node_address即可
# wsrep_sst_auth=sst:sstpass123
#
# 如果你没看文档,还是不要配了
# wsrep_provider_options="gcache.size=300M; gcache.page_size=300M"
# wsrep_provider_options="gcache.size=2G"
# wsrep_sst_method=xtrabackup-v2
#
# sst(State Snapshot Transfer)的默认同步方式就是rysnc,具体请参考:http://galeracluster.com/documentation-webpages/sst.html
wsrep_sst_method=rsync
#
#
2)启动第一个节点
rpm 方式:
#On Galera:
mysqld_bootstrap --wsrep-new-cluster
#On MariaDB:
mysqld --wsrep-new-cluster
#On Percona XtraDB Cluster
systemctl start mysql@bootstrap.service
⼆进制⽅式:
sh mysqld.sh wsrep-new-cluster
3)启动其他节点
rpm 方式:
systemctl start mysqld
⼆进制⽅式:
sh mysqld.sh start
4)查看集群状态
[root@mysql01 ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.37 MySQL Community Server - (GPL), wsrep_25.29
Copyright (c) 2000, 2022, 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.
#修改root密码
mysql> ALTER USER USER() IDENTIFIED BY '6tfc^YHN'
#查看所有状态变量
mysql> SHOW GLOBAL STATUS LIKE 'wsrep_%';
+------------------------------+----------------------------------------------------
| Variable_name | Value
+------------------------------+----------------------------------------------------
| wsrep_local_state_uuid | ec00f030-0258-11ed-9bcd-cb0312b05295
| wsrep_protocol_version | 9
| wsrep_last_committed | 4
| wsrep_replicated | 3
| wsrep_replicated_bytes | 736
| wsrep_repl_keys | 3
| wsrep_repl_keys_bytes | 96
| wsrep_repl_data_bytes | 435
| wsrep_repl_other_bytes | 0
| wsrep_received | 39
| wsrep_received_bytes | 4012
| wsrep_local_commits | 0
| wsrep_local_cert_failures | 0
| wsrep_local_replays | 0
| wsrep_local_send_queue | 0
| wsrep_local_send_queue_max | 1
| wsrep_local_send_queue_min | 0
| wsrep_local_send_queue_avg | 0.000000
| wsrep_local_recv_queue | 0
| wsrep_local_recv_queue_max | 2
| wsrep_local_recv_queue_min | 0
| wsrep_local_recv_queue_avg | 0.102564
| wsrep_local_cached_downto | 1
| wsrep_flow_control_paused_ns | 0
| wsrep_flow_control_paused | 0.000000
| wsrep_flow_control_sent | 0
| wsrep_flow_control_recv | 0
| wsrep_flow_control_active | false
| wsrep_flow_control_requested | false
| wsrep_cert_deps_distance | 1.000000
| wsrep_apply_oooe | 0.000000
| wsrep_apply_oool | 0.000000
| wsrep_apply_window | 1.000000
| wsrep_apply_waits | 0
| wsrep_commit_oooe | 0.000000
| wsrep_commit_oool | 0.000000
| wsrep_commit_window | 1.000000
| wsrep_local_state | 4
| wsrep_local_state_comment | Synced
| wsrep_cert_index_size | 1
| wsrep_causal_reads | 0
| wsrep_cert_interval | 0.000000
| wsrep_open_transactions | 0
| wsrep_open_connections | 0
| wsrep_incoming_addresses | 192.168.56.9:3306,192.168.56.10:3306,192.168.56.8:3306 |
| wsrep_cluster_weight | 3
| wsrep_desync_count | 0
| wsrep_evs_delayed |
| wsrep_evs_evict_list |
| wsrep_evs_repl_latency | 0/0/0/0/0
| wsrep_evs_state | OPERATIONAL
| wsrep_gcomm_uuid | ec00791a-0258-11ed-b92f-f7a5958db441
| wsrep_gmcast_segment | 0
| wsrep_cluster_conf_id | 10
| wsrep_cluster_size | 3
| wsrep_cluster_state_uuid | ec00f030-0258-11ed-9bcd-cb0312b05295
| wsrep_cluster_status | Primary
| wsrep_connected | ON
| wsrep_local_bf_aborts | 0
| wsrep_local_index | 2
| wsrep_provider_name | Galera
| wsrep_provider_vendor | Codership Oy <info@codership.com>
| wsrep_provider_version | 3.37(rf47405c8)
| wsrep_ready | ON
+------------------------------+----------------------------------------------------
64 rows in set (0.00 sec)
mysql> SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 3 |
+--------------------+-------+
1 row in set (0.00 sec)
2.7 监控集群
1)检查群集完整性
wsrep_cluster_state_uuid显示群集状态 UUID,可用于确定节点是否为群集的一部分。
mysql> SHOW GLOBAL STATUS LIKE 'wsrep_cluster_state_uuid';
+--------------------------+--------------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------------+
| wsrep_cluster_state_uuid | ec00f030-0258-11ed-9bcd-cb0312b05295 |
+--------------------------+--------------------------------------+
1 row in set (0.00 sec)
wsrep_cluster_conf_id显示已发生的群集更改的总数,您可以使用这些更改来确定节点是否是主组件的一部分。
mysql> SHOW GLOBAL STATUS LIKE 'wsrep_cluster_conf_id';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| wsrep_cluster_conf_id | 10 |
+-----------------------+-------+
1 row in set (0.00 sec)
wsrep_cluster_size显示群集中的节点数,可用于确定是否缺少任何节点。
mysql> SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 3 |
+--------------------+-------+
1 row in set (0.00 sec)
wsrep_cluster_status显示节点所在的群集组件的主要状态,可用于确定群集是否遇到分区。
mysql> SHOW GLOBAL STATUS LIKE 'wsrep_cluster_status';
+----------------------+---------+
| Variable_name | Value |
+----------------------+---------+
| wsrep_cluster_status | Primary |
+----------------------+---------+
1 row in set (0.00 sec)
2)检查节点状态
wsrep_ready显示节点是否可以接受查询。
mysql> SHOW GLOBAL STATUS LIKE 'wsrep_ready';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wsrep_ready | ON |
+---------------+-------+
1 row in set (0.00 sec)
ERROR 1047 (08501) Unknown Command
wsrep_connected显示节点是否与任何其他节点具有网络连接。
mysql> SHOW GLOBAL STATUS LIKE 'wsrep_connected';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| wsrep_connected | ON |
+-----------------+-------+
1 row in set (0.00 sec)
wsrep_local_state_comment以人类可读的格式显示节点状态。
mysql> SHOW STATUS LIKE 'wsrep_local_state_comment';
+---------------------------+--------+
| Variable_name | Value |
+---------------------------+--------+
| wsrep_local_state_comment | Synced |
+---------------------------+--------+
1 row in set (0.00 sec)
3)检查复制运行状况
wsrep_local_recv_queue_avg 显示自上次状态查询以来本地接收队列的平均大小。
mysql> SHOW STATUS LIKE 'wsrep_local_recv_queue_avg';
+----------------------------+----------+
| Variable_name | Value |
+----------------------------+----------+
| wsrep_local_recv_queue_avg | 0.102564 |
+----------------------------+----------+
1 row in set (0.00 sec)
wsrep_flow_control_paused 显示自上次调用FLUSH STATUS以来节点因流控制而暂停的时间比例。
mysql> SHOW STATUS LIKE 'wsrep_flow_control_paused';
+---------------------------+----------+
| Variable_name | Value |
+---------------------------+----------+
| wsrep_flow_control_paused | 0.000000 |
+---------------------------+----------+
1 row in set (0.00 sec)
4)检测慢速网络问题
mysql> SHOW STATUS LIKE 'wsrep_local_send_queue_avg';
+----------------------------+----------+
| Variable_name | Value |
+----------------------------+----------+
| wsrep_local_send_queue_avg | 0.000000 |
+----------------------------+----------+
1 row in set (0.00 sec)
2.8 验证
数据同步--在节点上分别执⾏以下命令:
# 在mysql01上执⾏
create database mytest1 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
# 在mysql02上执⾏
create database mytest2 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
# 在mysql03上执⾏
create database mytest3 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
# 在所有节点上执⾏
show databases;


1. LVS (DR)+Keepalived

1)keepalived 配置
! Configuration File for keepalived
global_defs {
.......... #省略
}
vrrp_instance VI_1 {
state MASTER
interface enp0s8
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.56.100
}
}
virtual_server 192.168.56.100 3306 {
delay_loop 6
lvs_sched wrr
lvs_method DR
protocol TCP
real_server 192.168.56.8 3306 {
weight 1
TCP_CHECK {
connect_timeout 5
retry 3
delay_before_retry 3
connect_port 3306
}
}
real_server 192.168.56.9 3306 {
.......... # 省略,和192.168.56.8一样
}
real_server 192.168.56.10 3306 {
.......... # 省略,和192.168.56.8一样
}
}
2. Haproxy + Keepalived

1)keepalived 配置
! Configuration File for keepalived
global_defs {
.......... #省略}
vrrp_instance VI_1 {
state MASTER
interface enp0s8
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.56.100
}
}
2)haproxy 配置
global
.......... #省略
defaults
.......... #省略
listen MYSQL_CLUSTER
bind 0.0.0.0:13306
mode tcp
option mysql-check user haproxy
maxconn 20000
balance roundrobin
server mysql_192_168_56_8 192.168.56.8:3306 check
server mysql_192_168_56_9 192.168.56.9:3306 check
server mysql_192_168_56_10 192.168.56.10:3306 check
timeout server 50000
listen admin_status
mode http
bind 192.168.56.11:8899
option httplog
log global
stats enable
stats refresh 10s
stats hide-version
stats realm Haproxy\ Statistics
stats uri admin-status
stats auth admin:123456
3. LVS、Keepalived和ProxySQL

1)Keepalived 配置
2)ProxySQL 配置

mysql> INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (0,'192.168.56.8',3306);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (0,'192.168.56.9',3306);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (0,'192.168.56.10',3306);
Query OK, 1 row affected (0.00 sec)

mysql> CREATE USER 'monitor'@'%' IDENTIFIED BY 'monitor!@#';
mysql> flush privileges;
ProxySQL Admin> UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-monitor_username';
ProxySQL Admin> UPDATE global_variables SET
variable_value='m0n1toRp@ssw0d' WHERE variable_name='mysql-
monitor_password';
ProxySQL Admin> LOAD MYSQL VARIABLES TO RUNTIME;
ProxySQL Admin> SAVE MYSQL VARIABLES TO DISK;
SELECT * FROM monitor.mysql_server_connect_log ORDER BY time_start_us DESC LIMIT 6;
SELECT * FROM monitor.mysql_server_ping_log ORDER BY time_start_us DESC LIMIT 6;
mysql> SELECT * FROM monitor.mysql_server_connect_log ORDER BY time_start_us DESC LIMIT 6;
+---------------+------+------------------+-------------------------+---------------+
| hostname | port | time_start_us | connect_success_time_us | connect_error |
+---------------+------+------------------+-------------------------+---------------+
| 192.168.56.9 | 3306 | 1661941880276727 | 902 | NULL |
| 192.168.56.10 | 3306 | 1661941880252444 | 623 | NULL |
| 192.168.56.8 | 3306 | 1661941880228475 | 945 | NULL |
| 192.168.56.10 | 3306 | 1661941878271410 | 779 | NULL |
| 192.168.56.8 | 3306 | 1661941878249663 | 874 | NULL |
| 192.168.56.9 | 3306 | 1661941878228074 | 961 | NULL |
+---------------+------+------------------+-------------------------+---------------+
6 rows in set (0.00 sec)
mysql> SELECT * FROM monitor.mysql_server_ping_log ORDER BY time_start_us DESC LIMIT 6;
+---------------+------+------------------+----------------------+------------+
| hostname | port | time_start_us | ping_success_time_us | ping_error |
+---------------+------+------------------+----------------------+------------+
| 192.168.56.8 | 3306 | 1661945342896956 | 239 | NULL |
| 192.168.56.9 | 3306 | 1661945342874007 | 214 | NULL |
| 192.168.56.10 | 3306 | 1661945342851008 | 265 | NULL |
| 192.168.56.8 | 3306 | 1661945340879414 | 193 | NULL |
| 192.168.56.9 | 3306 | 1661945340865025 | 245 | NULL |
| 192.168.56.10 | 3306 | 1661945340850602 | 345 | NULL |
+---------------+------+------------------+----------------------+------------+
6 rows in set (0.00 sec)
4. 对比结果
参考文档:

本文作者:王玉坤(上海新炬中北团队)
本文来源:“IT那活儿”公众号

文章转载自IT那活儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。