Postgresql并行框架随手记

使用方法

  1. EnterParallelMode()
  2. CreateParallelContext(“library_name”, “function_name”, nworkers)
    1. 指定并发数,bgworker拉起几个进程干活。
  3. shm_toc_estimate_chunk/shm_toc_estimate_keys 评估大小写入pcxt->estimator
    1. 先评估全部要进入共享内存的大小。
  4. InitializeParallelDSM(pcxt)
  5. shm_toc_allocate/shm_toc_insert 写入dsm共享内存
    1. 对应第3步评估大小,把真实数据插进去,并指定key,子进程用的时候用key查询即可。
  6. LaunchParallelWorkers(pcxt)
    1. 拉起bgworker
  7. worker走ParallelWorkerMain函数启动干活
    1. 注意ParallelWorkerMain是框架提供的子进程入口函数,会做很多初始化工作。
    2. 然后调用用户提供的业务逻辑函数,业务逻辑函数由第2步的参数指定。
    3. 可以指定任意so文件中的函数名,走动态加载找到函数。
  8. WaitForParallelWorkersToFinish(pcxt)
  9. DestroyParallelContext(pcxt)
  10. ExitParallelMode()

注意

  1. 共享内存:
    1. bgworker由父进程拉起,与当前进程无任何内存继承关系。进程身份与当前BACKEND对等。
    2. 基于上述,序列化是并行化最大的工作量,PG已经实现大部分结构体的序列化,大部分可以借鉴。
      1. nodeToString:序列化
      2. stringToNode:反序列化
  2. 锁系统:
    1. ParallelWorkerMain中会走BecomeLockGroupMember变成锁group leader,注意,这是为了子进程只读的情况下与同一锁组的其他进程不冲突,在只读情况下这是可行的,因为锁组内的行为都是只读的,与锁组外的锁依然会正常互斥。
  3. 事务系统:
    1. 子进程启动后,全程处于TBLOCK_PARALLEL_INPROGRESS状态,在现有的实现下,这是一种只读状态,如果需要做读写,需要自己DIY放开事务系统的限制(给子进程起好普通事务用于读写,记得最后让并行框架正常提交)。
  4. 进程通信
    1. 使用mq是个很好的选择不用自己实现了,在dsm初始化时顺便分配空间给mq即可,支持阻塞、非阻塞模式;支持flush一般是够用了。
    2. shm_mq_receive、shm_mq_send

你可能感兴趣的:(pgsql,postgresql,数据库,parallel)