Thursday, June 28, 2007

ORA-01429: Index-Organized Table: no data segment to store overflow row-pieces

I am a great fan of IOTs aka Oracle's Index Organized Tables.
As written in the documentation, they are most useful when accessed by their primary key, for the simple fact that the table's rows are kept "in order" according to such index, which means they can be scanned very efficiently.
Typical candidates for IOTs are lookup tables, that is tables where you know the value of their primary key in advance.
A very common scenario for an IOT is to store simple data like a table of cities (city_id and city_name) and you want to display the name of a store along with the city name where the store is located.
Normally you don't put the city name in the stores table, but you put the city_id, that is the foreign key to the cities table and then you look up city_name by means of a join (hence the name lookup table...).

So, back to my problem, i was trying to execute a DDL statement like:

create table yocoya_notifications
(application_id number,
language_code varchar2(5),
message_text varchar2(4000),
last_updated_on date default sysdate,
last_updated_by varchar2(255),
constraint yocoya_notifications_pk primary key (application_id, language_code)
) organization index
/
but with some surprise i got:

ORA-01429: Index-Organized Table: no data segment to store overflow row-pieces
Hmm, i was sure i had already created many other IOTs in the past with such minimal instructions.

I went to the error description and it says:
Cause: No overflow segment defined.
Action: Add overflow segment.
Why i do i need to add an overflow segment? I didn't need it in the past!

The fact is easily explained.
If i recreate the table with a smaller size for column MESSAGE_TEXT, say VARCHAR2(2000) instead of VARCHAR2(4000), Oracle accepts the DDL statement without a hitch.

If you read the documentation about CREATE TABLE, where it starts talking about the IOT overflow segment, then you'll find a reference to a possible error condition that can be raised when Oracle estimates that the row size might be larger than it fits in a single block.
Note also that i didn't specify a value for PCTTHRESHOLD, this means that Oracle defaulted it to 50 (% of block size), which in my case would mean 4096 bytes because the tablespace is made up of blocks of 8192 bytes.

At this point, in order to store up to 4000 bytes in this column, i'll have to specify an overflow segment that can accommodate MESSAGE_TEXT along with all the subsequent columns (LAST_UPDATED_ON and LAST_UPDATED_BY) in a separate block.

In practice, in the simplest case, this translates into adding the keyword OVERFLOW at the end of the statement above.

-------------------------------------------------
ORA-01429: Tabella organizzata a indice: nessun segmento dati per memorizzare row-pieces di overflow
ORA-01429: Tabla organizada por índice: no hay ningún segmento de datos para almacenar las partes de filas desbordadas
ORA-01429: Taula organitzada en índexos: no hi ha segment de dades per a emmagatzemar peces de fila de sobreeiximent
ORA-01429: Table organisée en index : pas de segment de données pour stocker les données de ligne en dépassement
ORA-01429: Index-organisierte Tabelle: Kein Datensegment zum Speichern überlaufender Zeilenstücke
ORA-01429: Πίνακας με Οργάνωση Ευρετηρίου: δεν υπάρχει τμήμα (segment) δεδομένων για αποθήκευση κομματιών γραμμών υπερχείλισης
ORA-01429: Indeksorganiseret tabel: Intet datasegment til lagring af overløbsrækkestykker
ORA-01429: Indexerad tabell: inga datasegment vid lagring av radspill
ORA-01429: Indeksert tabell: intet datasegment for lagring av ekstra radstykker
ORA-01429: Indeksi-organisoitu taulu: ei tieto-osaa, johon tallentaa riviylivuodot
ORA-01429: Index-szervezésű tábla: nincs adatszegmens a túlcsorduló sor-részek tárolásához
ORA-01429: Tabelă Organizată Index: nu există segment de date ptr. stocarea liniilor în plus
ORA-01429: Tabel met indexordening: geen gegevenssegment om overloop van rijonderdelen op te slaan.
ORA-01429: Tabela Organizada por Índice: não há segmento de dados para armazenar componentes de linha de overflow
ORA-01429: Tabela Organizada por Índices: não existe segmento de dados para armazenar excesso de row-pieces
ORA-01429: Индексная таблица: отсутствует сегмент данных для записи дополнительных отрезков строки
ORA-01429: Tabulka org. podle indexu: není datový segment pro uložení přetékajících částí řádku
ORA-01429: Indexovo organizovaná tabuľka: žiadny dátový segment na uloženie pretečených riadkových kusov
ORA-01429: Tabela wyłącznie indeksowa: brak segmentu danych pozwalającego przechować nadmiarowe wiersze
ORA-01429: Dizin-Düzenli Tablo: taşan satır parçalarını saklayacak veri segmenti yok

3 comments:

Anonymous said...

Your DDL statement look like what now?

Byte64 said...

create table yocoya_notifications
(application_id number,
language_code varchar2(5),
message_text varchar2(4000),
last_updated_on date default sysdate,
last_updated_by varchar2(255),
constraint yocoya_notifications_pk primary key (application_id, language_code)
) organization index overflow
/

Anonymous said...

When using the ALTER command, you'd have to do it in two steps:

ALTER TABLE yocoya_notifications
ADD OVERFLOW;

ALTER TABLE yocoya_notifications
ADD message_text varchar2(4000);

Regards,
bine

yes you can!

Two great ways to help us out with a minimal effort. Click on the Google Plus +1 button above or...
We appreciate your support!

latest articles