During tuning a query, I found one table has stale statistics. While running gather stats for that table, got below error. Let me demonstrate with a demo table:
SQL> execute dbms_stats.gather_table_stats(ownname => 'HR', tabname => 'EMPLOYEE', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO');
BEGIN dbms_stats.gather_table_stats(ownname => 'HR', tabname => 'EMPLOYEE', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO'); END;
*
ERROR at line 1:
ORA-20005: object statistics are locked (stattype = ALL)
ORA-06512: at "SYS.DBMS_STATS", line 34634
ORA-06512: at line 1
SQL>
Analysis:
Verify whether statistics is locked for that table or not.
SQL> col OWNER for a12
SQL> col table_name for a30
SQL> col STATTYPE_LOCKED for a15
SQL> select owner,table_name,STATTYPE_LOCKED from dba_tab_statistics where table_name='EMPLOYEE' and owner='HR';
OWNER TABLE_NAME STATTYPE_LOCKED
------------ ------------------------------ ---------------
HR EMPLOYEE ALL
SQL>
So, the column "stattype_locked" value is showing "ALL", that means statistics is locked for that table.
Solution Description:
The table statistics can be locked from the further update by using dbms_stats package. This will help to restrict from automatic statistics updation. When you get this error you can check whether your table is locked on further statistics updation using following query. The stattype_locked should be null to update the statistics.
STATTYPE_LOCKED – ALL -> stats are locked for the table
STATTYPE_LOCKED – NULL – > stats are not locked
To Unlock stats:
SQL> EXEC DBMS_STATS.unlock_table_stats('HR','EMPLOYEE');
PL/SQL procedure successfully completed.
SQL>
Now try to run stats again:
SQL> execute dbms_stats.gather_table_stats(ownname => 'HR', tabname => 'EMPLOYEE', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO');
PL/SQL procedure successfully completed.
SQL>
Similarly we can unlock stats for a schema also.
SQL> EXEC DBMS_STATS.unlock_schema_stats('HR');
PL/SQL procedure successfully completed.
SQL> execute dbms_stats.gather_table_stats(ownname => 'HR', tabname => 'EMPLOYEE', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO');
BEGIN dbms_stats.gather_table_stats(ownname => 'HR', tabname => 'EMPLOYEE', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO'); END;
*
ERROR at line 1:
ORA-20005: object statistics are locked (stattype = ALL)
ORA-06512: at "SYS.DBMS_STATS", line 34634
ORA-06512: at line 1
SQL>
Analysis:
Verify whether statistics is locked for that table or not.
SQL> col OWNER for a12
SQL> col table_name for a30
SQL> col STATTYPE_LOCKED for a15
SQL> select owner,table_name,STATTYPE_LOCKED from dba_tab_statistics where table_name='EMPLOYEE' and owner='HR';
OWNER TABLE_NAME STATTYPE_LOCKED
------------ ------------------------------ ---------------
HR EMPLOYEE ALL
SQL>
So, the column "stattype_locked" value is showing "ALL", that means statistics is locked for that table.
Solution Description:
The table statistics can be locked from the further update by using dbms_stats package. This will help to restrict from automatic statistics updation. When you get this error you can check whether your table is locked on further statistics updation using following query. The stattype_locked should be null to update the statistics.
STATTYPE_LOCKED – ALL -> stats are locked for the table
STATTYPE_LOCKED – NULL – > stats are not locked
To Unlock stats:
SQL> EXEC DBMS_STATS.unlock_table_stats('HR','EMPLOYEE');
PL/SQL procedure successfully completed.
SQL>
Now try to run stats again:
SQL> execute dbms_stats.gather_table_stats(ownname => 'HR', tabname => 'EMPLOYEE', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO');
PL/SQL procedure successfully completed.
SQL>
Similarly we can unlock stats for a schema also.
SQL> EXEC DBMS_STATS.unlock_schema_stats('HR');
PL/SQL procedure successfully completed.