前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在Docker中安装使用MySQL 高可用之MGC(多主同时写入)

在Docker中安装使用MySQL 高可用之MGC(多主同时写入)

作者头像
jwangkun
发布2021-12-23 17:35:55
1.4K0
发布2021-12-23 17:35:55
举报
文章被收录于专栏:John Wong's BlogJohn Wong's Blog

MariaDB Galera Cluster(下文简称 MGC 集群),是一套在 MySQL innodb 存储引擎上面实现多主、数据实时同步以及强一致性的关系存储架构,业务层面无需做读写分离工作,数据库读写压力都能按照既定的规则分发到 各个节点上去,在数据方面完全兼容 MariaDB 和 MySQL。

功能特性:

1、同步复制 Synchronous replication

2、Active-active multi-master 拓扑逻辑

3、可对集群中任一节点进行数据读写

4、自动成员控制,故障节点自动从集群中移除

*5、*自动节点加入

6、真正并行的复制,基于行级

*7、*直接客户端连接,原生的 MySQL 接口

**8、**每个节点都包含完整的数据副本

9、多台数据库中数据同步由 wsrep 接口实现

缺点:

1、目前的复制仅仅支持 InnoDB 存储引擎, 任何写入其他引擎的表,包括 mysql.* 表将不会复制, 但是 DDL 语句会被复制的, 因此创建用户将会被复制, 但是 insert into mysql.user… 将不会被复制的.

2、DELETE 操作不支持没有主键的表, 没有主键的表在不同的节点顺序将不同, 如果执行 SELECT…LIMIT… 将出现不同的结果集.

3、在多主环境下 LOCK/UNLOCK TABLES 不支持, 以及锁函数 GET_LOCK(), RELEASE_LOCK()…

4、查询日志不能保存在表中。如果开启查询日志,只能保存到文件中。

5、允许最大的事务大小由 wsrep_max_ws_rows 和 wsrep_max_ws_size 定义。任何大型操作将被拒绝。如大型的 LOAD DATA 操作。

6、由于集群是乐观的并发控制,事务 commit 可能在该阶段中止。如果有两个事务向在集群中不同的节点向同一行写入并提交,失败的节点将中止。对 于集群级别的中止,集群返回死锁错误代码 (Error: 1213 SQLSTATE: 40001 (ER_LOCK_DEADLOCK)).

7、XA 事务不支持,由于在提交上可能回滚。

8、整个集群的写入吞吐量是由最弱的节点限制,如果有一个节点变得缓慢,那么整个集群将是缓慢的。为了稳定的高性能要求,所有的节点应使用统一的硬件。

9、集群节点建议最少 3 个。

10、如果 DDL 语句有问题将破坏集群。

1、环境规划

node1:192.168.1.30:3310

node2:192.168.1.30:3311

node3:192.168.1.30:3312

2、部署环境

创建目录

代码语言:javascript
复制
mkdir /data/mysql/mariadb/cluster0/
mkdir /data/mysql/mariadb/cluster0/conf
mkdir /data/mysql/mariadb/cluster0/data
mkdir /data/mysql/mariadb/cluster1/
mkdir /data/mysql/mariadb/cluster1/conf
mkdir /data/mysql/mariadb/cluster1/data
mkdir /data/mysql/mariadb/cluster2/
mkdir /data/mysql/mariadb/cluster2/data
mkdir /data/mysql/mariadb/cluster2/conf

编辑配置文件

代码语言:javascript
复制
vi /data/mysql/mariadb/cluster0/conf/server.cnfjavascript:void(0);)
代码语言:javascript
复制
[server]  
[mysqld]  
server_id=130
pid-file=/var/run/mysqld/mysqld.pid
socket=/var/run/mysqld/mysqld.sock
basedir=/usr
datadir=/var/lib/mysql
tmpdir=/tmp
user=mysql
skip-external-locking
skip-name-resolve
character-set-server=utf8
port=3306
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address        = 127.0.0.1
#
# * Fine Tuning
#
max_connections=1000
connect_timeout=5
wait_timeout=600
max_allowed_packet=16M
thread_cache_size=128
sort_buffer_size=4M
bulk_insert_buffer_size=16M
tmp_table_size=32M
max_heap_table_size=32M
[galera]  
wsrep_causal_reads=ON  #节点应用完事务才返回查询请求  
wsrep_provider_options="gcache.size=128M"#同步复制缓冲池  
wsrep_certify_nonPK=ON   #为没有显式申明主键的表生成一个用于certificationtest的主键,默认为ON  
#log-bin=/app/galera/mysql-bin  #如果不接从库,注释掉  
#log_slave_updates=1         #如果不接从库,注释掉  
query_cache_size=0           #关闭查询缓存  
wsrep_on=ON   #开启全同步复制模式  
wsrep_provider=/usr/lib/galera/libgalera_smm.so #galera library  
wsrep_cluster_name=MGC-Cluster
#wsrep_cluster_address="gcomm://192.168.1.30:4567,192.168.1.30:4568,192.168.1.30:4569"  #galera cluster URL  
wsrep_node_name=mariadb-0
#wsrep_node_address=172.18.0.4
wsrep_sst_auth=syncuser:syncuser
#wsrep_sst_method=xtrabackup-v2
wsrep_sst_method=rsync
binlog_format=row  
default_storage_engine=InnoDB  
innodb_autoinc_lock_mode=2   #主键自增模式修改为交叉模式  
wsrep_slave_threads=8  #开启并行复制线程,根据CPU核数设置  
innodb_flush_log_at_trx_commit=0   #事务提交每隔1秒刷盘  
innodb_buffer_pool_size=500M
[embedded] 
[mariadb]  
[mariadb-10.3]

