powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как сделать split partition online?
23 сообщений из 23, страница 1 из 1
Как сделать split partition online?
    #39726239
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!

Задача - сделать разделение секции P_DEFAULT таблицы MYTEST_IN_DOC , не прерывая работу системы.
Нужен результат, как после:
Код: plsql
1.
2.
alter table mytest_in_doc split partition p_default at (to_date('01.01.2019', 'dd.mm.yyyy'))
  into (partition p_2018, partition p_default) update indexes;


На таблицах выполнятеся только INSERT .
Какой последовательностью действий можно решить задачу?

Исходные данные:
Код: plsql
1.
2.
3.
4.
5.
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
PL/SQL Release 12.2.0.1.0 - Production
CORE	12.2.0.1.0	Production
TNS for Linux: Version 12.2.0.1.0 - Production
NLSRTL Version 12.2.0.1.0 - Production


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
--drop table mytest_out_doc;
--drop table mytest_in_doc;
create table mytest_in_doc (
  in_id number
 ,doc_date timestamp default systimestamp not null
 ,cmd varchar2(256) not null
 ,client varchar2(200) 
 ,msg clob
 ,constraint pk_mytest_in_doc primary key (in_id)
)
pctfree 5 pctused 80
lob(msg) store as securefile
partition by range(doc_date) 
  (partition p_2017 values less than (to_date('01.01.2018','dd.mm.yyyy'))
  ,partition p_default values less than (maxvalue)
  );
create index ik_mytest_in_doc$doc_date on mytest_in_doc (doc_date) global partition by range(doc_date)
  (partition p_2017 values less than (to_date('01.01.2018','dd.mm.yyyy'))
  ,partition p_default values less than (maxvalue)
  );

create table mytest_out_doc (
  out_id number
 ,in_id  number not null
 ,doc_date timestamp default systimestamp not null
 ,msg clob
 ,err_code number
 ,constraint pk_mytest_out_doc primary key (out_id)
 ,constraint fk_mytest_out_doc$in_id foreign key (in_id) references mytest_in_doc (in_id)
)
pctfree 5 pctused 80
lob(msg) store as securefile
partition by reference (fk_mytest_out_doc$in_id);
create index ik_mytest_out_doc$in_id on mytest_out_doc (in_id) local;
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39726248
Вадиман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rename table + create view + "instead of insert" trigger + складываешь в сторонке + параллельно курочишь как хочешь исходные таблицы
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39726249
Вадиман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
потом сливаешь обратно
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39726257
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вадиман,

dbms_redefinition отменили?
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39726266
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вадиманrename table + create view + "instead of insert" trigger + складываешь в сторонке + параллельно курочишь как хочешь исходные таблицы

Я правильно понял суть?
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
--1 
create table mytest_in_doc_2;
create table mytest_out_doc_2;
--2
rename table mytest_in_doc to mytest_in_doc_original;
rename table mytest_out_doc to mytest_out_doc_original;
create or replace view mytest_in_doc as select * from mytest_in_doc_2;
create or replace view mytest_out_doc as select * from mytest_out_doc_2;
--3
alter table mytest_in_doc_original split partition p_default at (to_date('01.01.2019', 'dd.mm.yyyy'))
  into (partition p_2018, partition p_default) update indexes;
--4
drop view mytest_in_doc;
drop view mytest_out_doc;
rename table mytest_in_doc_original to mytest_in_doc;
rename table mytest_out_doc_original to mytest_out_doc;
--5
insert into mytest_in_doc select * from mytest_in_doc_2;
insert into mytest_out_doc select * from mytest_out_doc_2;
drop table mytest_out_doc_2;
drop table mytest_in_doc_2;


А триггер для чего?
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39726267
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Щукина Анна dbms_redefinition отменили?
Спасибо, сейчас гляну как это используется
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39726268
Вадиман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Примерно.
Если вьюха - простой SELECT * FROM table - то триггер не нужен.

