2013-02-14 3 views
0

Я получаю странное поведение. У меня есть процедура, которая изменяет имена разделов в таблице. Я создал задание, которое выполняет эту процедуру каждые 2 минуты для тестирования. Первый запуск проходит очень гладко и без каких-либо ошибок. Однако, со 2-го запуска я получаю следующую ошибкуoracle scheduler для переименования интервальных разделов

"ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired 
     ORA-06512: at "CDS_USER.RENAMING_PARTITIONS", line 17" 

Да, мой стол жив. Но когда я запускаю свою процедуру явно с помощью планировщика, он работает отлично. Никаких проблем с этим. И каждый первый запуск планировщика также идеален.

Вот код для планировщика

begin 
    bms_Scheduler.create_job(
    job_name => 'drop_user1' , 
    job_action => 'RENAMING_PARTITIONS' 
    job_action => 'DROP_PARTITIONS' 
    ,start_date => SYSDATE , 
    repeat_interval => 'freq=hourly;INTERVAL=7',bysecond=0;' , 
    enabled => TRUE , 
    comments => 'schduling drop job.'); 
    END; 

Вот код процедуры

 create or replace PROCEDURE RENAMING_PARTITIONS 
    AS 
    hv varchar2(9); 
    max_part VARCHAR2(9); 
    begin 
    select max(partition_position) into max_part from user_tab_partitions where table_name='DEMO'; 
    for x in (select partition_name, high_value, partition_position 
      from user_tab_partitions 
      where table_name = 'DEMO' and partition_name like 'SYS%') 
loop 
if x.partition_position <> max_part THEN 

     execute immediate 'select to_char('||x.high_value||'-1,''YYYYMMDD'') from dual' into hv; 
partition '||x.partition_name 
        --||' to DATE_'||hv); 
     execute immediate('alter table DEMO rename partition '||x.partition_name 
        ||' to DATE_'||hv); 
end if; 
end loop; 
end; 

Как я могу это исправить?

+0

Я предполагаю, что «alter table DEMO ...» не может получить блокировку в таблице, потому что она обновляется или используется «в использовании». –

+1

- это взломать переименование интервальных разделов? – tbone

+0

Почему вы сравниваете максимальный раздел таблицы 'T_FDC_TOOLCONTEXT' с положением раздела таблицы' DEMO'? –

ответ

1

Не делайте этого. Я знаю, что неудобно, что Oracle не будет следовать предопределенной схеме именования разделов для создаваемых системных интервалов (вероятно, это произойдет в будущем), но изменение таблицы каждые 2 минуты не является хорошей альтернативой любым растяжением.

К счастью, вам действительно нужно знать имя раздела заранее, указав его в запросах. Типичный запрос будет что-то вроде:

select * from my_table partition (blah); 

В 11g, вы можете использовать «раздел для» пункта для обхода системы генерируется именами, следующим образом (пример для интервальных разделов ДАТЫ):

SQL> set display on 
SQL> set linesize 200 
SQL> drop table test_data 
Table dropped. 
SQL> create table test_data (
    start_date  DATE, 
    store_id   NUMBER, 
    inventory_id  NUMBER, 
    qty_sold   NUMBER 
) 
PARTITION BY RANGE (start_date) 
INTERVAL(NUMTOYMINTERVAL(1, 'MONTH')) 
(
    PARTITION part_01 values LESS THAN (TO_DATE('20130101','YYYYMMDD')) 
) 
Table created. 
SQL> insert into test_data values (to_date('20121231', 'YYYYMMDD'), 1, 2, 1) 
1 row created. 
SQL> commit 
Commit complete. 
SQL> SELECT table_name, partition_name, high_value 
FROM user_tab_partitions 
WHERE table_name = 'TEST_DATA' 
ORDER BY table_name, partition_name 

TABLE_NAME      PARTITION_NAME     HIGH_VALUE           
------------------------------ ------------------------------ -------------------------------------------------- 
TEST_DATA      PART_01      TO_DATE(' 2013-01-01 00:00:00', 'SYYYY-MM-DD HH24: 
                   MI:SS', 'NLS_CALENDAR=GREGORIAN')     

1 row selected. 
SQL> insert into test_data values (to_date('20130101', 'YYYYMMDD'), 1, 5, 8) 
1 row created. 
SQL> insert into test_data values (to_date('20130115', 'YYYYMMDD'), 2, 4, 5) 
1 row created. 
SQL> insert into test_data values (sysdate, 2, 3, 2) 
1 row created. 
SQL> commit 
Commit complete. 
SQL> SELECT table_name, partition_name, high_value 
FROM user_tab_partitions 
WHERE table_name = 'TEST_DATA' 
ORDER BY table_name, partition_name 

TABLE_NAME      PARTITION_NAME     HIGH_VALUE           
------------------------------ ------------------------------ -------------------------------------------------- 
TEST_DATA      PART_01      TO_DATE(' 2013-01-01 00:00:00', 'SYYYY-MM-DD HH24: 
                   MI:SS', 'NLS_CALENDAR=GREGORIAN')     

TEST_DATA      SYS_P67      TO_DATE(' 2013-02-01 00:00:00', 'SYYYY-MM-DD HH24: 
                   MI:SS', 'NLS_CALENDAR=GREGORIAN')     

TEST_DATA      SYS_P68      TO_DATE(' 2013-03-01 00:00:00', 'SYYYY-MM-DD HH24: 
                   MI:SS', 'NLS_CALENDAR=GREGORIAN')     


3 rows selected. 
SQL> -- get data for January partition only 
SQL> select * from test_data partition for (to_date('20130101', 'YYYYMMDD')) 

START_DATE STORE_ID INVENTORY_ID QTY_SOLD 
----------- ---------- ------------ ---------- 
01-JAN-2013   1   5   8 
15-JAN-2013   2   4   5 

2 rows selected. 
+0

Для целей тестирования я делаю это каждые 2 минуты, на самом деле это будет выполняться каждые 24 часа. Это критическое требование. Я должен это сделать. – user1947949