初次部署OpenStack集群的小伙伴经常会遇到一个问题,集群断电或者不正常的关机后,mairadb集群就起不来了。这里为大家讲述kolla容器化部署中mairadb galera集群的恢复及相关基础知识。
Galera Cluster的所有节点是对等关系,每个节点都支持写入。
特性如下:
- 普通列表项目真正的多主集群,Active-Active架构。
- 同步复制,没有复制延迟。
- 多线程复制。
- 没有主从切换操作,无需使用虚IP。
- 热备份,单个节点故障期间不会影响数据库业务。
- 支持节点自动加入,无需手动拷贝数据。
- 支持InnoDB存储引擎。
- 对应用程序透明,原生MySQL接口。
- 无需做读写分离
查看mariadb服务状态
查看容器日志:docker logs mariadb
查看服务日志:cat /var/log/kolla/mariadb/mariadb.log
登陆数据库输入: show global status like “wsrep_%”;
数据库状态表主要查看3个值:
wsrep_cluster_status :
任何非Primary值都代表该集群不可用
wsrep_local_state_comment 状态对照表:
状态 | 状态说明 |
---|---|
Open: | 节点启动成功,尝试连接到集群 |
Primary: | 节点已处于集群中,在新节点加入时,选取donor进行数据库同步时会产生的状态 |
Joiner: | 节点处于等待接收或正在接收同步文件的状态 |
Joined: | 节点完成数据同步,但还有部分数据不是最新的,在追赶与集群数据一致的状态 |
Synced: | 节点正常提供服务的状态,表示当前节点数据状态与集群数据状态是一致的 |
Donor: | 表示该节点被选为Donor节点,正在为新加进来的节点进行全量数据同步,此时该节点对客户端不提供服务 |
SST
英文全称为State Snapshot Transfer,即状态快照迁移:通过从一个节点到另一个节点迁移完整的数据拷贝(全量拷贝)。当一个新的节点加入到集群中,新的节点从集群中已有节点进行数据同步,开始进行状态快照迁移。
IST
英文全称为Increamental State Transfer,即增量状态迁移:集群一个节点通过识别新加入的节点缺失的事务操作,将该操作发送,而并不像SST那样的全量数据拷贝。最常见情况就是该节点之前已经存在于该集群,只是关机重启了,重新加入该集群会使用IST进行同步。
grastate.dat
默认路径为:/var/lib/docker/volumes/mariadb/_data/grastate.dat
可以通过该文件查看到该节点记录的uuid和seqno,也就是上面说的GTID,当节点正常退出Galera集群时,会将GTID的值更新到该文件中。在断电的情况下,所有节点的seqno值可能都相同,此时需根 gvwstate.dat判断启动节点
gvwstate.dat
默认路径为:/var/lib/docker/volumes/mariadb/_data/grastate.dat
此文件保存了集群状态信息
kolla-ansible 恢复脚本原理
Stop MariaDB containers
Run MariaDB wsrep recovery
Stop MariaDB containers
Copying MariaDB log file to /tmp
Get MariaDB wsrep recovery seqno
Removing MariaDB log file from /tmp
Registering MariaDB seqno variable
Comparing seqno value on all mariadb hosts
Writing hostname of host with the largest seqno to temp file
Registering mariadb_recover_inventory_name from temp file
Copying grastate.dat file from MariaDB container in bootstrap host
Set grastate.dat file from MariaDB container in bootstrap host
手动恢复通用流程
- 关闭所有节点mariadb:docker stop mariadb
- 选择启动节点
- 对比所有节点cat /var/lib/docker/volumes/mariadb/_data/grastate.dat中seqno值,若该值在所有节点中存在唯一得最大值,则该节点选为启动节点
- 若seqno最大值相同得节点有多个,则 cat /var/lib/docker/volumes/mariadb/_data/gvwstate.dat文件中view_id和my_uuid相等得节点选为启动节点。
- 手动关闭所有服务器后,gvwstate.dat 文件会自动删除。若grastate.dat文件 seqno最大值不唯一,则在seqno最大的节点中随便选取一个节点作为启动节点。
- 在启动节点上修改配置文件,vim /etc/kolla/mariadb/galera.cnf ,注释原有wsrep_cluster_address。新增 wsrep_cluster_address = gcomm://(表示新集群),保存退出。
- 在启动节点上启动容器,docker start mariadb
- 进入启动节点查看集群状态,注意替换数据库密码:
- docker exec mariadb mysql -u root -p<MYSQL_PASSWORD> -e ‘show global status like “wsrep_%”;’ | grep wsrep_cluster_size 结果应当为 1
- docker exec mariadb mysql -u root -p<MYSQL_PASSWORD> -e ‘show global status like “wsrep_%”;’ | grep wsrep_local_state_comment 结果应当为 Synced
- 待启动节点启动完成以后,再依次启动其它节点(不要一次性启动所有)。
- 启动节点执行 docker exec mariadb mysql -u root -p<MYSQL_PASSWORD> -e ‘show global status like “wsrep_%”;’ | grep wsrep_local_state_comment 结果应该为 donor。
- 耐心等待启动节点完成数据传输,直到 docker exec mariadb mysql -u root -p<MYSQL_PASSWORD> -e ‘show global status like “wsrep_%”;’ | grep wsrep_local_state_comment 结果为 Synced
- 再启动其它节点;在任意已加入集群的节点上执行 docker exec mariadb mysql -u root -p<MYSQL_PASSWORD> -e ‘show global status like “wsrep_%”;’ | grep wsrep_cluster_size 可以看到当前集群的节点数。在所有节点执行 docker exec mariadb mysql -u root -p<MYSQL_PASSWORD> -e ‘show global status like “wsrep_%”;’ | grep wsrep_local_state_comment,执行结果为donor时表示有新节点加入正在同步数据。等待所有节点执行 docker exec mariadb mysql -u root -p<MYSQL_PASSWORD> -e ‘show global status like “wsrep_%”;’ | grep wsrep_local_state_comment 结果都为synced时表示 集群启动成功。
- 待所有节点启动完成以后,回到启动节点,vim /etc/kolla/mariadb/galera.cnf,将wsrep_cluster_address改回原值。
- 在启动节点上, docker stop mariadb(注意:docker restart 可能会出问题,待更多测试)
- 在启动节点上,docker start mariadb
- 随便进入一个节点查看集群状态
kolla-ansible mariadb galera 恢复参考
环境介绍
kolla-ansible部署三节点,机器断电重启时容器会自启
手动关闭所有服务器
参考本页手动恢复流程。
单点宕机
直接启动服务即可,集群会自动同步数据。docker start mariadb
两点宕机
- 剩余节点可使用
直接启动其它节点 - 剩余节点无法使用
参考全宕机恢复
全宕机
- 手动恢复:
参考本页手动恢复流程 - kolla脚本恢复:
登陆部署节点,执行命令 kolla-ansible mariadb_recovery -i /opt/mutinode
全宕机后舍弃某个节点
- 手动恢复:
参考本页手动恢复流程,只要不启动舍弃节点mariadb即可,其它配置无需改动 - kolla脚本恢复:
登陆部署节点,修改mutinode,执行命令kolla-ansible mariadb_recovery -i /opt/mutinode
全宕机后临时启动单节点使用
参考本页手动恢复流程,只需执行到第4步即可临时使用。
FAQ
Unknown/unsupported storage
2018-11-07 17:34:25 140218605119680 [ERROR] InnoDB: space [header](http://www.php.net/header) page consists of zero bytes in data [file](http://www.php.net/file) ./ibdata1 2018-11-07 17:34:25 140218605119680 [ERROR] InnoDB: Could not open or create the [system](http://www.php.net/system) tablespace. If you tried to add new data files to the [system](http://www.php.net/system) tablespace, and it failed here, you should now edit innodb_data_file_path in my.cnf back to what it was, and remove the new ibdata files InnoDB created in this failed attempt. InnoDB only wrote those files full of zeros, but did not yet use them in any way. But be careful: do not remove old data files which contain your precious data! 2018-11-07 17:34:25 140218605119680 [ERROR] Plugin 'InnoDB' init function returned error. 2018-11-07 17:34:25 140218605119680 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed. 2018-11-07 17:34:25 140218605119680 [Note] Plugin 'FEEDBACK' is disabled. 2018-11-07 17:34:25 140218605119680 [ERROR] Could not open [mysql](http://www.php.net/mysql).plugin table. Some plugins may be not loaded 2018-11-07 17:34:25 140218605119680 [ERROR] Unknown/unsupported storage engine: innodb 2018-11-07 17:34:25 140218605119680 [ERROR] Aborting'<\br>
删除ib文件,rm –rf /var/lib/docker/volumes/mariadb/_data/ib_log* (注意,若不生效,删除ib*),重启mariadb
Recovered position 00000000-0000-0000-0000-000000000000:-1
181107 17:34:59 mysqld_safe Starting mysqld daemon with databases from /var/lib/[mysql](http://www.php.net/mysql)/ 181107 17:34:59 mysqld_safe WSREP: Running position recovery with --log_error='/var/lib/mysql//wsrep_recovery.UR5wHx' --pid-[file](http://www.php.net/file)='/var/lib/mysql//kycloud1-recover.pid' 181107 17:36:00 mysqld_safe WSREP: Recovered position 00000000-0000-0000-0000-000000000000:-1 181107 17:38:41 mysqld_safe mysqld from pid [file](http://www.php.net/file) /var/lib/[mysql](http://www.php.net/mysql)/mariadb.pid ended
此信息表示尝试SST传输,但是未成功,可能为集群信息不正确,如已启动节点:vim /etc/kolla/mariadb/galera.cnf中得wsrep_cluster_address未包含此节点。
注意,此步骤可能花费较长时间,未出现ended 都不能确定是否失败。并且kolla自带恢复脚本可能因同步时间过长而报timeout的错误
kolla恢复脚本出错01
日志输出如下信息:
[ERROR] WSREP: failed to open backend connection:131: invalid UUID:00000000 (FATAL)
删除文件 rm /var/lib/docker/volumes/mariadb/_data/gvwstate.dat, 继续执行恢复脚本
使用kolla自带命令恢复失败后,某个节点的mariadb无法加入集群
现象:
此节点的mariadb启动后始终会建立新的集群,无法加入已启动的集群。
原因:kolla选取启动节点后重新run了容器,携带参数BOOTSTRAP_ARGS=–wsrep-new-cluster,此时恢复出现异常(timeout之类),恢复退出但是容器环境变量不正确,所以此容器每次重启都会建立新集群,也会产生恢复命令每次都会选择同一个节点作为启动节点的现象。
解决方案:
- service docker stop 没写错,停止docker服务。
- 设置/var/lib/docker/containers/<container_id>/config.v2.json中的”BOOTSTRAP_ARGS=”(置空即可,原值应当为BOOTSTRAP_ARGS=–wsrep-new-cluster)
- service docker start
参考链接
- 官方文档(数据库集群恢复及相关状态对照)
https://www.penguincomputing.com/documentation/scyld-cloud-manager/admin-guide/admin/galera/intro.html - 官方文档(数据库集群状态)
http://galeracluster.com/documentation-webpages/monitoringthecluster.html - 博客(数据库集群恢复)
https://blog.csdn.net/zengxuewen2045/article/details/51868976 - 博客 (数据库集群恢复)
https://www.cnblogs.com/luohaixian/p/9426359.html - https://www.jianshu.com/p/1dc3a9d01c1d