Maximum number of partitions

dbms_photoshop
Дата: 21.10.2015 18:54:14
+ Натолкнулся на поведение в продакшене
create table fact
(
   dt      date not null
  ,type    number not null
  ,value   number not null
)
partition by range (dt)
   interval ( interval '1' day )
   subpartition by hash (type) subpartitions 1024
   (partition values less than (date '2013-01-01'));

Table created.


insert into fact values (date '2013-10-21','1','1');

1 row created.

insert into fact values (date '2014-10-21','1','1');

1 row created.

insert into fact values (date '2015-01-01','1','1');

1 row created.

insert into fact values (date '2015-01-02','1','1');

1 row created.

insert into fact values (date '2015-10-20','1','1');
insert into fact values (date '2015-10-20','1','1')
*
ERROR at line 1:
ORA-14299: total number of partitions/subpartitions exceeds the maximum limit


insert into fact values (date '2015-10-21','1','1');
insert into fact values (date '2015-10-21','1','1')
            *
ERROR at line 1:
ORA-14300: partitioning key maps to a partition outside maximum permitted
number of partitions


alter table fact merge partitions for (date '2015-01-01'), for (date '2015-01-02') into partition part_merged;

Table altered.

insert into fact values (date '2015-10-20','1','1');

1 row created.

insert into fact values (date '2015-10-21','1','1');

1 row created.

insert into fact values (date '2016-10-21','1','1');

1 row created.

commit;

Commit complete.

select (date '2015-10-21' - date '2013-01-01' + 1) x from dual;

         X
----------
      1024
То есть все не рухнуло только из-за того, что проверка недосрабатывает если какие-то секции были объединены.
Думаю как теперь дешевле всего поднять нижний лимит, чтоб все было по честному, и стоит ли. :)
ORA__SQL
Дата: 21.10.2015 19:17:37
dbms_photoshop,
А какой объем таблицы? И какой initial extent?
Извращение какое-то:
subpartition by hash (type) subpartitions 1024
dbms_photoshop
Дата: 21.10.2015 21:37:05
ORA__SQL
А какой объем таблицы? И какой initial extent?
Я не вижу смысла отвечать на перпендикулярные к теме вопросы.
Допустим я скажу есть столько то записей каждый день.
Потом последуют комменты "та ты пи#дишь, столько быть не может" или "слыш, а какая у тебя предметная область" и прочий оффтоп.
Скоропостижные выводы про извращения тоже доставляют.

Возвращаясь к слиянию секций. В этом случае проверка выполняется не от нижней границы, а от "слияния минус день"
Для моего примера из первого поста
insert into fact values (date '2017-10-18','1','1');
insert into fact values (date '2017-10-18','1','1')
*
ERROR at line 1:
ORA-14299: total number of partitions/subpartitions exceeds the maximum limit


insert into fact values (date '2017-10-19','1','1');
insert into fact values (date '2017-10-19','1','1')
*
ERROR at line 1:
ORA-14300: partitioning key maps to a partition outside maximum permitted
number of partitions


select (date '2017-10-19' - date '2015-01-01' + 1 + 1) x from dual;

         X
----------
      1024

Судя по ноте "Insert Fails With ORA-14300 On Partition Table (Doc ID 1472941.1)" можно сделать вывод, что если работает - то прекрасно.
Типа проверка должна выполняться на фактическое число секций а не на основании расчета с первой секции (или смердженной секции или чего-то еще).
Короче видимо надо поговорить с саппортом.
SY
Дата: 21.10.2015 21:56:11
dbms_photoshop,

Ты бы доку покурил перед обращеним в support:

Creating Interval-Partitioned Tables

The INTERVAL clause of the CREATE TABLE statement establishes interval partitioning for the table. You must specify at least one range partition using the PARTITION clause. The range partitioning key value determines the high value of the range partitions, which is called the transition point, and the database automatically creates interval partitions for data beyond that transition point. The lower boundary of every interval partition is the non-inclusive upper boundary of the previous range or interval partition.

For example, if you create an interval partitioned table with monthly intervals and the transition point is at January 1, 2010, then the lower boundary for the January 2010 interval is January 1, 2010. The lower boundary for the July 2010 interval is July 1, 2010, regardless of whether the June 2010 partition was previously created. Note, however, that using a date where the high or low bound of the partition would be out of the range set for storage causes an error. For example, TO_DATE('9999-12-01', 'YYYY-MM-DD') causes the high bound to be 10000-01-01, which would not be storable if 10000 is out of the legal range.


В твоем случае lower boundary date '2013-01-01' а посему high boundary date '2013-01-01' + 1023.

SY.
SY
Дата: 21.10.2015 22:14:13
Т.e у любой range секции, включая интервальные, есть нижняя и верхняя границы. Я тоже когда-то ошибочно считал что у интервальных range секций есть нижняя граница + число интервалов.

SY.
ORA__SQL
Дата: 21.10.2015 23:29:09
dbms_photoshop
ORA__SQL
А какой объем таблицы? И какой initial extent?
Я не вижу смысла отвечать на перпендикулярные к теме

Никакого флуда, просто любопытно с какими объемами работаете.
Для меня такое кол-во партиций из области фантастики, если они действительно все не пустые.
dbms_photoshop
Дата: 21.10.2015 23:59:18
SY
В твоем случае lower boundary date '2013-01-01' а посему high boundary date '2013-01-01' + 1023
Не совсем понятно с какой целью это все было процитировано, если я в самом первом посте указал почему изначально валится именно на 20-м октября.

