第121集MongoDB数据库迁移与运维实战
|字数总计:4.1k|阅读时长:19分钟|阅读量:
1. MongoDB迁移概述
MongoDB数据库迁移是运维工作中的重要环节,涉及数据备份、迁移、验证和集群管理等多个方面。本文将详细介绍MongoDB数据库迁移与运维的实战经验,包括数据迁移策略、备份恢复、集群管理、性能优化的完整解决方案。
1.1 核心功能
- 数据迁移: 不同MongoDB实例间的数据迁移
- 备份恢复: 数据备份和恢复策略
- 集群管理: MongoDB集群的部署、监控和管理
- 性能优化: 数据库性能调优和监控
- 运维自动化: 自动化运维脚本和工具
1.2 技术架构
1 2 3
| 源MongoDB → 数据导出 → 数据转换 → 目标MongoDB → 数据验证 ↓ ↓ ↓ ↓ ↓ 备份策略 → 迁移工具 → 格式转换 → 集群部署 → 一致性检查
|
2. 环境准备
2.1 系统要求检查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| #!/bin/bash
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" }
check_os_version() { log "检查系统版本..." if [ -f /etc/os-release ]; then . /etc/os-release log "操作系统: $NAME $VERSION" else log "无法确定操作系统版本" fi }
check_mongodb_version() { log "检查MongoDB版本..." SOURCE_VERSION=$(mongo --host source-mongodb-server --eval "db.version()" --quiet) log "源MongoDB版本: $SOURCE_VERSION" TARGET_VERSION=$(mongo --host target-mongodb-server --eval "db.version()" --quiet) log "目标MongoDB版本: $TARGET_VERSION" }
check_mongodb_connection() { log "检查MongoDB连接..." if mongo --host source-mongodb-server --eval "db.adminCommand('ping')" --quiet > /dev/null 2>&1; then log "源MongoDB连接正常" else log "源MongoDB连接失败" return 1 fi if mongo --host target-mongodb-server --eval "db.adminCommand('ping')" --quiet > /dev/null 2>&1; then log "目标MongoDB连接正常" else log "目标MongoDB连接失败" return 1 fi }
check_database_size() { log "检查数据库大小..." SOURCE_SIZE=$(mongo --host source-mongodb-server --eval "db.stats().dataSize" --quiet) log "源数据库大小: $SOURCE_SIZE bytes" TARGET_SIZE=$(mongo --host target-mongodb-server --eval "db.stats().dataSize" --quiet) log "目标数据库大小: $TARGET_SIZE bytes" }
main() { log "开始MongoDB环境检查..." check_os_version check_mongodb_version if check_mongodb_connection; then check_database_size else log "MongoDB连接检查失败" exit 1 fi log "MongoDB环境检查完成" }
main "$@"
|
3. 数据备份脚本
3.1 MongoDB备份脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
| #!/bin/bash
SOURCE_HOST="source-mongodb-server" SOURCE_PORT="27017" SOURCE_USER="" SOURCE_PASSWORD="" BACKUP_DIR="/backup/mongodb" LOG_FILE="/var/log/mongodb_backup.log" RETENTION_DAYS=7
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE }
create_backup_dir() { log "创建备份目录..." BACKUP_DATE=$(date +%Y%m%d_%H%M%S) BACKUP_PATH="$BACKUP_DIR/$BACKUP_DATE" mkdir -p $BACKUP_PATH if [ $? -eq 0 ]; then log "备份目录创建成功: $BACKUP_PATH" else log "备份目录创建失败" exit 1 fi }
execute_mongodump() { log "执行mongodump备份..." MONGODUMP_CMD="mongodump --host $SOURCE_HOST:$SOURCE_PORT --out $BACKUP_PATH" if [ -n "$SOURCE_USER" ] && [ -n "$SOURCE_PASSWORD" ]; then MONGODUMP_CMD="$MONGODUMP_CMD --username $SOURCE_USER --password $SOURCE_PASSWORD --authenticationDatabase admin" fi eval $MONGODUMP_CMD if [ $? -eq 0 ]; then log "mongodump备份完成" BACKUP_SIZE=$(du -sh $BACKUP_PATH | awk '{print $1}') log "备份文件大小: $BACKUP_SIZE" else log "mongodump备份失败" exit 1 fi }
compress_backup() { log "压缩备份文件..." cd $BACKUP_DIR tar -czf "${BACKUP_DATE}.tar.gz" $BACKUP_DATE if [ $? -eq 0 ]; then log "备份文件压缩完成" COMPRESSED_SIZE=$(ls -lh "${BACKUP_DATE}.tar.gz" | awk '{print $5}') log "压缩后文件大小: $COMPRESSED_SIZE" rm -rf $BACKUP_DATE else log "备份文件压缩失败" exit 1 fi }
verify_backup() { log "验证备份文件..." BACKUP_FILE="$BACKUP_DIR/${BACKUP_DATE}.tar.gz" if [ -f "$BACKUP_FILE" ]; then log "备份文件存在" if tar -tzf $BACKUP_FILE > /dev/null 2>&1; then log "备份文件完整性验证通过" else log "备份文件完整性验证失败" exit 1 fi else log "备份文件不存在" exit 1 fi }
cleanup_old_backups() { log "清理过期备份..." find $BACKUP_DIR -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete if [ $? -eq 0 ]; then log "过期备份清理完成" else log "过期备份清理失败" fi }
generate_backup_report() { log "生成备份报告..." REPORT_FILE="$BACKUP_DIR/backup_report_${BACKUP_DATE}.txt" echo "MongoDB备份报告" > $REPORT_FILE echo "备份时间: $(date)" >> $REPORT_FILE echo "源主机: $SOURCE_HOST:$SOURCE_PORT" >> $REPORT_FILE echo "备份文件: ${BACKUP_DATE}.tar.gz" >> $REPORT_FILE echo "文件大小: $(ls -lh $BACKUP_DIR/${BACKUP_DATE}.tar.gz | awk '{print $5}')" >> $REPORT_FILE echo "================================" >> $REPORT_FILE log "备份报告生成: $REPORT_FILE" }
main() { log "开始MongoDB备份..." create_backup_dir execute_mongodump compress_backup verify_backup cleanup_old_backups generate_backup_report log "MongoDB备份完成" }
main "$@"
|
4. 数据迁移脚本
4.1 MongoDB迁移脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
| #!/bin/bash
SOURCE_HOST="source-mongodb-server" SOURCE_PORT="27017" SOURCE_USER="" SOURCE_PASSWORD=""
TARGET_HOST="target-mongodb-server" TARGET_PORT="27017" TARGET_USER="" TARGET_PASSWORD=""
MIGRATION_DATABASE="test_db" BACKUP_DIR="/backup/mongodb" LOG_FILE="/var/log/mongodb_migration.log"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE }
check_source_connection() { log "检查源MongoDB连接..." if mongo --host $SOURCE_HOST:$SOURCE_PORT --eval "db.adminCommand('ping')" --quiet > /dev/null 2>&1; then log "源MongoDB连接正常" return 0 else log "源MongoDB连接失败" return 1 fi }
check_target_connection() { log "检查目标MongoDB连接..." if mongo --host $TARGET_HOST:$TARGET_PORT --eval "db.adminCommand('ping')" --quiet > /dev/null 2>&1; then log "目标MongoDB连接正常" return 0 else log "目标MongoDB连接失败" return 1 fi }
export_source_database() { log "导出源数据库..." EXPORT_DIR="$BACKUP_DIR/${MIGRATION_DATABASE}_export" mkdir -p $EXPORT_DIR MONGODUMP_CMD="mongodump --host $SOURCE_HOST:$SOURCE_PORT --db $MIGRATION_DATABASE --out $EXPORT_DIR" if [ -n "$SOURCE_USER" ] && [ -n "$SOURCE_PASSWORD" ]; then MONGODUMP_CMD="$MONGODUMP_CMD --username $SOURCE_USER --password $SOURCE_PASSWORD --authenticationDatabase admin" fi eval $MONGODUMP_CMD if [ $? -eq 0 ]; then log "源数据库导出成功: $EXPORT_DIR" EXPORT_SIZE=$(du -sh $EXPORT_DIR | awk '{print $1}') log "导出文件大小: $EXPORT_SIZE" else log "源数据库导出失败" exit 1 fi }
import_target_database() { log "导入目标数据库..." EXPORT_DIR="$BACKUP_DIR/${MIGRATION_DATABASE}_export" MONGORESTORE_CMD="mongorestore --host $TARGET_HOST:$TARGET_PORT --db $MIGRATION_DATABASE $EXPORT_DIR/$MIGRATION_DATABASE" if [ -n "$TARGET_USER" ] && [ -n "$TARGET_PASSWORD" ]; then MONGORESTORE_CMD="$MONGORESTORE_CMD --username $TARGET_USER --password $TARGET_PASSWORD --authenticationDatabase admin" fi eval $MONGORESTORE_CMD if [ $? -eq 0 ]; then log "目标数据库导入成功" else log "目标数据库导入失败" exit 1 fi }
verify_migration() { log "验证数据迁移..." SOURCE_COLLECTIONS=$(mongo --host $SOURCE_HOST:$SOURCE_PORT --eval "db.getCollectionNames().length" $MIGRATION_DATABASE --quiet) TARGET_COLLECTIONS=$(mongo --host $TARGET_HOST:$TARGET_PORT --eval "db.getCollectionNames().length" $MIGRATION_DATABASE --quiet) log "源数据库集合数量: $SOURCE_COLLECTIONS" log "目标数据库集合数量: $TARGET_COLLECTIONS" if [ $SOURCE_COLLECTIONS -eq $TARGET_COLLECTIONS ]; then log "集合数量验证通过" else log "集合数量验证失败" exit 1 fi SOURCE_DOCS=$(mongo --host $SOURCE_HOST:$SOURCE_PORT --eval "db.stats().objects" $MIGRATION_DATABASE --quiet) TARGET_DOCS=$(mongo --host $TARGET_HOST:$TARGET_PORT --eval "db.stats().objects" $MIGRATION_DATABASE --quiet) log "源数据库文档数量: $SOURCE_DOCS" log "目标数据库文档数量: $TARGET_DOCS" if [ $SOURCE_DOCS -eq $TARGET_DOCS ]; then log "文档数量验证通过" else log "文档数量验证失败" exit 1 fi }
generate_migration_report() { log "生成迁移报告..." REPORT_FILE="$BACKUP_DIR/migration_report.txt" echo "MongoDB数据迁移报告" > $REPORT_FILE echo "迁移时间: $(date)" >> $REPORT_FILE echo "源数据库: $SOURCE_HOST:$SOURCE_PORT/$MIGRATION_DATABASE" >> $REPORT_FILE echo "目标数据库: $TARGET_HOST:$TARGET_PORT/$MIGRATION_DATABASE" >> $REPORT_FILE echo "================================" >> $REPORT_FILE echo "集合信息:" >> $REPORT_FILE mongo --host $TARGET_HOST:$TARGET_PORT --eval "db.getCollectionNames()" $MIGRATION_DATABASE --quiet >> $REPORT_FILE log "迁移报告生成: $REPORT_FILE" }
main() { log "开始MongoDB数据迁移..." if ! check_source_connection; then exit 1 fi if ! check_target_connection; then exit 1 fi export_source_database import_target_database verify_migration generate_migration_report log "MongoDB数据迁移完成" }
main "$@"
|
5. 集群管理脚本
5.1 MongoDB集群部署脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
| #!/bin/bash
CONFIG_SERVERS=( "192.168.1.10:27019" "192.168.1.11:27019" "192.168.1.12:27019" )
SHARD_SERVERS=( "192.168.1.10:27018" "192.168.1.11:27018" "192.168.1.12:27018" )
MONGOS_SERVERS=( "192.168.1.10:27017" "192.168.1.11:27017" "192.168.1.12:27017" )
MONGODB_VERSION="4.4.0" MONGODB_USER="mongodb" MONGODB_HOME="/opt/mongodb" CLUSTER_CONFIG_DIR="/etc/mongodb/cluster"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" }
install_mongodb() { log "安装MongoDB $MONGODB_VERSION..." cd /tmp wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-${MONGODB_VERSION}.tgz tar xzf mongodb-linux-x86_64-${MONGODB_VERSION}.tgz mv mongodb-linux-x86_64-${MONGODB_VERSION} $MONGODB_HOME if [ $? -eq 0 ]; then log "MongoDB安装成功" else log "MongoDB安装失败" exit 1 fi }
create_mongodb_user() { log "创建MongoDB用户..." if ! id $MONGODB_USER &>/dev/null; then useradd -r -s /bin/false $MONGODB_USER log "MongoDB用户创建成功" else log "MongoDB用户已存在" fi }
create_directories() { log "创建目录结构..." mkdir -p $MONGODB_HOME/{bin,conf,data,logs} mkdir -p $CLUSTER_CONFIG_DIR chown -R $MONGODB_USER:$MONGODB_USER $MONGODB_HOME chown -R $MONGODB_USER:$MONGODB_USER $CLUSTER_CONFIG_DIR log "目录结构创建完成" }
generate_config_server_config() { log "生成配置服务器配置文件..." for config_server in "${CONFIG_SERVERS[@]}"; do IFS=':' read -r host port <<< "$config_server" cat > $CLUSTER_CONFIG_DIR/mongod-config-${port}.conf << EOF # MongoDB配置服务器配置文件 storage: dbPath: $MONGODB_HOME/data/config-${port} journal: enabled: true
systemLog: destination: file logAppend: true path: $MONGODB_HOME/logs/mongod-config-${port}.log
net: port: ${port} bindIp: ${host}
processManagement: fork: true pidFilePath: /var/run/mongodb/mongod-config-${port}.pid
replication: replSetName: configReplSet
sharding: clusterRole: configsvr EOF log "配置文件生成: mongod-config-${port}.conf" done }
generate_shard_server_config() { log "生成分片服务器配置文件..." for shard_server in "${SHARD_SERVERS[@]}"; do IFS=':' read -r host port <<< "$shard_server" cat > $CLUSTER_CONFIG_DIR/mongod-shard-${port}.conf << EOF # MongoDB分片服务器配置文件 storage: dbPath: $MONGODB_HOME/data/shard-${port} journal: enabled: true
systemLog: destination: file logAppend: true path: $MONGODB_HOME/logs/mongod-shard-${port}.log
net: port: ${port} bindIp: ${host}
processManagement: fork: true pidFilePath: /var/run/mongodb/mongod-shard-${port}.pid
replication: replSetName: shardReplSet
sharding: clusterRole: shardsvr EOF log "配置文件生成: mongod-shard-${port}.conf" done }
generate_mongos_config() { log "生成mongos配置文件..." for mongos_server in "${MONGOS_SERVERS[@]}"; do IFS=':' read -r host port <<< "$mongos_server" cat > $CLUSTER_CONFIG_DIR/mongos-${port}.conf << EOF # MongoDB mongos配置文件 systemLog: destination: file logAppend: true path: $MONGODB_HOME/logs/mongos-${port}.log
net: port: ${port} bindIp: ${host}
processManagement: fork: true pidFilePath: /var/run/mongodb/mongos-${port}.pid
sharding: configDB: configReplSet/192.168.1.10:27019,192.168.1.11:27019,192.168.1.12:27019 EOF log "配置文件生成: mongos-${port}.conf" done }
start_config_servers() { log "启动配置服务器..." for config_server in "${CONFIG_SERVERS[@]}"; do IFS=':' read -r host port <<< "$config_server" mongod --config $CLUSTER_CONFIG_DIR/mongod-config-${port}.conf if [ $? -eq 0 ]; then log "配置服务器启动成功: $host:$port" else log "配置服务器启动失败: $host:$port" exit 1 fi done }
init_config_replica_set() { log "初始化配置服务器副本集..." sleep 10 mongo --host 192.168.1.10:27019 --eval " rs.initiate({ _id: 'configReplSet', configsvr: true, members: [ {_id: 0, host: '192.168.1.10:27019'}, {_id: 1, host: '192.168.1.11:27019'}, {_id: 2, host: '192.168.1.12:27019'} ] }) " if [ $? -eq 0 ]; then log "配置服务器副本集初始化成功" else log "配置服务器副本集初始化失败" exit 1 fi }
start_shard_servers() { log "启动分片服务器..." for shard_server in "${SHARD_SERVERS[@]}"; do IFS=':' read -r host port <<< "$shard_server" mongod --config $CLUSTER_CONFIG_DIR/mongod-shard-${port}.conf if [ $? -eq 0 ]; then log "分片服务器启动成功: $host:$port" else log "分片服务器启动失败: $host:$port" exit 1 fi done }
init_shard_replica_set() { log "初始化分片服务器副本集..." sleep 10 mongo --host 192.168.1.10:27018 --eval " rs.initiate({ _id: 'shardReplSet', members: [ {_id: 0, host: '192.168.1.10:27018'}, {_id: 1, host: '192.168.1.11:27018'}, {_id: 2, host: '192.168.1.12:27018'} ] }) " if [ $? -eq 0 ]; then log "分片服务器副本集初始化成功" else log "分片服务器副本集初始化失败" exit 1 fi }
start_mongos() { log "启动mongos..." for mongos_server in "${MONGOS_SERVERS[@]}"; do IFS=':' read -r host port <<< "$mongos_server" mongos --config $CLUSTER_CONFIG_DIR/mongos-${port}.conf if [ $? -eq 0 ]; then log "mongos启动成功: $host:$port" else log "mongos启动失败: $host:$port" exit 1 fi done }
add_shards_to_cluster() { log "添加分片到集群..." sleep 10 mongo --host 192.168.1.10:27017 --eval " sh.addShard('shardReplSet/192.168.1.10:27018,192.168.1.11:27018,192.168.1.12:27018') " if [ $? -eq 0 ]; then log "分片添加成功" else log "分片添加失败" exit 1 fi }
verify_cluster() { log "验证MongoDB集群..." mongo --host 192.168.1.10:27017 --eval "sh.status()" mongo --host 192.168.1.10:27017 --eval "db.runCommand({listShards: 1})" log "集群验证完成" }
main() { log "开始MongoDB集群部署..." install_mongodb create_mongodb_user create_directories generate_config_server_config generate_shard_server_config generate_mongos_config start_config_servers init_config_replica_set start_shard_servers init_shard_replica_set start_mongos add_shards_to_cluster verify_cluster log "MongoDB集群部署完成" }
main "$@"
|
6. 总结
MongoDB数据库迁移与运维是运维工作中的重要组成部分。通过本文的详细介绍,我们了解了:
- 数据迁移: 使用mongodump和mongorestore进行数据迁移
- 备份恢复: 数据备份和恢复策略
- 集群管理: MongoDB集群的部署、监控和管理
- 性能优化: 数据库性能调优和监控
- 运维自动化: 脚本化运维提高效率
通过合理的运维策略和工具,可以确保MongoDB数据库的稳定运行和高性能。
运维实战要点:
- 数据迁移前做好备份,确保数据安全
- 集群部署时注意网络配置和防火墙设置
- 定期监控集群状态,及时发现问题
- 性能调优需要根据实际业务场景进行
- 故障处理要有完整的诊断流程
代码注解说明:
- 日志函数: 统一日志格式,便于问题追踪
- 错误处理: 完善的错误检查和异常处理
- 配置管理: 灵活的配置参数管理
- 监控告警: 实时监控和告警机制
- 自动化运维: 脚本化运维提高效率