1、题目:PostgreSQL故障与隐患排查:典型案例解析与最佳实践,讲者:阎书利,CONTENTS,数据批量入库报 out-of-range?,/01,1.数据批量入库报 out-of-range,4,业务侧反馈,因为某业务积攒的单量太大,导致在数据批量入库的时候,产生如下报错,主要报错信息是:请求参数的整体大小不能超过2byte。Tried to send an out-of-range integer as a 2-byte value:53568,5,这个报错初步看起来,有个“out-of-range integer”,可能大家第一个想到的可能是:是不是表的字段不够长,但是插入的数据太长了
2、导致的?但其实简单测试下就可以发现,列的长度不够,报的错误和这个是不一样的。,postgres=#create table t1(id int2);CREATE TABLEpostgres=#insert into t1 values(53568);ERROR:smallint out of rangeCONTEXT:referenced column:idpostgres=#select 53568:int2;ERROR:smallint out of rangeCONTEXT:referenced column:int2,查看了报错的这张表的表结构,除了一列为数字类型外,其余字段均为字符或
3、者时间类型,而这一数字类型的列,根据业务场景来看,一般不会有超出长度的数值。,6,查看下pgjdbc的驱动的代码报错的位置只有一处,如下是42.3.10版本pgjdbc的报错部分,其中,判断条件里Short.MIN_VALUE和Short.MAX_VALUE的值分别为-32768和32767,表示SQL 解析过程中,SQL中的参数的个数最大不超过32767。,7,如下是42.4.0版本pgjdbc的报错部分,其中,判断条件里将之前版本的MIN_VALUE和MAX_VALUE直接替换成了0和65535,表示SQL 解析过程中,SQL中的参数的个数最大不超过65535。,8,而进一步和业务确认,果
4、然他们使用的pgjdbc驱动的版本比较低,并且其实日志的报错部分往上翻,其实也能大致看出这个报错的SQL,涉及到了大量的绑定变量。业务同事反馈,交易笔数大概几千比,但是每比交易涉及到很多绑定变量,这些总和超出了他们使用的pgjdbc驱动的参数个数限制。,9,因此,解决方案其实有两种:一种使用较高版本的pgjdbc驱动(42.4.0+),驱动支持的参数的最大个数提升到了65535,会很大程度上减少此类报错。一种是采用jdbc或者MyBatis等持久化框架提供的批量执行接口进行批量操作。调整业务,对拼接的SQL的逻辑进一步拆分,减少单个SQL绑定变量个数。,读写分离的冲突和隐患,/02,2.读写分
5、离的冲突和隐患。,11,数据库读写分离是一种常见的数据库架构优化策略,通过将数据库的读操作和写操作分配到不同的服务器上来提高系统性能。PostgreSQL数据库做读写分离的核心思想是:写操作(INSERT、UPDATE、DELETE等)集中在主数据库(Master)读操作(SELECT等)分散到一个或多个从数据库(Standby/Replica),12,门户异常,短暂无法访问,经检查后发现,数据库发生了切换。但是从单个连接观察来看,比较后,发现没有明显单个SQL消耗资源额外高(相比较而言)的情况每天0点-6点的cpu使用率是最高的,是由业务侧凌晨开始的定时任务引起的。从数据库日志和监控的检查发
6、现资源负载消耗过高。,13,翻看日志以及监控,发现此次切换之前,曾因为慢SQL导致的大量资源占用,使数据库切换过一次。切换之后,白天的业务量明显增多。负载也有明显变化。这套环境曾经因为负载的问题,做过读写分离。但是没有考虑读写的分离切换之后,读操作的重新分配,从而使切换之后,读写操作均集中在主节点,大量的并发,恰巧遇到了较多有问题的SQL(涉及大量的绑定变量,导致CPU达到了瓶颈),从而造成了此次切换。可以采用一些中间件,如ShardingSphere等:支持读写分离+故障自动切换,主备切换后,应尽快恢复读写分离架构,需预设降级策略,对低优先级查询降权,从而实现SQL 限流,避免因架构变化导致