当前位置:首页 > 问答 > 正文

ORA-14161报错说PCTUSED和PCTFREE加起来不能超过100,导致分区问题远程帮忙修复指导

ORA-14161这个错误,说白了就是你在给数据库里的表做分区或者修改分区属性时,不小心把PCTUSED和PCTFREE这两个参数的值加起来设得超过了100,数据库觉得你这样干不行,就弹出这个错误来阻止你,下面我就根据甲骨文官方技术支持文档和一些资深数据库管理员的经验,来详细说说这个事,以及怎么一步步把它修好。

第一部分:先搞清楚PCTUSED和PCTFREE到底是啥

你别被这两个英文词吓到,它们的意思其实很简单,你可以把数据库存储数据的最小单位——“数据块”,想象成一个个用来装数据的“箱子”。

  • PCTFREE:这个参数规定的是,在一个“箱子”里,必须留出多少百分比的空间不能马上用,比如你设置PCTFREE为20,意思是这个箱子装满到80%的时候,就得停手,剩下的20%空间要空着,留这些空位干嘛呢?主要是为了以后这个箱子里已经有的数据可能会“长大”(比如你更新了一条记录,把一个短的字符串改成了一个很长的字符串),如果一点空位不留,数据一长大就没地方放了,就会产生很多麻烦。
  • PCTUSED:这个参数规定的是,当一个“箱子”的使用率下降到百分之多少以下时,它才能被重新拿出来装新的数据,比如你设置PCTUSED为40,那么当一个箱子的数据被删除了一些,使用率降到了40%以下,这个箱子才会被数据库标记为“可用的空箱子”,之后有新的数据进来,就可以往这个箱子里放了。

PCTFREE关心的是“什么时候不能再装了”,而PCTUSED关心的是“什么时候可以重新装”,很显然,PCTUSED的值必须小于(100 - PCTFREE),比如说,你PCTFREE设为20,那么箱子最多装到80%就要停手,这个箱子要想再次被使用,它的使用率必须降到某个值以下,这个值(也就是PCTUSED)肯定得小于80%才行吧?如果你把PCTUSED设成了85,那就矛盾了:箱子用到80%就停止写入了,它永远也达不到85%的使用率,所以它永远也没机会被标记为可重新使用的状态,这逻辑上就不通。

数据库强制要求 PCTFREE + PCTUSED <= 100,ORA-14161错误就是告诉你,你当前的设置违反了这个最基本的规则。

第二部分:错误发生的常见场景和检查方法

这个错误通常在你执行以下几种SQL语句时出现:

  1. 创建分区表时:在CREATE TABLE ... PARTITION BY ...语句中,你为某个分区或所有分区设置的PCTFREE和PCTFREE值之和超过了100。
  2. 修改分区属性时:使用ALTER TABLE ... MODIFY PARTITION ...语句,想改变某个已有分区的存储参数,结果设置错了。
  3. 分裂分区时:使用ALTER TABLE ... SPLIT PARTITION ...语句,在新产生的分区上设置了不合理的参数。

怎么检查? 别慌,把数据库报错的完整SQL语句仔细看一遍,错误信息通常会告诉你是在哪张表、哪个分区上出的问题,你可以用下面的查询语句来查看这个分区当前的设置是多少:

SELECT table_name, partition_name, pct_free, pct_used
FROM user_tab_partitions
WHERE table_name = '你的表名';

'你的表名'换成你实际出错的表名(注意表名通常是大写的),执行这个查询,你就能看到每个分区的PCT_FREE和PCT_USED当前值,算一下它们的和,肯定有大于100的。

第三部分:一步步修复指导

知道问题在哪了,修复起来就简单了,核心就是把PCTFREE和PCTUSED的值调整到满足“相加不超过100”的条件。

修复步骤:

  1. 确认修改目标:你先想好,要把这两个参数改成多少,常见的、合理的搭配比如:

    • PCTFREE 20PCTUSED 40 (和=60)
    • PCTFREE 10PCTUSED 40 (和=50)
    • PCTFREE 5PCTUSED 60 (和=65) 你可以根据你的业务特点来选择,如果数据更新很频繁,经常有数据变长,PCTFREE就设大一点;如果主要是插入和删除,很少更新,PCTFREE可以设小点,PCTUSED设大点,这样空间利用率高。
  2. 执行修改语句:使用ALTER TABLE语句来修改出错分区的存储参数,假设你的表名叫SALES_DATA,出问题的分区叫PART_2024,你想把PCTFREE改成20,PCTUSED改成40,那么SQL语句这样写:

    ALTER TABLE SALES_DATA MODIFY PARTITION PART_2024
    PCTFREE 20 PCTUSED 40;

    如果出错的是多个分区,你需要一个一个地修改,或者,如果你想为所有分区设置一个统一的新值,可以使用修改表默认属性的方式(但注意,这不会改变已有分区的值,只影响新增加的分区):

    ALTER TABLE SALES_DATA MODIFY DEFAULT ATTRIBUTES
    PCTFREE 20 PCTUSED 40;
  3. 重新执行失败的操作:修改完参数之后,你再回头去执行最初那个因为ORA-14161而失败的操作(比如创建分区或分裂分区的语句),这时候就应该能成功执行了。

  4. 验证修改结果:修改完成后,再次运行第二部分里的那个查询语句,确认一下相关分区的PCT_FREE和PCT_USED值已经变成了你设定的新值,并且它们的和确实小于等于100。

非常重要的提醒:

  • 选择合适的时间:如果是要修改一个已经存在并且有大量数据的分区,ALTER TABLE ... MODIFY PARTITION ...操作可能会锁表,影响业务运行,所以尽量在数据库空闲时段(比如深夜)进行这类维护操作。
  • 理解参数的影响:PCTFREE和PCTUSED的设定会影响数据库的性能和空间利用效率,设置不当可能会导致数据块碎片化严重(如果PCTUSED设得太高)或者空间浪费较多(如果PCTFREE设得过高),如果不确定怎么设,采用甲骨文官方文档里常见的默认值或推荐值(如PCTFREE 10, PCTUSED 40)通常是一个比较稳妥的起点。
  • 备份意识:在对重要的生产环境数据库进行任何结构修改之前,只要条件允许,都建议先对相关的表或整个数据库做一个备份,以防万一操作失误导致更严重的问题。

解决ORA-14161错误就是一个“检查-计算-修改-验证”的过程,核心就是确保PCTFREE和PCTUSED这两个好朋友加起来别超过100,只要你耐心点,按照上面的步骤来,这个问题完全可以自己解决。

ORA-14161报错说PCTUSED和PCTFREE加起来不能超过100,导致分区问题远程帮忙修复指导