#sql #oracle #backup #partitioning #partition
#sql #Oracle #резервное копирование #разделение #раздел
Вопрос:
Я хочу сделать резервную копию таблицы a1_crm_query
с помощью EXCHANGE PARTITION
. Эта таблица содержит строки с разными статусами, такими как «ОШИБКА», «НОВЫЙ» или «СДЕЛАНО», и было бы здорово, если бы была еще одна таблица ( a1_crm_query_LOG
) со статусами «ОШИБКА» и «СДЕЛАНО», но моя первая таблица ( a1_crm_query
) будет только с «НОВЫМ».
Прежде всего я создаю свою таблицу:
CREATE TABLE ma_user.a1_crm_query (
ID NUMBER PRIMARY KEY,
DATA VARCHAR2(200)
);
Затем я создаю вторую таблицу с разделом.
CREATE TABLE ma_user.a1_crm_query_LOG (
ID NUMBER PRIMARY KEY,
DATA VARCHAR2(200)
)
PARTITION BY LIST (DATA) (
PARTITION DONE_STATUS VALUES ('DONE'),
PARTITION ERROR_STATUS VALUES ('ERROR')
) ;
затем вставьте значения в a1_crm_query
:
INSERT INTO ma_user.a1_crm_query SELECT 1 , CAST('NEW' AS VARCHAR2(200)) FROM dual;
INSERT INTO ma_user.a1_crm_query SELECT 2 , CAST('DONE' AS VARCHAR2(200)) FROM dual;
INSERT INTO ma_user.a1_crm_query SELECT 3, CAST('ERROR' AS VARCHAR2(200)) FROM dual;
Теперь я хочу создать ежедневный процесс, который должен перемещать все строки с ‘DONE’ и ‘ERROR’ в таблицу a1_crm_query_LOG
, a1_crm_query
должен быть только с ‘NEW’.
Я пытаюсь использовать exchange partition
:
ALTER TABLE ma_user.a1_crm_query_LOG EXCHANGE PARTITION ERROR_STATUS WITH TABLE ma_user.a1_crm_query WITHOUT VALIDATION;
ALTER TABLE ma_user.a1_crm_query_LOG EXCHANGE PARTITION DONE_STATUS WITH TABLE ma_user.a1_crm_query WITHOUT VALIDATION;
Но после этого ERROR_STATUS
раздел содержит все строки со всеми статусами.
Ответ №1:
Возможно, вам захочется создать две временные таблицы (temp_error, temp_done) с ОШИБКОЙ и СКОПИРОВАТЬ в них ГОТОВЫЕ данные из таблицы a1_crm_query, затем раздел exchange с таблицами temp_error и temp_done.
Проблема, с которой вы столкнулись, связана WITHOUT VALIDATION
с. По сути, вы сообщаете Oracle, что я уже проверил обмениваемые данные, поэтому Oracle не будет проверять их для вас.
Смотрите эту ссылку
Обновление: подход 1 Итак, это то, что я бы сделал.
CREATE TABLE TEMP_ERROR
( ID NUMBER PRIMARY KEY,
DATA VARCHAR2(200) );
CREATE TABLE TEMP_DONE
(
ID NUMBER PRIMARY KEY,
DATA VARCHAR2(200) );
insert into TEMP_ERROR
select * from a1_crm_query
where data = 'ERROR';
insert into TEMP_DONE
select * from a1_crm_query
where data = 'DONE';
ALTER TABLE a1_crm_query_LOG EXCHANGE PARTITION ERROR_STATUS WITH TABLE TEMP_ERROR WITHOUT VALIDATION;
ALTER TABLE a1_crm_query_LOG EXCHANGE PARTITION DONE_STATUS WITH TABLE TEMP_DONE WITHOUT VALIDATION;
truncate table temp_error;
truncate table temp_done
Обновление 2: Подход 2 Если вы также можете разбить a1_crm_query на разделы, то этот подход может подойти вам лучше всего. Вам понадобится одна промежуточная таблица. При таком подходе удаление или усечение не требуется.
CREATE TABLE a1_crm_query (
ID NUMBER PRIMARY KEY,
DATA VARCHAR2(200)
)
PARTITION BY LIST (DATA) (
PARTITION DONE_STATUS VALUES ('DONE'),
PARTITION ERROR_STATUS VALUES ('ERROR'),
PARTITION OTHER_STATUS VALUES (DEFAULT)
) ;
CREATE TABLE a1_crm_query_LOG (
ID NUMBER PRIMARY KEY,
DATA VARCHAR2(200)
)
PARTITION BY LIST (DATA) (
PARTITION DONE_STATUS VALUES ('DONE'),
PARTITION ERROR_STATUS VALUES ('ERROR')
) ;
INSERT INTO a1_crm_query SELECT 1 , 'NEW' FROM dual;
INSERT INTO a1_crm_query SELECT 2 , 'DONE' FROM dual;
INSERT INTO a1_crm_query SELECT 3, 'ERROR' FROM dual;
commit;
CREATE TABLE interim
( ID NUMBER PRIMARY KEY,
DATA VARCHAR2(200) );
ALTER TABLE a1_crm_query EXCHANGE PARTITION ERROR_STATUS WITH TABLE INTERIM WITHOUT VALIDATION;
ALTER TABLE a1_crm_query_LOG EXCHANGE PARTITION ERROR_STATUS WITH TABLE INTERIM WITHOUT VALIDATION;
ALTER TABLE a1_crm_query EXCHANGE PARTITION DONE_STATUS WITH TABLE INTERIM WITHOUT VALIDATION;
ALTER TABLE a1_crm_query_LOG EXCHANGE PARTITION DONE_STATUS WITH TABLE INTERIM WITHOUT VALIDATION;
Затем необходимо перестроить индекс в a1_crm_query
ALTER INDEX <index name> REBUILD;
select * from a1_crm_query;
select * from interim;
select * from a1_crm_query_LOG partition(ERROR_STATUS);
select * from a1_crm_query_LOG partition(done_STATUS)
Также смотрите эту ссылку
Комментарии:
1. Привет, Акио! Я должен использовать только одну таблицу _log, которая должна содержать оба статуса. Я не могу понять, почему переместить ВСЕ строки, включая «НОВЫЕ»
2. Акио, спасибо, это работает, но в таблице a1_crm_query все еще есть строки с ‘ERROR’ и ‘DONE’. Честно говоря, я не вижу преимуществ этого метода. Я думал, что РАЗДЕЛ EXCHANGE должен заменить операцию ВСТАВКИ- УДАЛЕНИЯ
3. @Jdzel вы можете удалить записи об ОШИБКАХ и выполненных из a1_crm_query. Я опубликую альтернативный подход, если вы также можете разбить a1_crm_query на разделы.
4. Да, будет здорово, если вы опубликуете это. Я могу разбить a1_crm_query на разделы.
5. Акио, спасибо, но после этого обмена я не могу вставить другие строки с этим статусом («ОШИБКА») в a1_crm_query. Я думаю, это происходит из-за перемещения раздела из этой таблицы. Должен ли я добавить раздел в a1_crm_query после обмена?