DB(MySQL)をネットワーク越しに簡単にコピーする。mysqldump + パイプで。python subprocess の例も

本番環境のデータベース(MySQL)をネットワーク越しに開発環境にコピーしたい時のプラクティスです。

シェル + パイプ

よくやるのが、bash等 でパイプを使って流し込む方法です。

$ ssh user@production.example.com mysqldump \
--skip-lock-tables \
--host=xxxx.rds.amazonaws.com \
--user=xxxx \
--password=xxxx \
database_name table_name | \
ssh user@dev.example.com mysql \
--host=127.0.0.1 \
--user=xxxx \
--password=xxxx \
--database=xxxx

ssh で本番サーバ user@production.example.com に接続し、mysqldump を実行。その標準出力を SSH 接続を通して手元まで持ってきます。

ssh でもう一つ、開発環境サーバ user@dev.example.com に SSH接続し、mysql を起動。先ほどの本番環境の mysqldump 結果をパイプでそのまま流し込みます。

速度が充分に早く、通信経路も ssh で暗号化されるため安全に、効率良くコピーできます。mysql に余計な穴を空ける必要もありません。

mysqldump のオプションで --where を付けて読み込むデータを絞り込んだりもできます。

Python subprocess を使う

subprocess shell=True で実行

(あまり面白くない。読みにくい。)

import subprocess
subprocess.check_call("上記のコマンド", shell=True)

subprocess で、Popen や check_call などの引数に shell=True を与えることで、シェルコマンドをそのまま実行できます。

subprocess のパイプを使う (おすすめ)

subprocess でシェルのパイプと同様の処理が行えます。

dump_command = [
"ssh",
"user@production.example.com",
"mysqldump",
"--skip-lock-tables",
"--host=xxxx.rds.amazonaws.com",
"--user=xxxx",
"--password=xxxx",
"database_name",
"table_name",
]
dump_process = subprocess.Popen(
dump_command, stdout=subprocess.PIPE)

import_command = [
"ssh",
"user@dev.example.com",
"mysql",
"--host=127.0.0.1",
"--user=xxxx",
"--password=xxxx",
"--database=xxxx",
]
import_process = subprocess.Popen(
import_command, stdout=subprocess.PIPE, stdin=dump_process.stdout)

stdout, stderr = import_process.communicate()

ダンププロセスの stdout を インポートプロセスの stdin に接続して 2 つのプロセスを実行します。

Python のコードにしておけば、再利用性・メンテナンス性を高くでき、使い回しに優れます。

Django のデータベースコネクションを使う場合

from django.db.transaction import get_connection

dump_command = [
"ssh",
"user@production.example.com",
"mysqldump",
"--skip-lock-tables",
"--host=xxxx.rds.amazonaws.com",
"--user=xxxx",
"--password=xxxx",
"database_name",
"table_name",
]
dump_process = subprocess.Popen(
dump_command, stdout=subprocess.PIPE)

connection = get_connection(using='db_alias_name')
cursor = connection.cursor()

cursor.execute(dump_process.stdout.read())

ダンプコマンドの結果を read() して、そのまま Django データベース接続の cursor で流し込むこともできます。

※ダンプ結果を一旦メモリにためるため、データ量が多い場合ちゃんと動くかは不安です。そして他の例より効率は悪そうです。

Currently unrated

コメント

コメントを投稿
コメントするには TORICO-ID にログインしてください。
ログイン コメント利用規約
Search

Recent Tweets

  • ytyng

    ytyng @ytyng

    https://t.co/fmpb7cEcr8 シオリエクスペリエンスイベントのドリンク注文特典のコースターめっちゃいいね…顔のチョイスいいね…すげーいい…
    20 hours, 18 minutes ago

  • ytyng

    ytyng @ytyng

    #ダンディナイト 2日間お疲れ様でした!照明、PA、映像配信オペレーターしました。漫画家の先生方やすごいアーティストの方々とイベントできてとても楽しかったです!
    1 week, 4 days ago

  • 濱田潤

    濱田潤 @hamada_TORICO

    ytyng

    #ダンディナイト ・ワン 閉幕。 2日間たくさんの皆様にご来場いただき、ライブ配信でもご参加いただき本当にありがとうございました! 多忙な中イベントにご参加いただいた参加メンバーの皆様にも改めて心から感謝!感謝!! ワンがあ… https://t.co/8RnqWWaDQW
    1 week, 4 days ago

  • 安藤拓郎 TAKURO ANDO

    安藤拓郎 TAKURO ANDO @takuroando

    ytyng

    #ダンディナイト ライブありトークありドローイングありカレーありコーヒーあり、こういうのやりたかったってイベントやらせていただいた。関係者の皆様、来場いただいた皆様、ありがとうございました! #池袋虜 https://t.co/qIAs2Gfmnr
    1 week, 4 days ago

  • マンガ展/TORICO

    マンガ展/TORICO @manga10_torico

    ytyng

    🎊【DANDY NIGHT.1/#ダンディナイト ・ワン】produced by #ダンディさん🎊 DAY2ライブデーオープン🎊 初日ご来場の方もそうでない方もぜひ #池袋虜 にお越し下さいませ〜😘 ライブドローイングやミュー… https://t.co/uzk8zeS2kB
    1 week, 5 days ago