online_redef - нет, не отменили.
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39726443
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Щукина Анна,
из докиPrivileges Required for the DBMS_REDEFINITION Package
Execute privileges on the DBMS_REDEFINITION package are granted to EXECUTE_CATALOG_ROLE. In addition to having execute privileges on this package, you must be granted the following privileges:
CREATE ANY TABLE
ALTER ANY TABLE
DROP ANY TABLE
LOCK ANY TABLE
SELECT ANY TABLE
The following additional privileges are required to execute COPY_TABLE_DEPENDENTS:
CREATE ANY TRIGGER
CREATE ANY INDEX
К сожалению таких привилегий у меня нет, так что пока не удалось этот пакет "пощупать"
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39726540
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если в новой секции не будет записей, то просто выполнить split
Это будет чисто операция над словарем + создание новых пустых секций

А вот кто догадался делать секционированный индекс ik_mytest_in_doc$doc_date глобальным -- заслуживает отдельного восхищения
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39726564
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rushchelК сожалению таких привилегий у меня нет, так что пока не удалось этот пакет "пощупать"

Значит ты не DBA. А DBMS_REDEFINITION девелоперам незачем заниматься (нормальный DBA никогда не даст).
А на "пощупать" - Oracle на домашний комп можно качать бесплатно.

SY.
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39726644
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вячеслав ЛюбомудровЕсли в новой секции не будет записей, то просто выполнить split
Это будет чисто операция над словарем + создание новых пустых секций

А вот кто догадался делать секционированный индекс ik_mytest_in_doc$doc_date глобальным -- заслуживает отдельного восхищенияВ новой секции P_2018 будут данные. Попробую, как Вадиман посоветовал. А есть еще идеи?
Если не трудно, можно про индекс развернуть мысль.
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39726649
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY, да не DBA, буду дома тренироваться.
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39726657
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rushchelВ новой секции P_2018 будут данные.А в P_DEFAULT ?
Если нет, то выполнится просто переименование на уровне словаря P_DEFAULT на P_2017 и создастся новая пустая секция P_DEFAULT
rushchelЕсли не трудно, можно про индекс развернуть мысль.Зачем делать секционированный индекс глобальным если ключ и границы секционирования одинаковы с таблицей?
Сейчас тебе придется также делать SPLIT секции индекса (отдельным оператором), а будь он локальным, все бы сделалось автоматом
Ну и локальный меньше места занимает :-)
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39726712
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вячеслав ЛюбомудровА в P_DEFAULT ?
Если нет, то выполнится просто переименование на уровне словаря P_DEFAULT на P_2017 и создастся новая пустая секция P_DEFAULTВ P_DEFAULT не будет данных. Ну так-то вроде логично. Поделаю тесты. По идее на уровне словаря это же быстро и не должно быть простоя?
Вячеслав ЛюбомудровЗачем делать секционированный индекс глобальным если ключ и границы секционирования одинаковы с таблицей?
Сейчас тебе придется также делать SPLIT секции индекса (отдельным оператором), а будь он локальным, все бы сделалось автоматом
Ну и локальный меньше места занимает :-)Ок учту. Значит в обслуживании локальный проще чем глобальный, по крайней мере в этом случае. Ну дома потренируюсь. А локальный индекс тоже будет по секциям и имена секций от таблицы будут браться?
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39727655
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я ведь правильно понимаю, если получил такое:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
begin
  dbms_redefinition.can_redef_table(uname => user, tname => 'IN_DOC');
end;
Error report -
ORA-23549: таблица "RUSH"."IN_DOC" используется в эталонном разбиении
ORA-06512: на  "SYS.DBMS_REDEFINITION", line 242
ORA-06512: на  "SYS.DBMS_REDEFINITION", line 5439
ORA-06512: на  line 2

То значит для таблицы нельзя выполнить online redefinition?
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39727693
Фотография Rb-Sr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rushchel,
В 12.2 split может быть online ведь

