2017-09-26 54 views
0

我正在使用Python將數據從一個mysql數據庫傳送到另一個。下面是我一直在使用數月之久,其代碼輕輕抽象的版本,這得不錯:multiprocessing.Pool執行從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表。爲了加快速度,我想利用多處理。我試圖在Ubuntu服務器上執行以下代碼,該服務器是t2.micro(AWS EC2)。

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() 

應該

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

你不應該關閉該管道,直到mysqldump的過程中完成。 check_output被阻塞,它會掛起,直到stdin達到結尾。

+0

謝謝。我試過了,沒有發現可觀察到的變化。我理解stdout.close()的目的是 - 如果子進程死亡,請確保將SIGINT返回給父進程。 – speedyturkey

+1

@speedyturkey我的錯誤,check_output阻塞呼叫,應該是Popen。 – hailinzeng

+0

早期的結果看起來很有希望。神奇的答案,謝謝! – speedyturkey