【ORA】ORA-38029 & ORA-20005

本文介绍了在Oracle数据库中遇到ORA-20005和ORA-38029错误的情况,详细解释了错误原因,并提供了具体的解决方案。特别是针对导入数据后统计信息被锁定的问题,给出了使用DBMS_STATS.UNLOCK_TABLE_STATS过程解锁统计信息的方法。

从10g导出了一致表到本地的11g环境中做测试。导入后习惯的去收集一下统计信息。遇到了ORA-20005ORA-38029错误。

/home/oracle$oerr ora 38029
38029, 00000, "object statistics are locked"
// *Cause: An attept was made to modify optimizer statistics of the object.
// *Action: Unlock statistics with the DBMS_STATS.UNLOCK_TABLE_STATS procedure
// on base table(s). Retry the operation if it is okay to update statistics.


Cause
Possible Cause #1: DBMS_STATS.LOCK_[SCHEMA|TABLE]_STATS has been used to lock statistics on the table.

Possible Cause #2: Using import (imp) or data pump import (impdp) to import a table without data results in the table's statistics being locked in 10gR2.

Possible Cause #3: If the table is a queue table then the statistics are intended to be empty and locked so that dynamic sampling will be used due to the table's volatility. During an upgrade to 10gR2 statistics on queue tables are deleted and then locked. In 10gR2 when a queue table is created statistics are locked while still empty.

Oracle Database Readme
10g Release 2 (10.2)
Part Number B14233-04
39.5 Original Export/Import
After an IMPORT is finished for which ROWS=N, the statistics for all tables imported will be locked.

Solution
- Unlock the table statistics after the import:
execute DBMS_STATS.UNLOCK_TABLE_STATS('','

我遇到的可能是ROWS=N这种情况,在开始导入到时候确实是加了ROWS=N这个参数。

示例:
SQL> EXEC DBMS_STATS.gather_table_stats('REPORT','SWFLOG');
begin DBMS_STATS.gather_table_stats('REPORT','SWFLOG'); end;

ORA-20005: object statistics are locked (stattype = ALL)
ORA-06512: 在 "SYS.DBMS_STATS", line 20337
ORA-06512: 在 "SYS.DBMS_STATS", line 20360
ORA-06512: 在 line 1

SQL> ANALYZE TABLE SWFLOG COMPUTE STATISTICS;

ANALYZE TABLE SWFLOG COMPUTE STATISTICS
ORA-38029: 对象统计信息已锁定


解决方法:

SQL> execute DBMS_STATS.UNLOCK_TABLE_STATS('REPORT','SWFLOG');
PL/SQL procedure successfully completed

SQL> EXEC DBMS_STATS.gather_table_stats('REPORT','SWFLOG');
PL/SQL procedure successfully completed

SQL> ANALYZE TABLE SWFLOG COMPUTE STATISTICS;
Table analyzed

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26892340/viewspace-722175/,如需转载,请注明出处,否则将追究法律责任。

user_pic_default.png
请登录后发表评论 登录
全部评论
<%=items[i].createtime%>

<%=items[i].content%>

<%if(items[i].items.items.length) { %>
<%for(var j=0;j
<%=items[i].items.items[j].createtime%> 回复

<%=items[i].items.items[j].username%>   回复   <%=items[i].items.items[j].tousername%><%=items[i].items.items[j].content%>

<%}%> <%if(items[i].items.total > 5) { %>
还有<%=items[i].items.total-5%>条评论 ) data-count=1 data-flag=true>点击查看
<%}%>
<%}%> <%}%>

转载于:http://blog.itpub.net/26892340/viewspace-722175/

