MongoDB副本集升级、降级及迁移

版本信息

  • 生产环境:3.2.7
  • 测试环境:4.0.11

需求

  • 生产环境需要将MongoDB迁移到3.2.22版本的集群中
  • 生产环境需要升级MongoDB到3.2.22版本,后续可能会升级到更高版本

主要操作步骤

  • 测试环境的MongoDB副本集集群从4.0.11 -> 3.6.23 -> 3.4.24 -> 3.2.7依次进行降级,保证与生产环境的版本一致
  • 新增一套3.2.7版本集群B
  • 将测试环境的MongoDB集群A从3.2.7跨环境同步到另一个3.2.7版本集群B
  • 将测试环境的B集群从3.2.7 -> 3.2.22
  • 将3.2.7集群版本集群B独立出来

降级

为了保证测试环境与生产环境的版本一致性,以便对后续的升级、迁移操作做验证

准备

  • 3.6.23、3.4.24、3.2.22版本的MongoDB安装包

操作步骤

整库备份

mongodump -umongo -p'mongopwd' --host 127.0.0.1:27017 --oplog --authenticationDatabase admin -o /opt/mongoback/mongodump_`date +%Y-%m-%d_%H:%M:%S`

降级操作

参考官方文档:https://www.mongodb.com/docs/v4.0/release-notes/4.0-downgrade-replica-set/

上传或下发MongoDB安装包

# 将3.6.23安装包mongodb-linux-x86_64-rhel70-3.6.23.tgz上传到服务器目录/home
# 解压3.6.23安装包并覆盖原4.0.11的bin目录文件
tar -zxvf /home/mongodb-linux-x86_64-rhel70-3.6.23.tgz

设置参数

/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
# 在主节点设置要降级到的版本,注意不能跨版本降级,提示ok:1即成功
db.adminCommand({setFeatureCompatibilityVersion: "3.6"});
# 确认副本集每个节点都返回以下内容:"featureCompatibilityVersion" : { "version" : "3.6" }
db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
# 移除4.0版本的特性,不涉及

从节点降级步骤

如果多台从节点,重复执行以下命令直至所有节点都降级完成

# 停止副本集的Secondary节点
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf --shutdown
# 备份4.0.11版本的bin目录下文件
cp -r /home/mongodb/bin /home/mongodb/bin_bak
# 覆盖原bin目录下的文件
cp -rf /home/mongodb-linux-x86_64-rhel70-3.6.23/bin /home/mongodb
# 启动mongodb,如果后续需要降级到3.4.X,需要 --setParameter disableLogicalSessionCacheRefresh=true
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf
# 登录mongoshell确认集群状态为SECONDARY且MongoDB的version为3.6.23
/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
rs.status();

主节点降级步骤

# 将3.6.23安装包mongodb-linux-x86_64-rhel70-3.6.23.tgz上传到服务器目录/home
/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
# 主节点强制进行故障转移
rs.stepDown();
# 确认主节点已转移成功,当前机器stateStr:SECONDARY
rs.status();
# 退出shell
exit
# 停止副本集的Secondary节点
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf --shutdown
# 备份4.0.11版本的bin目录下文件
cp -r /home/mongodb/bin /home/mongodb/bin_bak
# 覆盖原bin目录下的文件
cp -rf /home/mongodb-linux-x86_64-rhel70-3.6.23/bin /home/mongodb
# 启动mongodb,如果后续需要降级到3.4.X,需要 --setParameter disableLogicalSessionCacheRefresh=true
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf
# 登录mongoshell确认集群状态为SECONDARY且MongoDB的version为3.6.23
/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
rs.status();

验证

# 登录mongoshell确认集群状态和MongoDB的version为3.6.23
/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
rs.status();
# 启动应用,验证mongo相关功能是否可用

根据操作步骤依次进行降级,直到降级到3.2.7

3.6.23 -> 3.4.24纯净命令

如果出现writer worker caught exception: 12050 cannot delete from system namespace

需要回滚会3.6.X版本,以–setParameter disableLogicalSessionCacheRefresh=true启动后再进行滚动降级

tar -zxvf /home/mongodb-linux-x86_64-rhel70-3.4.24.tgz
# 主节点执行
/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
rs.status();
db.adminCommand({setFeatureCompatibilityVersion: "3.4"});
db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } );
# 从节点执行
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf --shutdown
cp -r /home/mongodb/bin /home/mongodb/bin_bak
cp -rf /home/mongodb-linux-x86_64-rhel70-3.4.24/bin /home/mongodb
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf
/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
rs.status();
# 主节点执行
/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
rs.stepDown();
rs.status();
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf --shutdown
cp -r /home/mongodb/bin /home/mongodb/bin_bak
cp -rf /home/mongodb-linux-x86_64-rhel70-3.4.24/bin /home/mongodb
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf
/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
rs.status();

3.4.24 -> 3.2.7纯净命令

如果启动失败出现:Found an invalid index,执行以下命令,查询v2版本索引,然后对其进行重建,通过db.collectionName.reIndex();

注意:reIndex主从不会同步

