multiprocessing.Pool执行并发子进程来管道来自mysqldump

时间:2017-09-26 01:06:53

标签: mysql subprocess python-multiprocessing

我使用Python将数据从一个mysql数据库传输到另一个mysql数据库。这是一个轻微抽象的代码版本,我已经使用了几个月,它运行得相当不错:

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 个答案:

答案 0 :(得分:1)

我认为以下代码

    Arrays.sort(array);
    int counter = 0; 
    for(int i = 1; i<array.length; i++) {
        if(array[i] == array[i-1]) {
            counter++;
            ++i;
        }
    }
    return counter;

应该是

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

在mysqldump进程完成之前,不应关闭管道。并且check_output被阻塞,它将一直挂起,直到stdin到达终点。