PXC-mysql,全名Percona XtraDB Cluster,是一种强大的MySQL开源集群方案,详见官方文档

1. 特点

  • 多主架构:真正的多点读写的集群,在任何时候读写数据,都是最新的。
  • 同步复制:集群不同节点之间数据同步,没有延迟,在数据库挂掉之后,数据不会丢失。
  • 并发复制:从节点在APPLY数据时,支持并行执行,有更好的性能表现。
  • 故障切换:在出现数据库故障时,因为支持多点写入,切的非常容易。
  • 热插拔:在服务期间,如果数据库挂了,只要监控程序发现的够快,不可服务时间就会非常少。在节点故障期间,节点本身对集群的影响非常小。
  • 自动节点克隆:在新增节点,或者停机维护时,增量数据或者基础数据不需要人工手动备份提供,PXC会自动拉取在线节点数据,最终集群会变为一致。

以上几点,足以说明PXC是一个既稳健,又在数据一致性、完整性及高性能方面有出色表现的高可用解决方案。

2. 缺点

  • 配置新节点的开销。 添加新节点时,必须从现有节点中的一个复制完整数据集。 如果是100GB,则复制100GB。
  • 这不能用作有效的写入缩放解决方案。 当您将写入流量运行到2个节点,而将所有流量运行到1个节点时,写入吞吐量可能会有所改善,但您不能期望太多。 所有写入仍然必须在所有节点上进行。
  • 重复的数据,3个节点就会有3个重复的数据。

3. 使用限制

  • 复制只适用于InnoDB存储引擎。任何写入其他类型的表,包括系统(mysql.*)表复制。
  • 不支持的查询:
1
2
– LOCK TABLES and UNLOCK TABLES is not supported in multi-master setups
– Lock functions, such as GET_LOCK(), RELEASE_LOCK(), and so on
  • 查询日志不能定向到表格。如果启用查询日志记录,则必须将日志转发到文件:log_output =file
  • 允许的最大事务大小由wsrep_max_ws_rows和wsrep_max_ws_size变量。 LOAD DATA INFILE处理将每隔10 000行提交一次。所以大transactions由于LOAD DATA将被拆分为一系列小型transactions。
  • 由于可能的提交回滚,XA事务不受支持。
  • 由于集群级乐观并发控制,事务发出COMMIT可能仍会中止阶段。
  • 整个集群的写入吞吐量受最弱节点的限制。如果一个节点变慢,则整个集群变慢。
  • 群集的最小建议大小是3个节点。第三个节点可以是一个arbitrator。
  • 不支持binlog_rows_query_log_events变量。
  • 在SST或XtraBackup中使用的备份锁可能会崩溃。

4. 专业名词

  • SST:State Snapshot Transfer全量同步
  • IST:Incremental State Transfer增量同步,

5. 集群端口

  • 3306 数据库对外提供服务的端口
  • 4444 镜像数据传输SST,集群数据同步端口,全量同步,新节点加入时起作用
  • 4567 集群节点间相互通信的端口
  • 4568 增量数据同步IST,节点下线、重启后使用该端口,增量同步数据。

6. 节点状态

  • OPEN 节点启动成功,尝试连接到集群,如果失败则根据配置退出或创建新的集群
  • PRIMARY 节点已处于集群中,在新节点加入时,选取donor进行数据同步时会产生的状态
  • JOINER 节点处于等待接收/接收同步文件时的状态
  • JOINED 节点完成数据同步,但有部分数据没跟上,在尝试保持和集群进度一致的过程状态,例如某个节点故障后,重新加入集群,在追赶集群进度时的状态
  • SYNCED 节点正常提供服务的状态,表示已经同步完成并和集群进度保持一致。
  • DONOR 节点处于为新节点提供全量数据数据同步时的状态。此时该节点对客户端不提供服务。

节点状态变更可能原因:新节点加入集群/节点故障恢复/重新加入集群/节点同步失效

7. 当galera cluster集群单个节点或所有节点停机情况分析

7.1 单个节点停机

  • 节点停机重启,重新加入集群,通过IST增量同步数据,来保持集群数据的一致性。IST的实现由wsrep_provider_options="gcache.size=1G"参数决定,一般设置为1G。参数大小由什么决定,根据停机时间,若停机一小时,需要确认一小时产生多大的binlog来算出参数大小。
  • 停机时间过长,部分数据gcache没有,此时该节点SST全量同步数据。

7.2. 所有节点关闭,应采用轮巡滚动关闭的方式:a节点关闭修复,加回集群;b节点关闭修复,加回集群

  • 原则就是保持cluster中最少一个成员存活,进行滚动重启。

  • 集群所有节点都关闭了,没有存活的节点的情况:每个节点数据库关闭后,都会保存最后一个GTID,启动集群时要先启动最后一个关闭的节点,启动顺序和关闭顺序相反。

7.3. 避免关闭和启动节点时数据丢失

  • 原则保持cluster集群中最少有一个成员存活,然后进行滚动重启
  • 利用主从的概念,把一个从节点转化为PXC/Galera集群中的节点