db.adminCommand(“listDatabases”).databases.forEach(function(d){ let mdb = db.getSiblingDB(d.name); mdb.getCollectionInfos().forEach(function©{ let currentCollection = mdb.getCollection(c.name); currentCollection.getIndexes().forEach(function(i){ if (i.v === 2){ printjson(i); } }); }); });

其他问题可以通过官方文档进行设置:https://www.mongodb.com/docs/v3.6/release-notes/3.4-downgrade/

tar -zxvf /home/mongodb-linux-x86_64-rhel70-3.2.7.tgz
# 主机节点执行
/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
rs.status();
db.adminCommand({setFeatureCompatibilityVersion: "3.2"});
db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } );
# 从节点执行
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf --shutdown
cp -r /home/mongodb/bin /home/mongodb/bin_bak
cp -rf /home/mongodb-linux-x86_64-rhel70-3.2.7/bin /home/mongodb
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf
/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
rs.status();
# 主节点执行
/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
rs.stepDown();
# 等待主节点切换
rs.status();
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf --shutdown
cp -r /home/mongodb/bin /home/mongodb/bin_bak
cp -rf /home/mongodb-linux-x86_64-rhel70-3.2.7/bin /home/mongodb
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf

降级失败回滚

将bin_bak目录恢复到bin,重新启动即可

迁移

新增一套3.2.7,B集群

重置集群初始信息

# 三台机器依次停机
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf --shutdown
# 三台机器依次清空dbdata下的数据
rm -rf /home/dbdata/mongodb/*
# 三台机器依次启动
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf

在A集群中加入B作为从节点

# 原集群主节点执行add命令
/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
rs.add( { host: "128.177.1.1:27017", priority: 1, votes: 1 } );
rs.add( { host: "128.177.1.2:27017", priority: 1, votes: 1 } );
rs.add( { host: "128.177.1.3:27017", priority: 0, votes: 0 } );
# 查看集群状态,新增的三台机器为STARTUP2
rs.status();
# 此步耗费时间较长,等待新增的三台机器状态变成SECONDARY即完成数据同步
# 数据同步期间,原服务仍可用,但性能较差,因为同步耗费大量的CPU资源

停止应用

切换集群的主节点

# 主节点继续执行命令,切换主节点到B集群,index表示第几台机器,从0开始
config = rs.conf();
config.members[3].priority=2;
rs.reconfig(config);
# 会报错,因为服务在重启,继续执行,待重启后可以查看到当前主节点已经切换成功
rs.status();

移除A集群机器

# 切换后的主节点执行命令,删除原来的三台机器
/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
rs.remove("128.177.2.1:27017");
rs.remove("128.177.2.2:27017");
rs.remove("128.177.2.3:27017");
# 恢复原来priority和votes设置为0的机器
config = rs.conf();
config.members[2].priority=1;
config.members[2].votes=1;
rs.reconfig(config);

升级

备份、解压

tar -zxvf /home/mongodb-linux-x86_64-rhel70-3.2.22.tgz
# 备份3.2.7版本的bin目录下文件
cp -r /home/mongodb/bin /home/mongodb/bin_bak

从节点升级步骤

# 停止副本集的Secondary节点
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf --shutdown
# 覆盖原bin目录下的文件
cp -rf /home/mongodb-linux-x86_64-rhel70-3.2.22/bin /home/mongodb
# 启动mongodb
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf
# 登录mongoshell确认集群状态为SECONDARY且MongoDB的version为3.2.22
/home/mongodb/bin/mongo  
use admin;
db.auth('mongo', 'mongopwd');
rs.status();

主节点升级步骤

# 登录mongoshell
/home/mongodb/bin/mongo
use admin;
db.auth('mongo', 'mongopwd');
# 主节点强制进行故障转移
rs.stepDown();
# 确认主节点已转移成功,当前机器stateStr:SECONDARY
rs.status();
# 退出shell
exit
# 停止副本集的主节点
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf --shutdown
# 覆盖原bin目录下的文件
cp -rf /home/mongodb-linux-x86_64-rhel70-3.2.22/bin /home/mongodb
# 启动mongodb
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf
# 登录mongoshell确认集群状态为SECONDARY且MongoDB的version为3.2.22
/home/mongodb/bin/mongo  
use admin;
db.auth('mongo', 'mongopwd');
rs.status();
# 待主机节点选举成功,启动应用

修改配置中心配置文件

启动应用

恢复移除的集群

# 不用配置启动
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf --shutdown
/home/mongodb/bin/mongod --dbpath=/home/dbdata/mongodb
# 删除其中一个节点的副本集缓存
/home/mongodb/bin/mongo  
use local;
db.dropDatabase();
# 删除另外两个节点的所有数据
rm -rf /home/dbdata/mongodb/*
# 重新启动
/home/mongodb/bin/mongod -f /home/mongodb/mongodb.conf
/home/mongodb/bin/mongo  
use admin;
db.auth('mongo', 'mongopwd');
rs.status();
# 原集群重置
rs.initiate({
   _id : "my-repl",
   members: [
      { _id: 0, host: "128.177.2.1:27017" },
      { _id: 1, host: "128.177.2.2:27017" },
      { _id: 2, host: "128.177.2.3:27017" }
   ]
});