关于 MPI多进程下的 sql 文件处理时 隐藏比较深的 Bug
需要从目录A的n个数据库合并,合并时字段重复报错。而且这个问题在设置小进程的时候没有出现,设置更多进程就发生了 ...
首先想到是不是给的数据中有重复,但理论上是不可能的。不管怎么样也先打印结果看看。发现文件重复了。
然后看看MPI分配有没有写错
size = comm.Get_size()
data = os.listdir(args.inputs)
input_file = [Path(args.inputs) / f for f in data if f[-4:]=='gpkg']
n_files = len(input_file)
files_per_process = n_files // size
remainder = n_files % size
start_index = rank * files_per_process + min(rank, remainder)
end_index = start_index + files_per_process + (1 if rank < remainder else 0)
assigned_files = input_file[start_index:end_index]
每个进程独立计算自己负责的部分,确实没有问题。
突发奇想
print(rank, len(input_file))
跑了几遍,发现居然有几个进程多了1-2个文件
再看了具体输出,发现gdal有几个不影响运行的 error
ERROR RuntimeError('/12_1281_17.gpkg-shm: No such file or directory')
ERROR RuntimeError('/12_1281_17.gpkg-wal: No such file or directory')
-shm 文件用于多进程间的同步与共享内存管理
-wal 文件用于保证数据库事务的持久性和高效性
所以是有些进程在其他进程还没 os.listdir(args.inputs)
就在处理数据库数据了
那解决了,在os.listdir(args.inputs)
后 comm.Barrier()
就ok了。
日后谈
这个问题其实可以扩展到并行程序涉及临时文件创建的操作,以前帮同事处理过类似问题,然而这次因不熟悉sql的工作流程,花了不少时间。