Greenplum的OLTP实现,就配置层面来说,就是打开了分布式死锁检测。
在Greenplum 6之前,greenplum里执行dml会带着全表写锁执行,既然是表级别锁,那么就无所谓并行了,也无从谈起OLTP。
从Greenplum 6 开始,出现了一个默认关闭的参数:gp_enable_global_deadlock_detector,这个参数如果设置为on,那么dml操作的时候,执拿的就不是表级别锁而是行锁,也就代表着,”OLTP“在greenplum上的执行成为了可能。
首先来看这个设置在源码哪些位置生效:
guc_gp.c:
gp_enable_global_deadlock_detector 参数默认设置为false
execMain.c:
InitPlan:
对于update,delete分区表的分区来说,如果gp_enable_global_deadlock_detector设置on,那么就不需要单独设置锁,变更lockmode为NoLock
对于gp_enable_global_deadlock_detector为off的情况,update,delete会直接加排他锁,而insert是加行锁
EvalPlanQual:主要用于检查被修改的行,在read commited隔离级别下是否有必要重新去读
对于gp_enable_global_deadlock_detector为on的情况,由于降级锁等级(排他锁变行锁)导致EvalPlanQual重新调度,这样会出现问题,因此直接报错。
gddbackend.c:
GlobalDeadLockDetectorStartRule:
设置全局死锁检查的状态,实际上关联到的,是postmaster.c的初始化列表,调用GlobalDeadLockDetectorMain启动死锁检测
GlobalDeadLockDetectorMain:
设置信号响应,调用GlobalDeadLockDetectorLoop启动。
BackgroundWorkerInitializeConnection(DB_FOR_COMMON_ACCESS):连接到postgres数据库
GlobalDeadLockDetectorLoop:
这里主要是处理信号带来的参数变更,以及死锁检查调用doDeadLockCheck,超时相关的设置等。
doDeadLockCheck:
buildWaitGraph 根据当前事务创建等待的图(一般是有向无环图)
GddCtxReduce 检查图中是否有死锁
heapam.c:
CdbTryOpenRelation:使用指定的锁模式打开表
对于节点为dispatcher节点,gp_enable_global_deadlock_detector为off,或者表是append形式的情况,锁模式设置为排他锁。
nodeModifyTable.c:
ExecDelete:
对于生成(greenplum会切割update主键的语句)的delete语句,直接报错为concurrent updates distribution keys on the same row is not allowed
以上,就是Greenplum如何做到”OLTP“的相关调整了。
另外,虽说实现了OLTP,但测试数据来说,我无论如何都做不到官方给出的案例case的性能 greenplum-6-oltp-60x:
文中场景:google云一个master主机和四个segment主机,master 48核,segment 8核,pgbench100仓库,最终数据是主键查询最高8w,tpcb 4k。
我的场景:48核物理机器单机内kvm虚拟机,全ssd存储,划分24核给master,另外划分4个segment,每个segment分4核,pgbench并行64,128,50个仓库。主键查询tps(每个事务为一个select语句),最大6k多。tpcb(postgresql自带的pgbench),最大300。
因为数据距离预期差别太大,目前还在进一步调优中,就不出测试报告了。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




