You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go语言中基于mongodriver使用mongodump与mongorestore命令

Go 基于 mongo-go-driver 调用 mongodump/mongorestore 实现方案

官方 mongo-go-driver 没有内置 mongodump、mongorestore 的原生调用接口。这两个能力属于MongoDB独立发布的命令行工具集,不属于驱动层实现范畴,生产环境可行的方案是通过Go标准库os/exec调用对应命令行二进制,同时可以直接复用mongo driver初始化时的连接配置,避免重复维护连接参数。

前置依赖

  • 运行Go程序的服务器/容器内,提前安装和Mongo实例版本匹配的MongoDB Database Tools,确保mongodump、mongorestore可执行文件在系统PATH中,或者在代码中指定二进制的绝对路径
  • 连接MongoDB使用的账号,提前分配对应权限:执行mongodump需要目标库的读权限,执行mongorestore需要目标库的写、集合创建、索引创建权限

具体实现

1. 复用driver连接参数,避免硬编码

如果你已经通过mongo driver完成了客户端初始化,可以直接从客户端配置中提取连接信息,不需要手动拆分连接串:

package main

import (
	"context"
	"fmt"
	"os/exec"
	"time"

	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.mongodb.org/mongo-driver/mongo/readpref"
)

// 存储Mongo连接配置,供dump/restore调用
type MongoConfig struct {
	Host     string
	Port     int
	Username string
	Password string
	AuthDB   string
}

var mongoConf MongoConfig

func initMongoClient(uri string) (*mongo.Client, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	clientOpts := options.Client().ApplyURI(uri)
	client, err := mongo.Connect(ctx, clientOpts)
	if err != nil {
		return nil, err
	}
	if err = client.Ping(ctx, readpref.Primary()); err != nil {
		return nil, err
	}
	// 从解析后的配置中提取连接参数
	mongoConf.Host = clientOpts.Hosts[0].Host
	mongoConf.Port = int(clientOpts.Hosts[0].Port)
	if clientOpts.Auth != nil {
		mongoConf.Username = clientOpts.Auth.Username
		mongoConf.Password = clientOpts.Auth.Password
		if clientOpts.Auth.AuthSource != "" {
			mongoConf.AuthDB = clientOpts.Auth.AuthSource
		} else {
			// 未指定auth源时默认用admin
			mongoConf.AuthDB = "admin"
		}
	}
	return client, nil
}

2. 调用mongodump实现备份

// MongoDump 执行mongodump备份
// dbName: 要备份的库名,传空则备份全实例
// collectionName: 要备份的集合名,传空则备份整个库
// outputPath: 备份文件输出目录
func MongoDump(dbName, collectionName, outputPath string) error {
	// 组装命令参数
	args := []string{
		"--host", mongoConf.Host,
		"--port", fmt.Sprintf("%d", mongoConf.Port),
		"-u", mongoConf.Username,
		"-p", mongoConf.Password,
		"--authenticationDatabase", mongoConf.AuthDB,
		"-o", outputPath,
	}
	if dbName != "" {
		args = append(args, "-d", dbName)
	}
	if collectionName != "" {
		args = append(args, "-c", collectionName)
	}
	// 超时时间根据备份数据量调整,示例配置1小时
	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Hour)
	defer cancel()
	cmd := exec.CommandContext(ctx, "mongodump", args...)
	// 捕获标准输出和错误输出,方便排查问题
	cmdOutput, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("mongodump执行失败: %w, 输出日志: %s", err, string(cmdOutput))
	}
	return nil
}

3. 调用mongorestore实现恢复

// MongoRestore 执行mongorestore恢复
// dbName: 要恢复到的目标库名
// inputPath: 备份文件所在路径
// drop: 恢复前是否删除已存在的集合
func MongoRestore(dbName, inputPath string, drop bool) error {
	args := []string{
		"--host", mongoConf.Host,
		"--port", fmt.Sprintf("%d", mongoConf.Port),
		"-u", mongoConf.Username,
		"-p", mongoConf.Password,
		"--authenticationDatabase", mongoConf.AuthDB,
	}
	if dbName != "" {
		args = append(args, "-d", dbName)
	}
	if drop {
		args = append(args, "--drop")
	}
	// 最后追加备份路径参数
	args = append(args, inputPath)

	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Hour)
	defer cancel()
	cmd := exec.CommandContext(ctx, "mongorestore", args...)
	cmdOutput, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("mongorestore执行失败: %w, 输出日志: %s", err, string(cmdOutput))
	}
	return nil
}

注意事项

  • 不要尝试自己实现dump/restore逻辑:BSON格式解析、索引一致性、事务快照等逻辑复杂度极高,官方工具已经做了全量兼容,自行实现很容易出现备份损坏、数据不一致的问题
  • 如果是副本集、分片集群场景,只需要在参数里追加--replicaSet等对应配置参数即可,参数提取逻辑和host等字段一致,副本集多节点场景把hosts列表拼接为逗号分隔的字符串传入即可
  • 大库备份/恢复时一定要设置合理的超时时间,不要用默认短超时导致命令被中途终止
  • 安全要求高的生产环境不要把密码明文放在命令参数中,可以通过--stdin参数传递密码,避免密码出现在进程列表中
  • 执行命令的运行用户需要对备份输出目录、备份输入路径有完整读写权限

内容的提问来源于stack exchange,提问作者TheLegenD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:21:36