sql >> データベース >  >> NoSQL >> MongoDB

MongoDBでデータを移行する方法

    この投稿の目的は、MongoDBでのデータ移行のさまざまな方法について学習することです。これにより、新しいドキュメントを追加したり、既存のドキュメントを変更したりして、データベースを変更するスクリプトを作成できます。

    初めてここに来る場合は、前編のSelf-HostedMongoDBをご覧ください。

    それでは、中断したところから選んで、MongoDBでのデータ移行を始めましょう。

    これで、あるMongoDBから別のMongoDBにデータを移行するための基本的な手順は次のようになります。

    1. 既存のデータのzipバックアップを作成する
    2. 新しいDBにデータをダンプします

    移行プロセス中に新しいドキュメントが作成/更新されないことがわかっているため、ソースデータベースがオンラインでない場合、これは非常に簡単です。実際のシナリオに入る前に、まず単純な移行を見てみましょう。

    MongoDBのオフラインデータベースからの移行

    バックアップの作成

    データベースのバックアップを作成するには、既存のユーティリティプログラムmongodumpを使用します。

    ソースデータベースサーバーでこのコマンドを実行します

    mongodump --host="hostname:port" \
      --username="username" --password="password" \
      --authenticationDatabase "admin" \
      --db="db name" --collection="collection name" --query='json' \
      --forceTableScan -v --gzip --out ./dump

    -ホスト :ソースMongoDBホスト名とポート。デフォルトはlocalhost:27017です。 。接続文字列の場合は、このオプションを使用できます —-uri ="mongodb:// username:password @ host1 [:port1] ..."

    -ユーザー名 :認証を使用するMongoDBデータベースに対して認証するユーザー名を指定します。

    -パスワード :認証を使用するMongoDBデータベースに対して認証するためのパスワードを指定します。

    -authenticationDatabase :指定された-usernameがある認証データベースを指定します 作成されました。

    認証データベースまたはエクスポートするデータベースを指定しない場合、mongodumpはadminデータベースがユーザーの資格情報を保持していると見なします。

    -db :バックアップを取得するデータベースを指定します。データベースを指定しない場合、mongodumpはこのインスタンスのすべてのデータベースから収集します。

    または、URI接続文字列でデータベースを直接指定することもできます。例: mongodb:// username:password @ uri / dbname
    -dbを使用しながら接続文字列を提供する 競合する情報を指定すると、エラーが発生します

    -コレクション :バックアップするコレクションを指定します。コレクションを指定しない場合、このオプションは、指定されたデータベースまたはインスタンス内のすべてのコレクションをダンプファイルにコピーします。

    -クエリ :mongodumpの出力に含まれるドキュメントをオプションで制限するクエリとしてJSONドキュメントを提供します。
    クエリドキュメントは一重引用符で囲む必要があります('{...}') 環境と相互作用しないようにするため。
    クエリは、拡張JSON v2形式(リラックスモードまたは正規/厳密モード)である必要があります。これには、フィールド名と演算子を引用符で囲むことも含まれます。 '{"created_at":{"\ $ gte":ISODate(...)}}'

    -queryを使用するには オプションの場合は、-collectionも指定する必要があります オプション。

    -forceTableScan :mongodumpにデータストアを直接スキャンするように強制します。通常、mongodumpは、エントリを _idのインデックスに表示されるとおりに保存します。 分野。

    クエリを指定した場合--query 、mongodumpは、そのクエリをサポートするために最も適切なインデックスを使用します。
    したがって、-forceTableScanは使用できません -queryを使用 オプション

    -gzip :出力を圧縮します。 mongodumpがダンプディレクトリに出力する場合、新しい機能は個々のファイルを圧縮します。ファイルには接尾辞.gzが付いています 。

    --out :mongodumpが BSONを書き込むディレクトリを指定します ダンプされたデータベースのファイル。デフォルトでは、mongodumpは出力ファイルを現在の作業ディレクトリのdumpという名前のディレクトリに保存します。

    バックアップの復元

    mongorestoreというユーティリティプログラムを使用します データベースのバックアップを復元するため。

    バックアップディレクトリダンプを新しいデータベースインスタンスにコピーし、次のコマンドを実行します。

    mongorestore --uri="mongodb://user:password@host:port/?authSource=admin" \
      --drop --noIndexRestore --gzip -v ./dump

    クレデンシャルを新しいデータベースクレデンシャルに置き換えます。前の手順である--authenticationDatabaseの行を解除します オプションはURI文字列で指定されます。

    また、-gzipを使用します バックアップの作成中に使用した場合。

    -ドロップ :ダンプされたバックアップからコレクションを復元する前に、ターゲットデータベースからコレクションを削除します。バックアップにないコレクションは削除されません。-noIndexRestore :対応するmongodump出力で指定されているように、mongorestoreがインデックスを復元および構築できないようにします。

    復元中にデータベースの名前を変更する場合は、
    -nsFrom="old_name。*"--nsTo="new_name。*"を使用して変更できます。 オプション。

    ただし、 oplogsを使用して移行する場合は機能しません これは、オンラインインスタンスからの移行の要件です。

    MongoDBのオンラインデータベースからの移行

    オンラインデータベースからの移行に関する唯一の課題は、移行中に更新を一時停止できないことです。手順の概要は次のとおりです

    1. oplogsを使用して最初の一括移行を実行します キャプチャ
    2. 同期ジョブを実行して、データベース接続スイッチの遅延を軽減します

    次に、 oplogsをキャプチャします 、レプリカセットは、ソースデータベースと宛先データベースで初期化する必要があります。これは、 oplogsが原因です。 local.oplog.rsからキャプチャされます 名前空間。レプリカセットを初期化した後に作成されます。

    このガイドに従って、レプリカセットを構成できます。

    Oplogキャプチャを使用した初期移行

    Oplogは、簡単に言うと、データベース内の操作ごとに作成される操作ログです。これらは、部分的なドキュメントの状態、つまりデータベースの状態を表します。したがって、これらの oplogs を使用して、移行プロセス中に古いデータベースの更新をキャプチャします。 。

    次のオプションを使用してmongodumpプログラムを実行します。

    mongodump --uri=".../?authSource=admin" \
      --forceTableScan --oplog \
      --gzip -v --out ./dump

    -oplog oplog.bsonという名前のファイルを作成します mongodumpの一部として 出力。 oplog.bson 出力ディレクトリの最上位にあるファイルには、 oplogが含まれています mongodump操作中に発生するエントリ。このファイルは、データベースインスタンスの状態の効果的なPOSスナップショットを提供します。

    oplogリプレイでデータを復元する

    oplogを再生するには、特別な役割が必要です。ロールを作成して、移行に使用されているデータベースユーザーに割り当てましょう。

    役割を作成する

    db.createRole({
      role: "interalUseOnlyOplogRestore",
      privileges: [
        {
          resource: { anyResource: true },
          actions: [ "anyAction" ] 
        }
      ],
      roles: []
    })

    役割を割り当てます

    db.grantRolesToUser(
      "admin",
      [{ role:"interalUseOnlyOplogRestore", db:"admin" }]
    );

    これで、次のオプションを指定してmongorestoreプログラムを使用して復元できます。

    mongorestore --uri="mongodb://admin:.../?authSource=admin" \
      --oplogReplay 
      --gzip -v ./dump

    上記のコマンドで、同じユーザー adminを使用します 役割が関連付けられた人。

    -oplogReplay :データベースダンプを復元した後、bsonファイルからoplogエントリを再生し、mongodump -oplogでキャプチャされたポイントインタイムバックアップにデータベースを復元します。 コマンド。

    データベース接続スイッチの遅延の軽減

    了解しました。これまでのところ、手間のかかる作業のほとんどは完了です。残っているのは、アプリケーションサーバーの接続切り替え中にデータベース間の一貫性を維持することだけです。

    MongoDBバージョン3.6以降を実行している場合は、データベース内の変更を最適化された方法でキャプチャするために導入されたイベントベースのメカニズムであるChangeStreamアプローチを使用することをお勧めします。これをカバーする記事がありますhttps://www.mongodb.com/blog/post/an-introduction-to-change-streams

    毎分CRONジョブとして実行できる汎用同期スクリプトを確認してください。

    このスクリプトの変数を更新し、次のように実行します

    $ ./delta-sync.sh from_epoch_in_milliseconds
    
    # from_epoch_in_milliseconds is automatically picked with every iteration if not supplied

    または、これを毎分実行するようにcronジョブを設定できます。

    * * * * * ~/delta-sync.sh

    次のコマンドで出力を監視できます(RHEL 8を実行しています。cron出力については、OSガイドを参照してください)

    $ tail -f /var/log/cron | grep CRON

    これはサンプルの同期ログです。

    CMD (~/cron/dsync.sh)
    CMDOUT (INFO: Updated log registry to use new timestamp on next run.)
    CMDOUT (INFO: Created sync directory: /home/ec2-user/cron/dump/2020-11-03T19:01:01Z)
    CMDOUT (Fetching oplog in range [2020-11-03T19:00:01Z - 2020-11-03T19:01:01Z])
    CMDOUT (2020-11-03T19:01:02.319+0000#011dumping up to 1 collections in parallel)
    CMDOUT (2020-11-03T19:01:02.334+0000#011writing local.oplog.rs to /home/ec2-user/cron/dump/2020-11-03T19:01:01Z/local/oplog.rs.bson.gz)
    CMDOUT (2020-11-03T19:01:04.943+0000#011local.oplog.rs  0)
    CMDOUT (2020-11-03T19:01:04.964+0000#011local.oplog.rs  0)
    CMDOUT (2020-11-03T19:01:04.964+0000#011done dumping local.oplog.rs (0 documents))
    CMDOUT (INFO: Dump success!)
    CMDOUT (INFO: Replaying oplogs...)
    CMDOUT (2020-11-03T19:01:05.030+0000#011using write concern: &{majority false 0})
    CMDOUT (2020-11-03T19:01:05.054+0000#011will listen for SIGTERM, SIGINT, and SIGKILL)
    CMDOUT (2020-11-03T19:01:05.055+0000#011connected to node type: standalone)
    CMDOUT (2020-11-03T19:01:05.055+0000#011mongorestore target is a directory, not a file)
    CMDOUT (2020-11-03T19:01:05.055+0000#011preparing collections to restore from)
    CMDOUT (2020-11-03T19:01:05.055+0000#011found collection local.oplog.rs bson to restore to local.oplog.rs)
    CMDOUT (2020-11-03T19:01:05.055+0000#011found collection metadata from local.oplog.rs to restore to local.oplog.rs)
    CMDOUT (2020-11-03T19:01:05.055+0000#011restoring up to 4 collections in parallel)
    CMDOUT (2020-11-03T19:01:05.055+0000#011replaying oplog)
    CMDOUT (2020-11-03T19:01:05.055+0000#011applied 0 oplog entries)
    CMDOUT (2020-11-03T19:01:05.055+0000#0110 document(s) restored successfully. 0 document(s) failed to restore.)
    CMDOUT (INFO: Restore success!)

    oplogs がなくなったことを確認した後、このスクリプトを停止できます。 作成中です。つまり、ソースDBがオフラインになったときです。

    これで、完全なセルフホストのMongoDBデータ移行ガイドは終わりです。 MongoDBの詳細については、goLangでMongoDBをデータソースとして使用する方法に関する役立つリソースをご覧ください。


    1. あるコレクションから別のコレクションへのmongoコピー(同じデータベース上)

    2. MongoDb-タイプをIntからDoubleに変更します

    3. ClusterControlを使用したエージェントレスデータベースモニタリング

    4. Node.js + MongoDB:1つ挿入して、新しく挿入されたドキュメントを返します