AQ $ _MESSAGES_EXCEPTIONПрежде всего, я знаю, что есть этот вопрос: How to clear a queue in Oracle AQ, но у него нет ответа.Есть ли быстрый способ очистки очереди Exception от Oracle AQ?
У меня много сообщений (500k) в очереди исключений в Oracle AQ (я не знал, что истекшие сообщения перемещаются в другую очередь, поэтому я не создал для них пользователя). Теперь мне нужно иметь возможность быстро удалять эти сообщения. Я читал, что не удастся очистить таблицу очередей с помощью delete, потому что это может привести к несогласованному состоянию. Таким образом, я соединил следующие процедуры, но только очищает около 50 сообщений/секунду
EXECUTE dbms_aqadm.start_queue(queue_name => 'AQ$_MESSAGES_EXCEPTION',
enqueue => FALSE, dequeue => TRUE);
DECLARE
dequeue_options DBMS_AQ.dequeue_options_t;
message_properties DBMS_AQ.message_properties_t;
message_handle RAW(16);
message SYS.AQ$_JMS_MESSAGE;
no_messages EXCEPTION;
pragma exception_init (no_messages, -25228);
BEGIN
dequeue_options.wait := DBMS_AQ.NO_WAIT;
dequeue_options.navigation := DBMS_AQ.FIRST_MESSAGE;
LOOP
DBMS_AQ.DEQUEUE(
queue_name => 'AQ$_MESSAGES_EXCEPTION',
dequeue_options => dequeue_options,
message_properties => message_properties,
payload => message,
msgid => message_handle);
DBMS_OUTPUT.put_line ('Message: ' || message_handle || ' dequeued');
END LOOP;
EXCEPTION
WHEN no_messages THEN
DBMS_OUTPUT.put_line (' ---- NO MORE MESSAGES ---- ');
WHEN others then
DBMS_OUTPUT.put_line ('Exception queue not started for dequeue.');
END;
/
Это кажется очень медленно, учитывая, что это работает на компьютере базы данных. Эта процедура занимает около трех часов с сообщениями 500 тыс. Сообщений. Могу ли я сделать это более эффективным образом?
EDIT:
Я попытался dequeue_array по ссылке здесь: http://www.oracle-developer.net/display.php?id=319 Но я не могу создать таблицы, так что я пытаюсь создать массив в «магазин» результаты. Вот что я получил:
DECLARE
type messages_type is varray(500) of SYS.AQ$_JMS_MESSAGE;
messages messages_type;
dequeue_options DBMS_AQ.dequeue_options_t;
msg_properties DBMS_AQ.message_properties_array_t;
msg_ids DBMS_AQ.MSGID_ARRAY_T;
x_timeout EXCEPTION;
no_messages EXCEPTION;
dequeue_batch PLS_INTEGER := 500;
pragma exception_init (no_messages, -25228);
BEGIN
messages := messages_type();
msg_properties := DBMS_AQ.MESSAGE_PROPERTIES_ARRAY_T();
msg_properties.EXTEND(dequeue_batch);
msg_ids := DBMS_AQ.MSGID_ARRAY_T();
dequeue_options.wait := 5;
LOOP
DBMS_AQ.DEQUEUE_ARRAY(
queue_name => 'AQ$_MESSAGES_EXCEPTION',
dequeue_options => dequeue_options,
array_size => dequeue_batch,
message_properties_array => msg_properties,
payload_array => messages,
msgid_array => msg_ids);
...
Я получаю эту ошибку:
wrong number or types of arguments in call to 'DEQUEUE_ARRAY'
Я думаю, что проблема в массиве сообщений, но я не знаю, что делать, чтобы сделать он работает. Кроме того, в соответствии с оракулом документ (http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_aq.htm#i1000850), должен быть еще один параметр:
error_array OUT error_array_t
Но объяснение для этого параметра «В настоящее время не реализован». Что это значит? Можно ли это оставить? Должно ли оно быть нулевым? Это действительно сбивает с толку и Google здесь не поможет :(
Но проблема в том, что в очереди исключений нет отдельной таблицы. Поэтому, если бы я использовал решение из ссылки, я бы также удалял данные из обычной очереди, и я не хочу этого. Я попробую массив dequeue и посмотрю, будет ли он быстрее. – NeplatnyUdaj
Я сдаюсь. Я не могу собрать процедуру для вызова dequeue_array. – NeplatnyUdaj
Я вижу, я делаю это из .NET-кода, и я не сталкивался с какой-либо проблемой. библиотека Oracle предоставляет API для очередей. У вас есть это: http://www.oracle-developer.net/display.php?id=319 –