2017-09-26 9 views
0

私はPythonを使って1つのmysqlデータベースから別のmysqlデータベースにデータをパイプしています。マルチプロセッシング。並列サブプロセスを実行してmysqldumpのデータをパイプするためのプール

def copy_table(mytable): 
    raw_mysqldump = "mysqldump -h source_host -u source_user --password='secret' --lock-tables=FALSE myschema mytable" 
    raw_mysql = "mysql -h destination_host -u destination_user --password='secret' myschema" 

    mysqldump = shlex.split(raw_mysqldump) 
    mysql = shlex.split(raw_mysql) 

    ps = subprocess.Popen(mysqldump, stdout=subprocess.PIPE) 
    subprocess.check_output(mysql, stdin=ps.stdout) 
    ps.stdout.close() 
    retcode = ps.wait() 
    if retcode == 0: 
     return mytable, 1 
    else: 
     return mytable, 0 

データのサイズが成長してきた、そしてそれは現在30のようなものをコピーすることについての時間をとります。ここで私はかなりよく働いている、数ヶ月のために使用されているコードの軽く抽象化したバージョンですテーブル。速度を上げるために、私はマルチプロセッシングを利用したいと思います。私はt2.micro(AWS EC2)であるUbuntuサーバーで次のコードを実行しようとしています。

def copy_tables(tables): 
    with multiprocessing.Pool(processes=4) as pool: 
     params = [(arg, table) for table in sorted(tables)] 
     results = pool.starmap(copy_table, params) 
    failed_tables = [table for table, success in results if success == 0] 
    all_tables_processed = False if failed_tables else True 
    return all_tables_processed 

問題がある:ほとんどすべてのテーブルのコピーされますが、それより左の子プロセスのカップルが完了しません常に存在している - 彼らはちょうどハング、と私はデータベースの監視から見ることができるデータなし転送中です。彼らは何とか親プロセスから切断されたか、データが適切に返されていないように感じます。

これは私の最初の質問です。私は具体的かつ簡潔になるように努力しました。事前にお手伝いいただきありがとうございます。詳細をお知らせください。

答えて

1

私は次のコード

ps = subprocess.Popen(mysqldump, stdout=subprocess.PIPE) 
subprocess.check_output(mysql, stdin=ps.stdout) 
ps.stdout.close() 
retcode = ps.wait() 

は、mysqldumpを処理が終了するまで、あなたはパイプを閉じてはならない

ps = subprocess.Popen(mysqldump, stdout=subprocess.PIPE) 
sps = subprocess.Popen(mysql, stdin=ps.stdout) 
retcode = ps.wait() 
ps.stdout.close() 
sps.wait() 

でなければなりません。だと思いますそして、check_outputはブロックしており、stdinが最後まで到達するまでハングします。

+0

ありがとうございました。私はこれを試しましたが、目に見える変化はありませんでした。私は、stdout.close()の目的を理解しています。子プロセスが死んでも、親プロセスにSIGINTを返すようにしてください。 – speedyturkey

+1

@speedyturkey私の間違いは、check_outputがコールをブロックしている、Popenでなければなりません。 – hailinzeng

+0

初期の結果はここで有望です。素晴らしい答え、ありがとう! – speedyturkey

関連する問題