このトピックでは、ApsaraDB for MongoDB インスタンスのクラウドディスクバックアップファイルから、mongorestore を使用してデータを自己管理 MongoDB データベースに復元する方法について説明します。
背景情報
MongoDB は、公式のバックアップおよび復元ツールとして Mongodump および Mongorestore を提供しています。ApsaraDB for MongoDB は Mongodump を使用して論理バックアップを生成し、そのバックアップを Mongorestore を使用して自己管理 MongoDB データベースに復元できます。
注意事項
-
ご利用の MongoDB データベースと互換性のある mongorestore のバージョンを使用してください。頻繁なアップデートにより、古いバージョンの mongorestore が新しいデータベースバージョンと互換性を持たない場合があります。詳細については、「mongorestore」をご参照ください。
-
コレクションに含まれるデータ量が非常に少なく、BSON ファイルが 1 つだけ(例:
myDatabase/myCollection/data/myCollection_0_part0.bson)であっても、BSON ファイルをマージまたはリネームする必要があります。これは、mongorestoreがファイル名のプレフィックスに基づいて BSON ファイルを処理するためです。 -
クラウドディスクバックアップをダウンロードすると、スキーマが保持された空のコレクションも処理され、データベース名およびコレクション名情報を含む空の BSON ファイルが生成されます。mongorestore ツールは、このような空のファイルを正しく処理できます。
-
シャードクラスターインスタンスの場合、ダウンロードしたクラウドディスクバックアップファイルにはシャーディングルート情報が含まれていません。そのため、バックアップデータをシングルノード、レプリカセット、またはシャードクラスターインスタンスのいずれにも復元できます。シャードクラスターインスタンスにデータを復元する場合は、事前シャーディングを実行する必要があります。
前提条件
-
自己管理 MongoDB データベースをホストするクライアント(ローカルサーバーまたは ECS インスタンス)に、ご利用の ApsaraDB for MongoDB インスタンスのバージョンと一致する MongoDB をインストールしてください。インストール手順については、「Install MongoDB」をご参照ください。
-
論理バックアップファイルをダウンロード済みである必要があります。まだダウンロードしていない場合は、「Download backup files」をご参照ください。
操作手順
-
ダウンロードしたバックアップファイルを、mongorestore ツールおよび自己管理 MongoDB データベースをホストするクライアントにコピーします。
-
バックアップファイルを解凍します。
バックアップファイルは
tar.zstまたはtar.gz形式でダウンロードでき、それぞれ zstd および gzip 圧縮アルゴリズムを使用します。 CreateDownload OpenAPI オペレーションの UseZstd パラメーターを使用してダウンロード形式を選択できます。tar.zst (コンソール)
zstd -d -c <backup_file.tar.zst> | tar -xvf - -C <extraction_directory>クライアントに zstd ツールがインストールされており、解凍先ディレクトリが存在することを確認してください。
例:
mkdir -p ./download_test/test1 zstd -d -c test1.tar.zst | tar -xvf - -C /Users/xxx/Desktop/download_test/test1/tar.gz (API)
tar -zxvf <backup_file.tar.gz> -C <extraction_directory>解凍先ディレクトリが存在することを確認してください。
例:
mkdir -p ./download_test/test1 tar -zxvf testDB.tar.gz -C /Users/xxx/Desktop/download_test/test1/ -
BSON ファイルをマージします。
Python 環境がインストールされたクライアント上で、以下のスクリプトをコピーし、
merge_bson_files.pyとして保存します。import os import struct import sys import argparse import shutil import re # Handle strings for compatibility with both Python 2 and 3 if sys.version_info[0] >= 3: unicode = str def merge_single_bson_dir(input_dir: str, output_dir: str, namespace: str) -> None: """ Merges BSON files within a single directory. Args: input_dir (str): The directory path containing the BSON files. output_dir (str): The directory path for the output file. namespace (str): The name of the output file (without extension). """ try: # Get all BSON files matching the ***_*_part*.bson pattern and sort them by name files = [f for f in os.listdir(input_dir) if re.match(r'^.+_.+_part\d+\.bson$', f)] files.sort() # Sort by filename if not files: print("No matching .bson files found in {}".format(input_dir)) return output_file = os.path.join(output_dir, "{}.bson".format(namespace)) if os.path.exists(output_file): print("Output file {} already exists, skipping...".format(output_file)) return print("Merging {} files into {}...".format(len(files), output_file)) # Stream-read and merge the files total_files = len(files) with open(output_file, "wb") as out_f: for index, filename in enumerate(files, 1): file_path = os.path.join(input_dir, filename) print(" Processing file {}/{}: {}...".format(index, total_files, filename)) try: with open(file_path, "rb") as in_f: while True: # Read the BSON document size size_data = in_f.read(4) if not size_data or len(size_data) < 4: break # Parse the document size (little-endian) doc_size = struct.unpack("<i", size_data)[0] # Reread the complete document data in_f.seek(in_f.tell() - 4) doc_data = in_f.read(doc_size) if len(doc_data) != doc_size: break out_f.write(doc_data) except Exception as e: print("Error reading {}: {}".format(filename, str(e))) except Exception as e: print("Error in merge_single_bson_dir: {}".format(str(e))) def merge_bson_files_recursive(input_root: str, output_root: str = None) -> None: """ Recursively traverses directories and merges all BSON files. Args: input_root (str): The root directory path containing the BSON files. output_root (str): The root directory for the output files, defaults to input_root. """ if output_root is None: output_root = input_root # Ensure the output root directory exists if not os.path.exists(output_root): os.makedirs(output_root) print("Scanning directories in {}...".format(input_root)) # Traverse all items in the input root directory for item in os.listdir(input_root): item_path = os.path.join(input_root, item) # If it is a directory, process it if os.path.isdir(item_path): print("Processing directory: {}".format(item)) # Create the corresponding output directory output_item_path = os.path.join(output_root, item) if not os.path.exists(output_item_path): os.makedirs(output_item_path) # Traverse all subdirectories and files within this directory for item_d in os.listdir(item_path): sub_item_path = os.path.join(item_path, item_d) for sub_item in os.listdir(sub_item_path): data_path = os.path.join(sub_item_path, sub_item) # If it's a "data" directory, merge the BSON files within it if os.path.isdir(data_path) and sub_item == "data": # Extract the namespace (parent directory name) namespace = os.path.basename(sub_item_path) merge_single_bson_dir(data_path, output_item_path, namespace) # If it's a .metadata.json file, copy it directly to the corresponding output directory elif sub_item.endswith(".metadata.json"): src_file = os.path.join(sub_item_path, sub_item) target_dir = os.path.join(output_item_path, sub_item) shutil.copy(src_file, target_dir) print("Copied metadata file: {}".format(sub_item)) print("Finished processing directory: {}".format(item)) if __name__ == "__main__": parser = argparse.ArgumentParser(description="Recursively merge BSON files") parser.add_argument("input_root", help="The root directory path containing the BSON files") parser.add_argument("-o", "--output_root", help="The root directory path for output files, defaults to the input root") args = parser.parse_args() merge_bson_files_recursive(args.input_root, args.output_root)以下のコマンドを実行します。
python merge_bson_files.py <input_directory> -o <output_directory> -
mongorestore ツールを使用して、バックアップデータを自己管理データベースインスタンスに復元します。
# 単一コレクションの復元 mongorestore --uri=<mongodb-uri> --db <db> --collection <collection> <xxx.bson> # 単一コレクションの復元例 mongorestore --uri='mongodb://127.x.x.x:27017/?authSource=admin' --db testDB --collection coll1 ./testDB/coll1.bson # 単一データベースの復元 mongorestore --uri=<mongodb-uri> --db <db> --dir </path/to/bson/dir> # 単一データベースの復元例 mongorestore --uri='mongodb://127.x.x.x:27017/?authSource=admin' --db testDB --dir ./testDB # インスタンス全体の復元 mongorestore --uri=<mongodb-uri> --dir </path/to/bson/dir> # インスタンス全体の復元例 mongorestore --uri='mongodb://127.x.x.x:27017/?authSource=admin' --dir ./パラメーター:
-
<mongodb-uri>:自己管理データベースまたは ApsaraDB for MongoDB インスタンスの接続文字列 URI です。URI にはユーザー名、パスワード、サーバー IP アドレス、ポートが含まれます。詳細については、「official documentation」をご参照ください。
-
<db>:復元するデータベースの名前です。
-
<collection>:復元するコレクションの名前です。
-
<xxx.bson>:復元する単一コレクションの BSON バックアップファイルです。
-
<path/to/bson/dir>:復元操作に使用する BSON ファイルを含むディレクトリです。
-