Что меня смущает - так это то, что после слияния проверка уже работает по другому.
Если обратить внимание, то видно что после слияния я вставил обе строки, которые вызывали ORA-14299 и ORA-14300 и более того строку еще на год вперед.

Возможно, как-то проверка зависит от типа секций, очевидно, что после слияния, тип меняется
select interval, to_date(regexp_substr(high_value, '\d{4}-\d{2}-\d{2}'), 'yyyy-mm-dd') - 1 dt
  from xmltable('/ROWSET/ROW'
       passing((select dbms_xmlgen.getxmltype('select * from user_tab_partitions t where table_name = ''FACT''') from dual))
       columns
       interval varchar2(10) path 'INTERVAL',
       high_value varchar2(30) path 'HIGH_VALUE')
 order by 2;

INTERVAL   DT
---------- ---------
NO         31-DEC-12
YES        21-OCT-13
YES        21-OCT-14
YES        01-JAN-15
YES        02-JAN-15

alter table fact merge partitions for (date '2015-01-01'), for (date '2015-01-02') into partition part_merged;

Table altered.

select interval, to_date(regexp_substr(high_value, '\d{4}-\d{2}-\d{2}'), 'yyyy-mm-dd') - 1 dt
  from xmltable('/ROWSET/ROW'
       passing((select dbms_xmlgen.getxmltype('select * from user_tab_partitions t where table_name = ''FACT''') from dual))
       columns
       interval varchar2(10) path 'INTERVAL',
       high_value varchar2(30) path 'HIGH_VALUE')
 order by 2;

INTERVAL   DT
---------- ---------
NO         31-DEC-12
NO         21-OCT-13
NO         21-OCT-14
NO         02-JAN-15


Повторюсь,
1) до слияния отсчет шел от верхней границы первой секции
2) после слияния отсчет пошел от верхней границы первой из объединенных секций минус день

То есть, возможность вставить данные определяется некоторой точкой отсчета + 1024 дня * 1024 секций.

Можно придумать еще что лимит подразумевал бы возможность вставить до 1024K секций "с дырками" независимо от первой секции, объединенной секции или еще чего-то.
Но так оно очевидно не работает.

То есть сейчас в базе, (лимит последней секции - лимит первоц секции)*1024 > 1024K.
Это нормальное поведение или нет?
Еще раз повторюсь, что это стало возможным только потому что "когда-то что-то" было смерджено.
orawish
Дата: 22.10.2015 10:32:58
dbms_photoshop,

однако, баян
разумеется, с поправкой на композитность - в вашем случае
init.ora
Дата: 22.10.2015 12:24:15
create table fact
(
   dt      date not null
  ,type    number not null
  ,value   number not null
)
partition by range (dt)
interval ( interval '1' day )
subpartition by hash (type) subpartitions 1024
(partition values less than (date '2013-01-01'));
insert into fact values (date '2013-10-21','1','1');
insert into fact values (date '2014-10-21','1','1');
insert into fact values (date '2015-01-01','1','1');
insert into fact values (date '2015-01-02','1','1');
commit;


SQL> select count(1) СNT
  2  from user_tab_partitions
  3  where table_name = 'FACT'
  4  /
       СNT
----------
         5


Чтобы "сдвинуть" нарезку секций можно использовать:
alter table fact set interval(interval '1' day);

После этого нарезка секций будет делаться с последней созданной секции (date '2015-01-02')
И если попробовать вставить данные до этой даты, то новые секции создаваться уже не будут
insert into fact values (date '2013-10-10','1','1');
SQL> select count(1) СNT
  2  from user_tab_partitions
  3  where table_name = 'FACT'
  4  /
       СNT
----------
         5

-- После - будут

insert into fact values (date '2015-10-20','1','1');  
 SQL> select count(1) СNT
  2  from user_tab_partitions
  3  where table_name = 'FACT'
  4  /
       СNT
----------
         6
dbms_photoshop
Дата: 22.10.2015 12:53:05
orawish
dbms_photoshop,

однако, баян
разумеется, с поправкой на композитность - в вашем случае
Разумеется если читать не по диагонали, то могут возникнуть иные мысли что баян а что нет.
+
drop table ttt;

Table dropped.

create table ttt
(
   p   number(10) not null
  ,v   varchar2(500)
)
partition by range (p)
   interval ( 1 )
   (partition p0 values less than (0));

Table created.


insert into ttt(p) values ( 1048576-2 );
insert into ttt(p) values ( 1048576-2 )
            *
ERROR at line 1:
ORA-14300: partitioning key maps to a partition outside maximum permitted
number of partitions



insert into ttt(p) values(1000000);

1 row created.

insert into ttt(p) values(1000001);

1 row created.


alter table ttt merge partitions for (1000000), for (1000001) into partition part_merged;

Table altered.


insert into ttt(p) values ( 1048576 );

1 row created.

insert into ttt(p) values ( 1500000 );

1 row created.
Сначала SY начинает писать банальщину, теперь вы.
Я вроде даже выделил жирным основные моменты и повторил несколько раз что смущает и вопрос.
Пост был написан из расчета может кто сталкивался да и просто узнать мнения.

А то на работе для одной таблицы свалилось 20 октября, а для другой аналогичной нет.
Я пишу "Oracle fails to check 1M limit if some partitions were merged", тут сразу же появляется множество писем от одаренных личностей, которые ничего самостоятельно расследовать не в состоянии, зато везде пытаются вставить 5 копеек. И они начитнаю разводить демагогию, что то, что Оракл начинает проверять с другой точки, это он не fails. Это просто сдвигается точка отсчета и вообще легко объяснимое поведение. Непонятно только чего сами до него не доперли раз так.

Я описания такого поведения не нашел. Может что-то пропустил.