Greenplum max_prepared_transactions 设置不正确时的症状 - too many clients already

简介:

背景

Greenplum分布式事务使用2PC提交,因此需要依赖max_prepared_transactions参数的配置。

原文

https://www.cnblogs.com/chenminklutz/p/8946269.html

max_prepared_transactions 应该至少设置为 max_connections 一样大。

正文

max_prepared_transactions是greenplum的一个参数,以下是官方文档

Sets the maximum number of transactions that can be in the prepared state simultaneously. Greenplum uses prepared transactions internally to ensure data integrity across the segments. This value must be at least as large as the value of max_connections on the master. Segment instances should be set to the same value as the master.

Value Range Default Set Classifications
integer 250 on master 
250 on segments
local 
system 
restart

参数类型:本地,系统级,需要重启生效。

当这个参数设置的足够小时,如果max_prepared_transactions使用耗尽,会报错如下:

FATAL: sorry, too many clients already.  
DETAIL: There are no more available slots in the sharedSnapshotArray.  
HINT: Another piece of code should have detected that we have too many clients.this probably means that someone isn't releasing their slot properly.  

然后其他人就连不上数据库。

开始解决问题:

查看数据库状态,gpstate -s

正常,segment没有挂

但是发现master current role变成了utility,正常应该是是dispatch啊。

肯定有问题,继续找。

手动pg_terminate_backend()最早的30个进程,正常啦,master current role也回去了,其他人也能连上了。

过一会儿又不行啦。

上源码搜sharedSnapshotArray,发现如下判断就会报这个错

    if (arrayP->numSlots >= arrayP->maxSlots || arrayP->nextSlot == -1)  
    {  
        /*  
         * Ooops, no room.  this shouldn't happen as something else should have  
         * complained if we go over MaxBackends.  
         */  
        LWLockRelease(SharedSnapshotLock);  
        ereport(FATAL,  
                (errcode(ERRCODE_TOO_MANY_CONNECTIONS),  
                 errmsg("sorry, too many clients already."),  
                 errdetail("There are no more available slots in the sharedSnapshotArray."),  
                 errhint("Another piece of code should have detected that we have too many clients."  
                         " this probably means that someone isn't releasing their slot properly.")));  
    }  

继续顺藤摸瓜搜maxSlots,看是怎么确定的值。

        /*  
         * We're the first - initialize.  
         */  
        sharedSnapshotArray->numSlots = 0;  
  
        /* TODO:  MaxBackends is only somewhat right.  What we really want here  
         *        is the MaxBackends value from the QD.  But this is at least  
         *          safe since we know we dont need *MORE* than MaxBackends.  But  
         *        in general MaxBackends on a QE is going to be bigger than on a  
         *          QE by a good bit.  or at least it should be.  
         *  
         * But really, max_prepared_transactions *is* what we want (it  
         * corresponds to the number of connections allowed on the  
         * master).  
         *  
         * slotCount is initialized in SharedSnapshotShmemSize().  
         */  
        sharedSnapshotArray->maxSlots = slotCount;  
        sharedSnapshotArray->nextSlot = 0;  
  
        sharedSnapshotArray->slots = (SharedSnapshotSlot *)&sharedSnapshotArray->xips;  
  
        /* xips start just after the last slot structure */  
        xip_base = (TransactionId *)&sharedSnapshotArray->slots[sharedSnapshotArray->maxSlots];  

继续slotCount,上边有注释说slotCount在SharedSnapshotShmemSize里被初始化

/*  
 * Report shared-memory space needed by CreateSharedSnapshot.  
 */  
Size  
SharedSnapshotShmemSize(void)  
{  
    Size        size;  
  
    xipEntryCount = MaxBackends + max_prepared_xacts;  
  
    slotSize = sizeof(SharedSnapshotSlot);  
    slotSize += mul_size(sizeof(TransactionId), (xipEntryCount));  
    slotSize = MAXALIGN(slotSize);  
  
    /*  
     * We only really need max_prepared_xacts; but for safety we  
     * multiply that by two (to account for slow de-allocation on  
     * cleanup, for instance).  
     */  
    slotCount = NUM_SHARED_SNAPSHOT_SLOTS;  
  
    size = offsetof(SharedSnapshotStruct, xips);  
    size = add_size(size, mul_size(slotSize, slotCount));  
  
    return MAXALIGN(size);  
}  

全局变量NUM_SHARED_SNAPSHOT_SLOTS

