postgresql:ERROR: row is too big: size 12032, maximum size 8160

    pg的页面初始化默认值为8192,除去页面头信息之外可以使用的空间约为8160字节,当某一个tuple超过这个大小后,就会出现上述报错。

   什么情况下会出现这种报错呢?

    我举个栗子

   首先是字段数量要足够大,注意不要超过最大字段数1600。例如我们建个1500字段的

-bash-4.2$ cat create_table.sh 
#!/bin/bash
sql=idMbigint
for ((i=0;i<1500;i++))
do
	sql=${sql}Fid_${i}Mbigint
done
column=`echo $sql|sed  's/M/ /g'|sed 's/F/,/g'`
sql="create table tp ($column);"
echo $sql
-bash-4.2$ ./create_table.sh |psql 
CREATE TABLE
-bash-4.2$ 

然后,字段类型大小乘字段数要大于8160字节,这里bigint 8字节*1501=12008字节,在加上元组头信息,妥妥的超过了。

插入试试

-bash-4.2$ cat insert_table.sh 
#!/bin/bash
sql=10
for ((i=0;i<1500;i++))
do
	sql=${sql}F${i}
done
column=`echo $sql|sed 's/F/,/g'`
sql="insert into tp values ($column);"
echo $sql
-bash-4.2$ ./insert_table.sh |psql 
ERROR:  row is too big: size 12032, maximum size 8160
-bash-4.2$ 

   出现了,就是这个报错。解决这个问题有两种方法,一种是从数据库着手初始化页面时设置大一些,比如32K,另一个就是从应用着手修改表结构,要么缩减字段数量要么修改字段类型,总之表结构肯定是要重建的。

   其实刚开始发现这个问题还是挺懵逼的,pg自带的toast机制一度让我掉到沟里去了,翻了翻才发现toast的启用是根据字段的大小来决定的,例如单字段char或者varchar超过501,就会启用toast机制,或者text字段当插入长度超过2560的时候才启用toast机制。当然这个也和字段数量有关,当字段数量增多时,启用toast机制的临界值就会降低。总的来说当一条元组超过2KB的时候,PG就会考虑是否启用toast机制。

        其实常用的数据类型,INT,BIGINT,REAL,FLOAT...应该是不会启用toast的,如果启用了toast,那存在原先位置处数据变成一个地址或者OID,相比也不会小多少。


参考博客:

    https://www.qcloud.com/community/article/164816001481011925

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`org.postgresql.util.PSQLException: ERROR: deadlock detected` 错误表示在您的PostgreSQL数据库中发生了死锁情况。死锁是指两个或多个事务互相等待对方释放资源而无法继续执行的情况。 解决死锁问题的常见方法包括: 1. 分析死锁日志:在PostgreSQL中,您可以查看日志文件以获取有关死锁的详细信息。查找死锁日志和相关事务的详细信息可能有助于确定问题的原因和解决方案。 2. 优化事务并发性:通过减少事务之间的竞争来降低出现死锁的可能性。这可以通过设计更合理的事务逻辑、调整事务隔离级别、降低事务持续时间等方式来实现。 3. 调整数据库配置参数:某些数据库配置参数可以影响死锁发生的频率。例如,您可以尝试增加`max_locks_per_transaction`参数的值,以便每个事务可以持有更多的锁。请注意,调整配置参数可能需要谨慎操作,并且需要根据具体情况进行测试和评估。 4. 重新设计应用程序逻辑:有时,死锁问题是由于应用程序中的设计问题引起的。检查应用程序中的并发访问模式和锁使用情况,考虑重新设计或优化以减少死锁风险。 5. 使用合适的锁机制:根据具体情况,可以考虑使用不同类型的锁机制来避免死锁。例如,使用行级锁而不是表级锁,或者使用乐观锁机制。 请注意,解决死锁问题可能需要一定的经验和调试技巧。如果您遇到复杂的死锁问题,建议咨询数据库管理员或PostgreSQL社区以获取更专业的支持和建议。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值