cluster0/server.cnf 配置文件 先注释掉 wsrep_cluster_address, 因为要初始化用户之后再开始集群

注意: wsrep_provider_options="gcache.size=128M"# 同步复制缓冲池 , 根据电脑固态硬盘容量大小设置成, 这里设置成 128M

cluster1 差异部分

代码语言:javascript
复制
wsrep_node_name=mariadb-1

cluster2 差异部分

代码语言:javascript
复制
wsrep_node_name=mariadb-2

第一次启动节点

代码语言:javascript
复制
docker run -d --name mariadb-cluster0 --expose 4567 -p 4567:4567 -p 3310:3306 -e TIMEZONE=Asia/Shanghai -v /data/mysql/mariadb/cluster0/conf:/etc/mysql/conf.d -v /data/mysql/mariadb/cluster0/data:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=yse mariadb:10.3
docker run -d --name mariadb-cluster1 --expose 4567 -p 4568:4567 -p 3311:3306 -e TIMEZONE=Asia/Shanghai -v /data/mysql/mariadb/cluster1/conf:/etc/mysql/conf.d -v /data/mysql/mariadb/cluster1/data:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=yse mariadb:10.3
docker run -d --name mariadb-cluster2 --expose 4567 -p 4569:4567 -p 3312:3306 -e TIMEZONE=Asia/Shanghai -v /data/mysql/mariadb/cluster2/conf:/etc/mysql/conf.d -v /data/mysql/mariadb/cluster2/data:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=yse mariadb:10.3

分别在三个容器中添加 mysql 账户 注: 生产环境注意安全,我是在测试环境为了方便

代码语言:javascript
复制
mysql -uroot -p
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO 'syncuser'@'%' IDENTIFIED BY 'syncuser' WITH GRANT OPTION;
flush privileges;
shutdown;

先停止然后删除 3 个容器

然后分别解开 wsrep_cluster_address 注释, 再次启动 3 个节点 --wsrep-new-cluster 只有在第一次集群, 第一个节点, 才需要加上, 下次启动不需要此参数

代码语言:javascript
复制
docker run -d --name mariadb-cluster0 --expose 4567 -p 4567:4567 -p 3310:3306 -e TZ=Asia/Shanghai -v /data/mysql/mariadb/cluster0/conf:/etc/mysql/conf.d -v /data/mysql/mariadb/cluster0/data:/var/lib/mysql mariadb:10.3 --wsrep-new-cluster
docker run -d --name mariadb-cluster1 --expose 4567 -p 4568:4567 -p 3311:3306 -e TZ=Asia/Shanghai -v /data/mysql/mariadb/cluster1/conf:/etc/mysql/conf.d -v /data/mysql/mariadb/cluster1/data:/var/lib/mysql mariadb:10.3
docker run -d --name mariadb-cluster2 --expose 4567 -p 4569:4567 -p 3312:3306 -e TZ=Asia/Shanghai -v /data/mysql/mariadb/cluster2/conf:/etc/mysql/conf.d -v /data/mysql/mariadb/cluster2/data:/var/lib/mysql mariadb:10.3

注意启动顺序

查看是否成功

代码语言:javascript
复制
SHOW STATUS LIKE 'wsrep_cluster_size';

三、遇到问题

1、WSREP: failed to open gcomm backend connection: 131: invalid UUID

进入该数据库节点 / var/lib/mysql / 目录,将文件 gvwstate.dat 移除 (mv) 掉。然后重新启动 mairbd 即可

2、bind: Address already in use

查看 mysql 进程:ps -ef | grep mysql,然后杀死该进程,在启动 mariadb

3、It may not be safe to bootstrap the cluster from this node

数据库集群宕机,在运行 / bin/galera_new_cluster 启动第一个节点时报错,意思是该节点不是最后一个停掉的,不能安全启动;

    然后可以尝试在其他节点运行该命令;

    如果报错都相同,则需要从 3 个节点中选取一个主节点,修改 / var/lib/mysql/grastate.dat,把其中 safe_to_bootstrap 的值改为 1 即可。然后运行 / bin/galera_new_cluster。其他节点依次启动

4、ERROR WSREP: failed to open gcomm backend connection: 110

现象:集群三个节点无法启动,日志有如上报错,gvwstate.dat 不存在,三个 grastate.dat 中 seqno 值都为 - 1,并且其内无 safe_to_bootstrap 参数。

原因:

1、数据库如果正常关闭的话,gvwstate.dat 文件是不存在的,如果三个节点同时关闭(无数据变化)seqno 值应该是相等的,且不为 - 1。

2、如果这个时候无论先后顺利启动节点,都会导致所有节点都在不断重启中,并且 seqno 值由原来的值变为 - 1。

3、此时无法选举出来哪个作为主启动节点,需要再第一个节点启动时手动指定该节点作为集群主节点启动。

解决办法:

选定主节点启动时加 --wsrep-new-cluster 参数启动

正常启动后的节点重新生成 gvwstate.dat 文件

5、MySQL Unknown/unsupported storage engine: INNODB

  1. 删除 data 目录下文件

ib_logfile0 , ib_logfile1 , ibdata1

  1. 重新启动服务

6、ERROR mysqld: Table './mysql/user' is marked as crashed and should be repaired

修复过程:

表 user 被标记有问题,需要修复

./myisamchk -c -r /var/lib/mysql/mysql/user.MYI

出现可以参考这些错误,但根据实际情况来,版本不一样情况可能会有变化。

下一篇: 在Docker中安装使用MySQL 部署PXC高可用(多主同时写入)→

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-11-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、环境规划
  • 2、部署环境
  • 三、遇到问题
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档