&lt;think&gt; 我们正在处理的是关于Oracle数据库统计信息锁定导致的ORA-20005ORA-38029错误的问题。根据引用内容,这些错误通常发生在尝试收集或分析表的统计信息时,因为统计信息被锁定(stattype_locked为&#39;ALL&#39;)。 原因分析: 1. 统计信息被锁定:这是为了防止统计信息被自动或手动更新,从而保持执行计划的稳定性。在Oracle 10g及以上版本中,默认会自动收集统计信息,但有时为了稳定执行计划,可能会使用`DBMS_STATS.LOCK_TABLE_STATS`或`DBMS_STATS.LOCK_SCHEMA_STATS`来锁定统计信息。 2. 锁定的影响:一旦锁定,任何尝试更新统计信息的操作(如`DBMS_STATS.GATHER_TABLE_STATS`或`ANALYZE`命令)都会失败,并抛出ORA-20005ORA-38029错误。 解决办法: 1. 解锁统计信息:使用`DBMS_STATS.UNLOCK_TABLE_STATS`来解锁特定表的统计信息。语法为: ```sql EXEC DBMS_STATS.UNLOCK_TABLE_STATS(ownname =&gt; &#39;用户名&#39;, tabname =&gt; &#39;表名&#39;); ``` 如果是多个表被锁定,可以批量生成解锁语句(如引用[5]所示): ```sql SELECT &#39;EXEC DBMS_STATS.UNLOCK_TABLE_STATS(&#39;&#39;&#39;||owner||&#39;&#39;&#39;,&#39;&#39;&#39;||table_name||&#39;&#39;&#39;);&#39; FROM dba_tab_statistics WHERE owner=&#39;用户名&#39; AND stattype_locked IS NOT NULL; ``` 注意:在PL/SQL Developer等工具中执行时,需要去掉EXEC并放在BEGIN...END块中。 2. 重新收集统计信息:解锁后,就可以正常收集统计信息了: ```sql EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname =&gt; &#39;用户名&#39;, tabname =&gt; &#39;表名&#39;); ``` 3. 如何避免:除非有特殊需求(如稳定执行计划),否则不要随意锁定统计信息。如果确实需要锁定,应该记录并在需要更新统计信息时解锁。 注意事项: - 权限:执行解锁操作需要相应的权限(通常需要具有DBA权限或该表的权限)。 - 批量操作:如果整个模式(schema)的统计信息被锁定,可以使用`DBMS_STATS.UNLOCK_SCHEMA_STATS`解锁整个模式。 相关问题: 1. 如何查询数据库中所有被锁定的统计信息? 2. 锁定统计信息对数据库性能有什么影响? 3. 在什么情况下需要锁定统计信息? 4. 如何永久避免统计信息被锁定导致的收集失败? 引用说明:我们在回答中参考了引用[1][2][3][4][5]的内容,其中引用[1][2][3][4][5]均提到了ORA-20005/ORA-38029错误与统计信息锁定有关,并提供了查询锁定状态和解锁的方法。 &lt;/think&gt; ### 🔍 对象统计信息锁定问题(ORA-20005/ORA-38029)解析 #### 📌 错误本质 当 Oracle 数据库尝试更新表的统计信息时,若检测到统计信息已被锁定,会抛出两种等效错误: - **`ORA-20005: object statistics are locked (stattype = ALL)`** - **`ORA-38029: 对象统计信息已锁定`** 二者均表示 **统计信息处于人工锁定状态**,阻止自动或手动更新操作[^1][^2]。 --- ### ️ **核心原因分析** 1. **人为锁定统计信息** - 通过 `DBMS_STATS.LOCK_TABLE_STATS` 或 `DBMS_STATS.LOCK_SCHEMA_STATS` 显式锁定 - 目的:**稳定执行计划**,防止 Oracle 自动收集统计信息改变优化器行为[^3] 2. **Schema/表迁移操作** - 从其他数据库导入表时,若源库锁定了统计信息,导入后锁定状态会保留[^2] 3. **特殊维护需求** - 对关键业务表手动锁定统计信息,确保执行计划长期稳定 - 例如:避免因数据倾斜导致优化器选择低效执行计划 --- ### 🔧 **解决方案** #### ✅ 步骤 1:确认锁定状态 ```sql -- 查询被锁定的表 SELECT owner, table_name, stattype_locked FROM dba_tab_statistics WHERE stattype_locked = &#39;ALL&#39;; -- ALL 表示完全锁定 ``` &gt; 输出示例: &gt; ``` &gt; OWNER TABLE_NAME STATTYPE_LOCKED &gt; ------ ----------- ---------------- &gt; SYS TEST_TABLE ALL &gt; ```[^1][^5] #### ✅ 步骤 2:解锁统计信息 ```sql -- 单表解锁 BEGIN DBMS_STATS.UNLOCK_TABLE_STATS( ownname =&gt; &#39;SYS&#39;, -- 模式名 tabname =&gt; &#39;TEST_TABLE&#39; -- 表名 ); END; ``` -- **批量解锁**(适用于多表锁定) ```sql -- 生成解锁语句 SELECT &#39;EXEC DBMS_STATS.UNLOCK_TABLE_STATS(&#39;&#39;&#39;||owner||&#39;&#39;&#39;,&#39;&#39;&#39;||table_name||&#39;&#39;&#39;);&#39; FROM dba_tab_statistics WHERE stattype_locked = &#39;ALL&#39;; ``` &gt; 执行生成的语句即可批量解锁[^5] #### ✅ 步骤 3:重新收集统计信息 ```sql BEGIN DBMS_STATS.GATHER_TABLE_STATS( ownname =&gt; &#39;SYS&#39;, tabname =&gt; &#39;TEST_TABLE&#39; ); END; ```[^1] --- ### ️ **关键注意事项** 1. **锁定策略需谨慎** - 仅对关键业务表锁定统计信息 - 避免使用 `LOCK_SCHEMA_STATS` 锁定整个模式 - 锁定后需文档记录,避免遗忘[^3] 2. **迁移后的检查** - 从其他环境导入表后,立即检查 `dba_tab_statistics.stattype_locked` 3. **权限要求** - 解锁操作需要 `ANALYZE ANY` 或 `DBA` 权限 --- ### 💡 替代方案:临时禁用自动统计 若需保持执行计划稳定但不想永久锁定: ```sql -- 禁用表自动统计(不锁定) BEGIN DBMS_STATS.SET_TABLE_PREFS( ownname =&gt; &#39;SYS&#39;, tabname =&gt; &#39;TEST_TABLE&#39;, pname =&gt; &#39;AUTOSTATS_TARGET&#39;, pvalue =&gt; &#39;OFF&#39; ); END; ``` --- ### ❓ 相关问题 1. **如何区分 `LOCK_TABLE_STATS` 和 `SET_TABLE_PREFS` 的使用场景?** 2. **统计信息锁定对 SQL 执行计划有何具体影响?** 3. **Oracle 自动统计收集机制如何检测锁定的统计信息?** 4. **批量解锁操作是否存在性能风险?** 5. **统计信息锁定与表锁定的本质区别是什么?** &gt; 参考资料: &gt; [^1]: ORA-20005 统计信息被锁定的原因与解决方案 &gt; [^2]: 表迁移导致统计信息锁定的场景 &gt; [^3]: 锁定统计信息的设计目的与风险 &gt; [^4]: 统计信息锁定的技术实现细节 &gt; [^5]: 批量解锁操作的实践方法
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值