8. 常见问题汇总

  • 如果主节点(负责写入的节点)写入过大,apply_cd时间过长,导致数据更新操作时间过长,怎么处理?

  • Wrep_slave_threads参数配置成cpu的个数或者1.5倍。

  • 脑裂:任何命令执行出现unknown command,表示出现脑裂,集群中任意两个节点间通信的4567端口不通,并且无法对外提供服务。SET GLOBAL wsrep_provider_options=“pc.ignore_sb=true”;

  • 并发写:如果在集群多个节点进行写/更新操作,有可能同时不同节点update同一行操作时就会出现锁死问题,出现:Error:1213 SQLSTATE:4001.解决:指定更新和写入都在都一个节点操作。

  • DDL全局锁:采用pt-online-schema-change

  • 只支持innodb引擎,表结构必须要有主键,不然会造成集中每个节点的data page里的数据不一致。

  • 不支持表级锁,即不能lock/unlock tables,使用行级锁

  • 新节点加入加入&故障节点恢复加入集群,此时不能有写操作,不然会导致被写入的那台库DDL死锁。所以需要暂停集群业务写操作,等数据一致后在开启写操作。

项目PXC-mysql配置及运维

1. 节点信息

PXC-mysql采用的是3个节点集群规模,3节点角色相同,均可读写,数据要求是强一致性,节点信息如下:

主机名 IP BaseDir DataDir ConfigFile LogDir
testdb1 10.1.2.7 /opt/server/mysql /opt/data/mysql /opt/server/mysql/etc/my.cnf /opt/server/var/log
testdb2 10.1.2.16 /opt/server/mysql /opt/data/mysql /opt/server/mysql/etc/my.cnf /opt/server/var/log
testdb3 10.1.2.3 /opt/server/mysql /opt/data/mysql /opt/server/mysql/etc/my.cnf /opt/server/var/log

2. 服务控制

启动服务

1
server mysql start

停止服务

1
server mysql stop

重启服务

1
server mysql restart

3. 重要配置参数

vim /opt/server/mysql/etc/my.cnf

服务配置

  • wsrep-on # 开启全同步复制模式
  • server_id # 节点服务id,各节点不能冲突
  • log-bin # 如果不接从库,注释掉
  • expire-logs-days
  • max_connect_errors
  • max_connections # 最大连接数
  • bind_address # 监听地址
  • port # 监听端口
  • user # 服务运行用户
  • basedir # mysql根目录
  • datadir # mysql数据目录
  • tmpdir # mysql临时目录
  • pid_file # mysql进程文件路径
  • log_error # 错误日志路径
  • slow-query-log-file # 慢日志路径
  • socket # socket存放路径
  • sql-mode
  • thread_cache_size # 可以重新利用保存在缓存中线程的数量
  • skip_name_resolve
  • back_log # 出在MySQL暂时停止响应新请求之前的短时间内多少个请求可以被存在堆栈中
  • table_open_cache # 缓存表数量,默认64
  • max_allowed_packet # 服务器发送和接受的最大包长度
  • slow_query_log # 开启慢查询统计日志
  • long_query_time # 慢查询超时标准
  • explicit_defaults_for_timestamp
  • default_storage_engine # 默认使用InnoDB引擎
  • binlog_format # binlog格式:Galera supports only row-level replication
  • query_cache_size # 指定MySQL查询缓冲区的大小,0为关闭
  • query_cache_type
  • open-files-limit # 指定撕开的最大文件数

集群配置

  • wsrep_cluster_name # 集群名,必须统一
  • wsrep_node_name # 当前节点名,保证每个节点名唯一
  • wsrep_node_address # 当前节点IP
  • wsrep_cluster_address # 集群节点主机集合(IP或可解析主机名)
  • wsrep_node_incoming_address # 集群节点主机集合
  • wsrep_provider # 指定galera库
  • wsrep_provider_options # 在此值范围内,重新恢复的节点会使用IST同步数据,否则使用SST同步
  • wsrep_slave_threads # 开启并行复制线程,根据CPU核数设置
  • wsrep_certify_nonPK # 为没有显式申明主键的表生成一个用于certificationtest的主键,默认为ON
  • wsrep_max_ws_rows
  • wsrep_debug
  • wsrep_convert_LOCK_to_trx
  • wsrep_retry_autocommit
  • wsrep_auto_increment_control
  • wsrep_causal_reads
  • wsrep_sst_method # SST模式,有rsync,官方推荐xtrabackup-v2,但要在初始化节点时创建SST用户
  • wsrep_sst_auth # SST验证用户和密码

InnoDB配置

  • innodb_buffer_pool_size=48G # 只有InnoDB存储引擎的数据库服务器上面,可以设置60-80%的内存
  • innodb_buffer_pool_instances=8
  • innodb_lock_wait_timeout=60
  • innodb_log_files_in_group=3
  • innodb_log_file_size=1024M # 该参数决定了recovery speed,一般取256M可以兼顾性能和recovery的速度
  • innodb_log_buffer_size=32M # 设定log buffer的大小
  • innodb_file_per_table=1 # 可以存储每个InnoDB表和它的索引在它自己的文件中
  • innodb_flush_method=O_DIRECT # 设置InnoDB同步IO的方式
  • innodb_flush_neighbors=0
  • innodb_sync_spin_loops=0
  • innodb_io_capacity=3000
  • innodb_io_capacity_max=6000
  • innodb_lru_scan_depth=3000
  • innodb_max_dirty_pages_pct=40
  • innodb_adaptive_flushing=1
  • innodb_read_io_threads=8
  • innodb_write_io_threads=8
  • innodb_thread_concurrency=16 # InnoDB kernel最大的线程数
  • innodb_flush_log_at_trx_commit=0 # 事务提交每隔1秒刷盘
  • innodb_autoinc_lock_mode=2 # Galera仅支持主键自增模式修改为交叉模式
  • innodb_doublewrite=1