Este artigo est� escrito em Ingl�s e Portugu�s
English version:
Back to Panther... Although I'm not in the video on the right, I do love Informix. That doesn't mean I ignore some issues it has (or had in this particular case). One thing that always worries an Informix DBA is the number of extents in his tables. Why? Because it used to have a maximum amount, and because that maximum was pretty low (if compared with other databases). But what is an extent? In short an extent is a sequence of contiguous pages (or blocks) that belong to a specific table or table partition. A partition (a table has one or more partitions) has one or more extents.
Before I go on, and to give you some comparison I'd like to tell you about some feedback I had over the years from a DBA (mostly Oracle, but who also managed an Informix instance):
- A few years ago he spent lots of time running processes to reduce the number of extents in a competitor database that had reach an incredible number of extents (around hundreds of thousands). This was caused by real large tables and real badly defined storage allocation
- Recently I informed the same customer that Informix was eliminating the extent limits and the same guy told me that he was afraid that it could lead to situations as above. He added, and I quote, "I've always admired the way Informix deals with extents"
- After 16 allocations of new extents Informix automatically doubles the size of the next extent for the table. This decreases the number of times it will try to allocate a new extent. So, using only this rule (which is not correct as we shall see) if you create a table with a next size of 16K, you would reach 4GB with around 225 extents.
- If Informix can allocate a new extent contiguous to an already existing one (from the same table of course) than it will not create a new one, but instead it will extend the one that already exists (so it does not increase the number of extents). This is one reason why rule number one may not be seen in practice. In other words, it's more than probable that you can reach 4GB with less than 225 extents.
- In version 11.50 if I'm correct, a fix was implemented to prevent excessive extent doubling (rule 1). If the next extent size is X and the dbspace only has a maximum of Y (Y < X) informix will allocate Y and will not raise any error.
If this happens many times, we could end up having a number of allocated pages relatively small, but a next extent size too big. There's a real problem in this: If in these circumstances we create another chunk in the same dbspace, and after that our table requires another extent, the engine could reserve a large part of the new (and possibly still empty) chunk to our table. This can be much more than the size already allocated to the table. To avoid this, extent doubling will only happen when there is a reasonable relation between the new calculated next extent size and the space effectively allocated to the table. - Extent description in Informix have never been stored in the database catalog. This leads to simpler and efficient space management. Compared to other databases that used to do the management in the catalog, they tend to hit issues in the SQL layer and at the same time these were slower. One of our competitors changed that in their later versions, and DBAs have seen improvement with that (but they had to convert). Informix always worked the better way...
Why didn't we have a fix limit and why was it different in several platforms? In order to explain that we must dive a bit deeper in the structure of a dbspace and tables. Each partition in Informix has a partition header. Each partition header is stored in exactly one Informix page. There is a special partition in every dbspace (tablespace tablespace) that holds every partition headers from that dbspace. This special partition starts in a specific page but then, it can contain more than one extent.
Also important to understand this is the notion of slot. Most Informix pages contain several slots. For a data page, a slot contains a row (in the simplest cases). A partition header is a page that contains 5 slots:
- Slot 1
This contains the partition structure (things like creation date, partition flags, maximum row size, number of special columns - VARCHAR and BLOB -, number of keys - if it's an index or has index pages -, number of extents and a lot of other stuff. If you want to see all the details check the sysptnhdr table in $INFORMIXDIR/etc/sysmaster.sql. It's basically an SQL interface for the partition headers in the instance.
In version 11.50 this slot should occupy 100 bytes. Previous versions can have less (no serial 8, and bigserial) - Slot 2
Contains the database name, the partition owner, the table name and the NLS collation sequence - Slot 3
Contains details about the special columns. If there are no special columns this slot will be empty - Slot 4
Contains the description for each key (if it's an index or a mix). Starting with version 9.40, by default the indexes are stored in their own partitions. This was not the case in previous versions. A single partition could contain index pages interleaved with data pages.
Currently, by default, a partition used for data should not have any key, so this slot will be empty - Slot 5
Finally, this is the slot that contains the list of extents.
A table that reached it's maximum number of extents was a very real and serious problem in Informix. If you reach the table limit for number of extents and all your table's data pages are full, the engine would need to allocate one more extent in order to complete new INSERTs. But for that it would require some free space in the partition header. If there was no space left, any INSERT would fail with error -136:
-136 ISAM error: no more extents.
After hitting this nasty situation there were several ways to solve it, but all of them would need temporary table unavailability, which in our days is rare... We tend to use 24x7 systems. Even systems that have a maintenance window would suffer with this, because most of the time the problem was noticed during "regular" hours...
So, I've been talking in the past... This used to be a problem. Why isn't it a problem anymore? Because Panther (v11.7) introduced two great features:
- The first one is that it is able to automatically extend the partition header when slot 5 (the extent list) becomes full. When this happens it will allocate a new page for the partition header that will be used for the extent list. So you should not see error -136 caused by reaching the extent limit. At first you may think like my customer DBA: "wow! Isn't that dangerous? Will I get tables/partitions with tens of thousands of extents?". The answer is simple. You won't get that high number of extents because all the nice features that were always there (automatic extent concatenation, extent doubling...) are still there. This will just avoid the critical situation where the use of the table would become impossible (new INSERTs). And naturally it doesn't mean that you should not care about the number of extents. For performance reasons it's better to keep them low
- The second great feature is an online table defragmenter. They can grow forever, but that's not good. Once you notice you have a table with too many extents you can ask the engine to defragment it. I will not dig into this simply because someone else already did it. I recommend you check the recent DeveloperWorks article entitled "Understand the Informix Server V11.7 defragmenter"
Vers�o Portuguesa:
De volta � Panther... Apesar de n�o estar no v�deo � direita, eu adoro o Informix. Isso n�o significa que ignore alguns problemas que ele tem (ou tinha neste caso particular). Uma coisa que preocupa qualquer DBA Informix � o n�mero de extents das suas tabelas. Porqu�? Porque esse n�mero tinha um m�ximo, e porque esse m�ximo era bastante baixo (se comparado com outras bases de dados). Mas o que � um extent? De forma simples, um extent � uma sequ�ncia cont�gua de p�ginas (ou blocos) que pertencem a uma tabela ou parti��o de tabela. Uma parti��o (uma tabela tem uma ou mais parti��es) tem um ou mais extents.
Antes de continuar, e para estabelecer uma compara��o, gostaria de transmitir algum feedback que ao longo de anos tive de um DBA (essencialmente Oracle, mas tamb�m geria uma inst�ncia Informix):
- H� alguns anos atr�s passou bastante tempo a executar processos para reduzir o n�mero de extents de uma base de dados concorrente do Informix. Essa base de dados tinha tabelas que atingiram um n�mero incr�vel de extents (na casa das centenas de milhar). Isto foi causado por tabelas verdadeiramente grandes e cl�usulas de aloca��o de espa�o realmente mal definidas
- Recentemente informei esse mesmo cliente que o Informix ia eliminar o limite de extents, e a mesma pessoa disse-me que tinha receio que isso pudesse levar a situa��es como a de cima. Ele acrescentou, e cito: "Se h� coisa que sempre admirei foi a maneira como o Informix gere os extents".
- Ap�s cada 16 novos extents adicionados, o Informix automaticamente duplica o tamanho do pr�ximo extent da tabela. Isto diminui o n�mero de vezes que tenta reservar um novo extent. Usando apenas esta regra (o que n�o � correcto como veremos a seguir), se criar uma tabela com o extent m�nimo (16KB), a tabela pode crescer at� aos 4GB com cerca de 225 extents.
- Se o Informix conseguir reservar um novo extent que seja cont�guo a um que j� esteja alocado � mesma tabela, ent�o em vez de criar um novo, vai alargar o j� existente (portanto n�o aumenta o n�mero de extents). Esta � a raz�o porque a regra anterior pode n�o ser verificada na pr�ctica. Por outras palavaras � mais que prov�vel que consiga atingir os 4GB com menos de 225 extents.
- Salvo algum erro, na vers�o 11.50 foi introduzida uma melhoria para prevenir a duplica��o excessiva do tamanho do pr�ximo extent (regra 1). Se o tamanho do pr�ximo extent for X, mas o dbspace s� tiver um m�ximo de Y espa�o livre cont�guo (Y < X) o Informix vai cri�-lo com o tamanho Y e nem se queixar� de nada. Se isto acontecer muitas vezes, podemos acabar por ter um n�mero de p�ginas efectivas de uma tabela ou parti��o relativamente pequeno e um tamanho para o pr�ximo extent muito grande. Existe um problema real nisto: Se nessas cirunst�ncias for criado um novo chunk nesse dbspace, e a tabela precisar de novo extent, pode acontecer que o motor reserve grande parte, ou mesmo a totalidade do novo chunk para a tabela (possivelmente muito mais que o tamanho j� reservado at� ent�o). Para evitar isto, a duplica��o do tamanho do pr�ximo extent s� acontece quando o novo tamanho tem uma rela��o razo�vel com o espa�o reservado at� ent�o. Caso contr�rio o tamanho do pr�ximo extent a alocar n�o � duplicado.
- A informa��o dos extents em Informix nunca foi guardada nas tabelas de cat�logo. Isto faz com que a sua gest�o seja mais simples e eficiente. Comparada com outras bases de dados que faziam a gest�o no cat�logo, estas tendiam a encontrar problemas e constrangimentos pr�prios da camada de SQL, e ao mesmo tempo eram mais lentas. Um dos concorrentes mudou isto h� umas vers�es atr�s e os seus utilizadores viram benef�cios bem not�rios (mas tiveram de converter). O Informix sempre trabalhou da melhor forma...
Porque � que o limite n�o � fixo, e porque � diferente consoante a plataforma? Para explicar isto temos de nos debru�ar de forma mais detalhada na estrutura f�sica de um dbspace e tabela. Cada parti��o em Informix tem um cabe�alho. Cada cabe�alho de parti��o � guardado numa p�gina Informix. Existe uma parti��o especial em cada dbspace (designada habitualmente por tablespace tablespace) que guarda todos os cabe�alhos das parti��es criadas nesse dbspace. Esta parti��o especial come�a numa p�gina espec�fica do primeiro chunk do dbspace, mas pode ter mais que um extent.
Igualmente importante para compreender isto � a no��o de slot. A maioria das p�ginas Informix est�o divididas em slots. Para uma p�gina de dados um slot cont�m uma linha de dados da tabela (caso mais simples). Um cabe�alho de parti��o � uma p�gina que cont�m cinco slots:
- Slot 1
Este cont�m a estrutura da parti��o (coisas como a data de cria��o, flags, tamanho m�ximo de uma linha, num�ro de colunas ditas especiais - VARCHAR e BLOBs -, n�mero de chaves - se for um ind�ce ou tiver p�ginas de ind�ce -, n�mero de extents e uma s�rie de outros detalhes. Se tiver curiosidade em saber o que l� est� guardado consulte a tabela sysptnhdr na base de dados sysmaster (ou o ficheiro $INFORMIXDIR/etc/sysmaster.sql). Basicamente esta tabela � um interface SQL sobre todos os cabe�alhos de parti��o da inst�ncia Informix.
Na vers�o 11.50 este slot ocupa 100 bytes. Vers�es anteriores podem ocupar menos (aus�ncia do serial8 e bigserial) - Slot 2
Cont�m o nome da base de dados, dono da parti��o, nome da tabela e a NLS collation sequence - Slot 3
Cont�m detalhes sobre todas as colunas especiais. Se n�o existirem colunas especiais (VARCHAR e BLOB) este slot estar� vazio. Se existirem, o tamanho ocupado depender� da estrutura da tabela. - Slot 4
Cont�m a descri��o de cada chave (se for um �ndice ou um mix). Desde a vers�o 9.40, por omiss�o os ind�ces s�o guardados em parti��o � parte. Isto n�o era assim em vers�es anteriores. Uma parti��o podia conter p�ginas de ind�ces e de dados.
Actualmente, por omiss�o, uma parti��o usada para dados n�o deve ter nenhuma chave, e assim este slot deve estar vazio - Slot 5
Finalmente, este � o slot que cont�m a lista dos extents.
Uma tabela que atingisse o n�mero m�ximo de extents tornava-se num problema s�rio em Informix. Quando tal acontece, se todas as p�ginas de dados estiverem cheias, o motor ter� de reservar um novo extent para completar novos INSERTs. Mas para isso necessitaria de espa�o livre no cabe�alho da parti��o. Portanto, n�o havendo a� espa�o livre todos os INSERTs falhariam com o erro -136:
-136 ISAM error: no more extents.
Depois de batermos nesta situa��o havia v�rias formas de a resolver, mas todas elas necessitavam de indisponibilidade tempor�ria da tabela, o que nos dias que correm � um bem raro... A tend�ncia � usarmos sistemas 24x7. Mesmo sistemas que tenham janela de manuten��o sofreriam com isto, porque na maioria das vezes o problema manifestava-se durante o hor�rio normal ou produtivo...
Bom, mas tenho estado a falar no passado.... Isto costumava ser um problema. Porque � que j� n�o o �? Porque a vers�o 11.7 (Panther) introduziu duas excelentes funcionalidades:
- A primeira � que a partir de agora � poss�vel estender automaticamente o cabe�alho da parti��o quando o slot cinco enche. Nesta situa��o, uma nova p�gina � reservada para o cabe�alho da parti��o e a lista de extents pode crescer. Portanto n�o dever� voltar a ver o erro -136 causado por atingir o limite de extents. � primeira vista pode ter a mesma reac��o que o DBA do meu cliente. "Epa! Mas isso n�o � perigoso? Vou passar a ter tabelas/parti��es com dezenas de milhares de extents?". A resposta � simples. N�o vai atingir esses n�meros de extents porque todas as boas caracter�sticas que sempre existiram (jun��o autom�tica de extents, duplica��o de tamanho do pr�ximo extent...) ainda est�o presentes e funcionais. Isto apenas evitar� a situa��o cr�tica em que o uso da tabela se tornava imposs�vel (para novos INSERTs). E naturalmente isto n�o significa que passemos a ignorar o n�mero de extents das nossas tabelas. Por quest�es de desempenho � melhor mant�-los baixos.
- A segunda grande funcionalidade � um desfragmentador online de tabelas ou parti��es. O n�mero de extents pode crescer indefinidamente, mas isso n�o � bom. Assim que notar que tem uma parti��o com um n�mero elevado de extents pode pedir ao motor que a desfragmente. N�o vou aprofundar este tema, simplemente porque j� foi feito. Recomendo que consulte um artigo recente do DeveloperWorks intitulado "Understand the Informix Server V11.7 defragmenter". Infelizmente o artigo s� tem vers�o em Ingl�s