#define NUM_SHARED_SNAPSHOT_SLOTS (2 * max_prepared_xacts)  

二倍的max_prepared_transactions参数值。其实上边的英文注释也说啦:我们实际上只需要max_prepared_transactions,但是为了安全我们把他乘二,比如清除时的缓慢反分配。

所以查看系统的max_prepared_transactions的值,发现只有50,此处笑cry,捂脸哭。

修改max_prepared_transactions等于master的max_connections,gpconfig -c max_prepared_transactions -v 1500,重启数据库gpstop -a -M fast。

查看max_prepared_transactions,已经生效。

OK问题解决!!

问题模拟

gpconfig -c max_prepared_transactions -v 1
gpstop -M fast -a
gpstart -a

postgres=# show max_prepared_transactions ;
 max_prepared_transactions 
---------------------------
 1
(1 row)


postgres=# create table test(id int, info text);
NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Greenplum Database data distribution key for this table.
HINT:  The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
CREATE TABLE
postgres=# begin;
BEGIN
postgres=# insert into test select generate_series(1,1000),'test';
INSERT 0 1000


-- 会话2
postgres=# \set VERBOSITY verbose
postgres=# insert into test select generate_series(1,1000),'test';
FATAL:  XX000: the limit of 1 distributed transactions has been reached. (cdbtm.c:2569)
DETAIL:  The global user configuration (GUC) server parameter max_prepared_transactions controls this limit.
LOCATION:  createDtx, cdbtm.c:2569
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
目录
相关文章
|
存储 NoSQL 关系型数据库
|
Linux 虚拟化 数据安全/隐私保护
银河麒麟V10 VMWare安装保姆级教程
银河麒麟V10 VMWare安装保姆级教程
24762 5
银河麒麟V10 VMWare安装保姆级教程
|
SQL 关系型数据库 MySQL
阿里云的云数据库RDS简介
阿里云关系型数据库RDS(Relational Database Service)是一种安全稳定、高性价比、可弹性伸缩的在线数据库服务。支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供容灾、备份、恢复、监控、迁移等全套解决方案,帮助用户轻松应对数据库运维挑战。RDS具备高可用性、高安全性、轻量运维和弹性伸缩等优势,适用于各类业务场景,助力企业降低成本、提升效率。
|
12月前
|
数据库 数据中心 数据库管理
【赵渝强老师】OceanBase的内存管理
OceanBase数据库采用多租户架构,内存分为500虚拟租户、系统租户和业务租户三类。通过memory_limit_percentage和memory_limit参数控制OBServer节点总内存上限,并在创建Resource Unit时设定业务租户内存,实现资源隔离与管理。
518 0
|
NoSQL Redis
跨redis迁移数据的增量迁移方案和工具
面对这个不能完全覆盖的需求,使用RDB备份的需求是无法满足,因为RDB文件会将B的全部数据改为A的数据,显然是不可行的。后来我用了yunedit-redis,这款客户端工具,完美实现了数据的迁移,而且全程都在客户端操作,无需通过编码的方式来实现。
1232 1
|
SQL 前端开发 关系型数据库
阿里云百炼|析言GBI:产品博士的智能分析利器
本文介绍了阿里云“云知道”平台的云指针频道如何利用大模型实现从自然语言到SQL的转换,从而快速提供数据分析服务。通过阿里云AnalyticDB PostgreSQL版数据库存储数据,并结合析言GBI产品能力,实现了高效的数据查询与可视化展示。
2526 10
|
监控 算法 5G
uwb定位技术原理
UWB(超宽带)定位技术利用极宽的频带(3.1-10.6GHz)和纳秒级脉冲,通过测量信号飞行时间(ToF)或到达时间差(TDOA)实现高精度(厘米级)定位。其抗干扰性强、穿透力好、低功耗,适用于工业自动化、智能家居、医疗健康和智能安防等领域。UWB技术可有效应对信号遮挡和多径效应等问题,提供稳定可靠的室内定位解决方案。
2247 0
|
开发框架 Java API
「SpringBrick快速入门指南」:一款基于Spring Boot的高级插件化开发框架
「SpringBrick快速入门指南」:一款基于Spring Boot的高级插件化开发框架
1565 0
|
开发框架 开发者 数据库管理
模块化开发和传统开发的优缺点有哪些
【8月更文挑战第26天】模块化开发和传统开发的优缺点有哪些
1203 2