doc Partition maintenance with SPLIT operations are supported as online operations with the keyword ONLINE for heap organized tables, enabling concurrent DML operations while a partition maintenance operation is ongoing.
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39727701
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rushchelТо значит для таблицы нельзя выполнить online redefinition?

Скорее всего IN_DOC имeет child таблицы. Online redefinition тут невозможен, придется drop FK, redefinition, create FK.

SY.
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39727719
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYrushchelТо значит для таблицы нельзя выполнить online redefinition?
Скорее всего IN_DOC имeет child таблицы.
Не човчем.
Она является базовой для partition by reference.
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39727754
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymousSYпропущено...

Скорее всего IN_DOC имeет child таблицы.
Не човчем.
Она является базовой для partition by reference.Да, так и есть.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
--WITHOUT PARTITION BY REFERENCE------------------------------------------------
create table in_doc2 (
  in_id    number
 ,doc_date timestamp default systimestamp not null
 ,constraint pk_in_doc2 primary key (in_id)
) partition by range(doc_date) (
  partition p_2017 values less than (to_date('01.01.2018','dd.mm.yyyy'))
 ,partition p_default values less than (maxvalue)
);
create table out_doc2 (
  out_id   number
 ,in_id    number not null
 ,constraint pk_out_doc2 primary key (out_id)
 ,constraint fk_out_doc2$in_id foreign key (in_id) references in_doc2 (in_id)
);
create index ik_out_doc2$in_id on out_doc2 (in_id);
begin
  dbms_redefinition.can_redef_table(uname => user, tname => 'IN_DOC2');
end;
/
drop table out_doc2;
drop table in_doc2;

--SCRIPT OUTPUT-----------------------------------------------------------------

Table IN_DOC2 created.

Table OUT_DOC2 created.

Index IK_OUT_DOC2$IN_ID created.

PL/SQL procedure successfully completed.

Table OUT_DOC2 dropped.

Table IN_DOC2 dropped.

--WITH PARTITION BY REFERENCE---------------------------------------------------
create table in_doc3 (
  in_id    number
 ,doc_date timestamp default systimestamp not null
 ,constraint pk_in_doc3 primary key (in_id)
) partition by range(doc_date) (
  partition p_2017 values less than (to_date('01.01.2018','dd.mm.yyyy'))
 ,partition p_default values less than (maxvalue)
);
create table out_doc3 (
  out_id   number
 ,in_id    number not null
 ,constraint pk_out_doc3 primary key (out_id)
 ,constraint fk_out_doc3$in_id foreign key (in_id) references in_doc3 (in_id)
) partition by reference (fk_out_doc3$in_id);
create index ik_out_doc3$in_id on out_doc3 (in_id) local;
begin
  dbms_redefinition.can_redef_table(uname => user, tname => 'IN_DOC3');
end;
/
drop table out_doc3;
drop table in_doc3;

--SCRIPT OUTPUT-----------------------------------------------------------------

Table IN_DOC3 created.

Table OUT_DOC3 created.

Index IK_OUT_DOC3$IN_ID created.

Error starting at line : 17 in command -
begin
  dbms_redefinition.can_redef_table(uname => user, tname => 'IN_DOC3');
end;
Error report -
ORA-23549: таблица "RUSH"."IN_DOC3" используется в эталонном разбиении
ORA-06512: на  "SYS.DBMS_REDEFINITION", line 242
ORA-06512: на  "SYS.DBMS_REDEFINITION", line 5439
ORA-06512: на  line 2

Table OUT_DOC3 dropped.

Table IN_DOC3 dropped.
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39727755
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Rb-Sr,
Да, я пробовал использовать опцию ONLINE, но ORACLE отфутболил по причине, как в сообщении выше.
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39727811
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Итак, мои выводы по исходной задаче:
1) split partition online не доступен
2) нужно делать split partition во время минимальной активности в системе

