主主同步实验
参考 MariaDB 主从同步与热备 需要配置文件my.cnf 注意bin-log设置的过期时间以及文件大小 配置文件中增加server-id同步旧数据库的数据到新数据库:新数据库实例创建数据库(create database)后导入所有数据(mysql < sql_file),同步前需要两个数据库实例上数据一致。 在两台实例上:
- 创建同步用的用户:create user 'another'@'%' identified by 'slave.mysql.password';
- 授权:grant replication slave on . to 'another'@'%' identified by 'slave.mysql.password';
- 查看master状态:show master status;
- 改变master:change master to master_host='172.31.10.242',master_port=3006,master_user='another',master_password='slave.mysql.password',master_log_file='mariadb-bin.000007',master_log_pos=245; 注意端口是否放开。
- 启动slave: start slave;
- 查看状态:show slave status;
从配置过程来看,相当于两台实例互为主备,A是B的slave、B也是A的master,同时B也是A的slave、A是B的master,即A和B为主备的同时B和A也为主备。 理论上可以直接使用zsha2来执行数据库同步相关的流程。
Mariadb-Galera
MariaDB Galera Cluster底层原理:https://blog.csdn.net/wzy0623/article/details/102522268
Galera Cluster与传统的复制方式不同,不通过I/O_thread和sql_thread进行同步,而是在更底层通过wsrep实现文件系统级别的同步,可以做到几乎实时同步,而其上的MySQL对此一无所知。 要求MySQL能够调用wsrep提供的API来完成,在Mariadb10.1之前的版本,支持Galera Cluster的版本是与Mariadb分开发行的,其版本名称就成为Mariadb-Galera,Mariadb10.1以后的版本中MariaDB Galera Cluste不再单独发行,而是以galera-25.3.12-2.el7.x86_64包的形式出现。 所有节点可以同时读写数据库自动的节点成员控制,失效节点自动被清除新节点加入数据自动复制真正的并行复制,行级用户可以直接连接集群。
优点:
- 因为是多主,所以不存在Slavelag(延迟)。
- 不存在丢失事务的情况。
- 同时具有读和写的扩展能力。
- 更小的客户端延迟。
- 节点间数据是同步的,而Master/Slave模式是异步的,不同slave上的binlog可能是不同的。
缺点:
- 加入新节点时开销大,需要复制完整的数据。
- 不能有效地解决写扩展的问题,所有的写操作都发生在所有的节点。
- 有多少个节点,就有多少份重复的数据。
- 由于事务提交需要跨节点通信,即涉及分布式事务操作,因此写入会比主从复制慢很多,节点越多,写入越慢,死锁和回滚也会更加频繁。
- 对网络要求比较高,如果网络出现波动不稳定,则可能会造成两个节点失联,Galera Cluster集群会发生脑裂,服务将不可用。
- 仅支持InnoDB/XtraDB存储引擎,任何写入其他引擎的表,包括mysql.*表都不会被复制。但是DDL语句可以复制,但是insert into mysql.user(MyISAM存储引擎)之类的插入数据不会被复制。
- Delete操作不支持没有主键的表,因为没有主键的表在不同的节点上的顺序不同,如果执行select … limit …将出现不同的结果集。
- LOCK/UNLOCK TABLES/FLUSH TABLES WITH READ LOCKS不支持单表所锁,以及锁函数GET_LOCK()、RELEASE_LOCK(),但FLUSH TABLES WITH READ LOCK支持全局表锁。
- General Query Log日志不能保存在表中,如果开始查询日志,则只能保存到文件中。
- 不能有大事务写入,不能操作wsrep_max_ws_rows=131072(行),且写入集不能超过wsrep_max_ws_size=1073741824(1GB),否则客户端直接报错。
- 由于集群是乐观锁并发控制,因此,在commit阶段会有事务冲突发生。如果两个事务在集群中的不同节点上对同一行写入并提交,则失败的节点将回滚,客户端返回死锁报错。
- XA分布式事务不支持Codership Galera Cluster,在提交时可能会回滚。
- 整个集群的写入吞吐量取决于最弱的节点限制,集群要使用同一的配置。
Mariadb galera cluster手工实验
准备:
- 三台不同云主机
- mariadb:mariadb:10.6.14镜像
- 三台机器上均创建/tmp/mariadb/{conf,data}目录
配置示例:
cnf
# The MariaDB configuration file
#
# The MariaDB/MySQL tools read configuration files in the following order:
# 0. "/etc/mysql/my.cnf" symlinks to this file, reason why all the rest is read.
# 1. "/etc/mysql/mariadb.cnf" (this file) to set global defaults,
# 2. "/etc/mysql/conf.d/*.cnf" to set global options.
# 3. "/etc/mysql/mariadb.conf.d/*.cnf" to set MariaDB-only options.
# 4. "~/.my.cnf" to set user-specific options.
#
# If the same option is defined multiple times, the last one will apply.
#
# One can use all long options that the program supports.
# Run program with --help to get a list of available options and with
# --print-defaults to see which it would actually understand and use.
#
# If you are new to MariaDB, check out https://mariadb.com/kb/en/basic-mariadb-articles/
#
# This group is read both by the client and the server
# use it for options that affect everything
#
[client-server]
# Port or socket location where to connect
# port = 3306
socket = /run/mysqld/mysqld.sock
# [galera]
# wsrep_on=ON
# wsrep_provider=/usr/lib/galera/libgalera_smm.so
# wsrep_cluster_address='gcomm://172.20.16.234:4567,172.20.16.139:4567,172.31.10.242:4567'
# wsrep_cluster_name='serviceb_galera'
# wsrep_node_address='172.20.16.234'
# wsrep_node_name='mariadb01'
# wsrep_sst_method=rsync
# binlog_format=row
# default_storage_engine=InnoDB
# innodb_autoinc_lock_mode=2
# bind-address=0.0.0.0
# wsrep_sst_auth=root:servicea.mysql.password
# [galera]
# wsrep_on=ON
# wsrep_provider=/usr/lib/galera/libgalera_smm.so
# wsrep_cluster_address='gcomm://172.20.16.234:4567,172.20.16.139:4567,172.31.10.242:4567'
# wsrep_cluster_name='serviceb_galera'
# wsrep_node_address='172.20.16.139'
# wsrep_node_name='mariadb02'
# wsrep_sst_method=rsync
# binlog_format=row
# default_storage_engine=InnoDB
# innodb_autoinc_lock_mode=2
# bind-address=0.0.0.0
# wsrep_sst_auth=root:servicea.mysql.password
[galera]
wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_address='gcomm://172.20.16.234:4567,172.20.16.139:4567,172.31.10.242:4567'
wsrep_cluster_name='serviceb_galera'
wsrep_node_address='172.31.10.242'
wsrep_node_name='mariadb03'
wsrep_sst_method=rsync
binlog_format=row
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0
wsrep_sst_auth=root:servicea.mysql.password
wsrep_provider_options="ist.recv_bind=172.17.0.2" # ip为对应容器ip
# Import all .cnf files from configuration directory
!includedir /etc/mysql/mariadb.conf.d/
!includedir /etc/mysql/conf.d/实验步骤:
- 上述配置写入/tmp/mariadb/conf/my.cnf, 注意第一个启动的节点的配置中
wsrep_cluster_address='gcomm://',不是完整的集群地址配置。 - 启动前请先使用镜像初始化数据目录,以便写入root密码,然后启动第一个docker容器, 开放端口4444,4567,4568以及mariadb监听端口:
docker run -d -p 0.0.0.0:13006:3306 -p 0.0.0.0:4567:4567 -p 0.0.0.0:4568:4568 -p 0.0.0.0:4444:4444 -v /tmp/mariadb/data/:/var/lib/mysql/ -v /tmp/mariadb/conf/my.cnf:/etc/mysql/my.cnf --name=mariadb1 172.20.16.139:5000/mariadb:10.6.14 --wsrep-new-cluster - 确认容器正常启动后,启动其他节点的容器:
docker run -d -p 0.0.0.0:13006:3306 -p 0.0.0.0:4567:4567 -p 0.0.0.0:4568:4568 -p 0.0.0.0:4444:4444 -v /tmp/mariadb/data/:/var/lib/mysql/ -v /tmp/mariadb/conf/my.cnf:/etc/mysql/my.cnf -e MARIADB_ROOT_PASSWORD=servicea.mysql.password --name=mariadb2 172.20.16.139:5000/mariadb:10.6.14请确认数据目录为空,第一次同步为SST全量同步。并且启动命令没有--wsrep-new-cluster参数。 - 分别登录mariadb节点,执行
show global status like '%wsrep%';,检查集群状态和同步状态等,关于命令输出的结果说明:https://runebook.dev/zh/docs/mariadb/galera-cluster-status-variables/index。 - 测试:在节点1上创建数据库serviceb,节点2上创建表abcd,节点3上写入多行数据,在各个节点检查数据是否同步。
- 测试:docker stop某个mariadb节点,在其余节点上写入/更新数据,重新启动停止的节点,查看数据同步情况。
- 关于后续的集群启动,必须按照以下规则,按照启动顺序反向关闭节点,第一个启动的节点的数据目录的
grastate.dat的safe_to_bootstrap为1:- 如果集群从来没有启动过(3个节点上都没有数据目录下的
grastate.dat文件),则必要由其中一个节点以--wsrep-new-cluster参数启动,另外两个节点正常启动即可,即上述的启动方式。 - 如果集群以前启动过,则参考数据目录下的
grastate.dat,找到safe_to_bootstrap为1的节点,在该节点上以--wsrep-new-cluster参数启动,另外两个节点正常启动即可. - 如果集群以前启动过,但参考数据目录下的
grastate.dat,找不到safe_to_bootstrap为1的节点(一般是因为mariadb服务非正常停止造成),则在3个节点中随便找1个节点,将/var/lib/mysql/grastate.dat中的safe_to_bootstrap修改为1,再在该节点上以--wsrep-new-cluster参数启动,另外两个节点正常启动即可(待验证)。
- 如果集群从来没有启动过(3个节点上都没有数据目录下的
- mariadb galera cluster配置项说明:https://galeracluster.com/library/documentation/galera-parameters.html
Questions:
- 集群中
safe_to_bootstrap=1的节点关机后,其余节点正常,但是关机的节点无法启动,即便是删除掉wsrep-new-cluster容器启动参数。此时无法启动是因为配置中的wsrep_cluster_address='gcomm://'中包含自身。需要删除自身的配置并且不用--wsrep-new-cluster参数启动。而整个集群关机后参考集群启动相关。