Если бы в результате разбиения новая секция P_DEFAULT стала не пустой, то для минимизации простоя использовал бы советВадиманrename table + create view + "instead of insert" trigger + складываешь в сторонке + параллельно курочишь как хочешь исходные таблицыПоскольку в результате разбиения новая секция P_DEFAULT будет пустой, то просто выполню оператор
Код: plsql
1.
2.
alter table mytest_in_doc split partition p_default at (to_date('01.01.2019', 'dd.mm.yyyy'))
  into (partition p_2018, partition p_default) update indexes;


Запланирую работу на час ночи. Спасибо всем за советы!
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39728018
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rushchel1) split partition online не доступен

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
alter table in_doc3 split partition for (date'2018-06-01') at (date'2018-06-01'); 
Table altered.

alter table in_doc3 split partition for (date'2018-07-01') at (date'2018-07-01') ONLINE update indexes; 
Table altered.

select table_name, partition_name, high_value_length from user_tab_partitions order by table_name, partition_position;

TABLE_NAME	PARTITION_NAME	HIGH_VALUE_LENGTH
IN_DOC3	P_2017	31
IN_DOC3	SYS_P18906	31
IN_DOC3	SYS_P18908	31
IN_DOC3	SYS_P18909	8
OUT_DOC3	P_2017	0
OUT_DOC3	SYS_P18906	0
OUT_DOC3	SYS_P18908	0
OUT_DOC3	SYS_P18909	0

8 rows selected.
...
Рейтинг: 0 / 0
Как сделать split partition online?
    #39728059
rushchel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous, а с данными получится?
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
--CREATE OBJECTS----------------------------------------------------------------
create table in_doc3 (
  in_id    number
 ,doc_date timestamp default systimestamp not null
 ,constraint pk_in_doc3 primary key (in_id)
) partition by range(doc_date) (
  partition p_2017 values less than (to_date('01.01.2018','dd.mm.yyyy'))
 ,partition p_default values less than (maxvalue)
);
create table out_doc3 (
  out_id   number
 ,in_id    number not null
 ,constraint pk_out_doc3 primary key (out_id)
 ,constraint fk_out_doc3$in_id foreign key (in_id) references in_doc3 (in_id)
) partition by reference (fk_out_doc3$in_id);
create index ik_out_doc3$in_id on out_doc3 (in_id) local;
--INSERT DATA-------------------------------------------------------------------
insert into in_doc3 
select rownum
      ,systimestamp - trunc(500 * dbms_random.value)
  from dual connect by level <= 100;
commit;
insert into out_doc3 
select in_id
      ,in_id
  from in_doc3;
commit;
--ALTER TABLE-------------------------------------------------------------------
alter table in_doc3 split partition for (date'2018-06-01') at (date'2018-06-01'); 
alter table in_doc3 split partition for (date'2018-07-01') at (date'2018-07-01') online update indexes; 
drop table out_doc3 purge;
drop table in_doc3 purge;

--SCRIPT OUTPUT-----------------------------------------------------------------
Table IN_DOC3 created.

Table OUT_DOC3 created.

Index IK_OUT_DOC3$IN_ID created.

100 rows inserted.

Commit complete.

100 rows inserted.

Commit complete.

Table IN_DOC3 altered.

Error starting at line : 30 in command -
alter table in_doc3 split partition for (date'2018-07-01') at (date'2018-07-01') online update indexes
Error report -
SQL Error: ORA-14808: таблица не поддерживает ONLINE SPLIT PARTITION
14808. 00000 -  "ONLINE MOVE PARTITION is not supported for this table"
*Cause:    An ALTER TABLE MOVE PARTITION ONLINE statement was issued on a
           table that was either not a heap table or had an object type,
           domain index or bitmap join index defined on it. This operation is
           only supported for heap tables.
*Action:   Do not use the ONLINE keyword.

Table OUT_DOC3 dropped.

Table IN_DOC3 dropped.
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как сделать split partition online?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]