Showing posts with label sql. Show all posts
Showing posts with label sql. Show all posts

Friday, April 25, 2014

EXECUTE IMMEDIATE: SQL injection prevention / EXECUTE IMMEDIATE: Prevenção SQL injection

This article is written in Englsih and Portuguese (original version here)
Este artigo está escrito em Inglês e Português (versão original aqui)


English version
Recently I was requested to implement some stored procedures on a customer site. The request was urgent and I must admit I didn't pay enough attention. The procedures needed to accept some values that would be used inside some SQL statements. Basic best practices mandate that we must check all parameters and in such cases use prepared statements. These principles provide for better interaction with the calling layer and more important, help us avoid a classic and nasty security flaw called SQL injection.
The idea behind SQL injection is terribly simple and efficient: By supplying specially crafted parameters we explore the developer's mistake of not sanitizing those parameters and blindly use them to construct SQL statements. By doing so we may be able to change the meaning of those statements or eventually terminate them and include our own. A couple of examples:

  1. An authentication page uses the SQL statement:
    SELECT
        COUNT(*)
    FROM
        user_table
    WHERE
        user_name = $USER AND user_pass = '$PASS'
    

    and we supply these arguments:
    'john_doe'
    'dummy'' OR ( user_name = ''john_doe'' )'
    

  2. An online banking uses the SQL statement:
    UPDATE
        balance_account
    SET
        ammount = ammount - $VALUE
    WHERE
        account_number = $SOME_NUMBER
    

    and we supply these arguments:
    - 1000
    our_account_number
    

Well, after the procedures were created and some basic testing was done I had a bit more time to look at the code and I noticed I used the SQL instruction "EXECUTE IMMEDIATE..." where I was just concatenating some SQL with the provided arguments. Some of them were being slightly checked, but others were not checked at all. I was alarmed and ashamed by that piece of code and I decided to prove it was crappy... I tried to send weird parameters which included a semi-colon and a full statement following it. As an example consider something like:

CREATE PROCEDURE test_proc(table_name VARCHAR(20))
    EXECUTE IMMEDIATE "DROP TABLE " || table_name
END PROCEDURE;

And I tried to send "some_table;DROP DATABASE d"

(consider that some_table is an existent table name and "d" and existing database)
It raised error

26058: EXECUTE IMMEDIATE and PREPARE in SPL cannot allow multiple SQL statements

Which was a bit of a surprise. I tried other variations and they all failed.
The error description is clear. And the manual too:

http://www-01.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.sqls.doc/ids_sqs_0768.htm?lang=en

As a security measure or not, EXECUTE IMMEDIATE and PREPARE, inside stored procedures don't allow the execution of more than one instruction. A reason for that can be to avoid this specific type of SQL injection exploitation. So it was a good surprise to see that the good people in R&D have thought about something that I failed to (at my first attempt). This is a good security measure. But don't get too enthusiastic.... Terminating a statement and including another on in a variable or argument is just one of the SQL injection attacks. It will be useless on the two examples above. So be aware and never do the same error I was about to do: Always check your parameters and if possible PREPARE your statements. That's the way to avoid these security issues.
For the so called "cursory" statements we can use PREPARE, DECLARE, OPEN, FETCH, CLOSE and FREE. For non-cursory statements we need to use EXECUTE IMMEDIATE. In any case, it's essential to validate all inputs!





Versão Portuguesa
Recentemente foi-me pedido que implementasse algumas stored procedures num cliente. O pedido era urgente e devo admitir que não prestei a devida atenção. Os procedimentos necessitavam de aceitar alguns valores que seriam depois usados em instruções SQL. As boas práticas mais simples ditam que temos sempre de validar os inputs e sempre que possível usar prepared statements. Estes princípios permitem uma melhor interação com a camada que executa os procedimentos (ou genericamente funções), e mais importante, ajudam-nos a evitar uma falha de segurança bastante má, chamada SQL injection.
A ideia base do SQL injection é terrivelmente simples mas eficiente: Fornecendo argumentos "construidos", exploramos falhas dos programadores que não validam nem purificam os argumentos que lhes são passados, usando-os cegamente na construção de instruções SQL. Ao fazê-lo podemos alterar o sentido dessas instruções e eventualmente até terminá-las e escrevendo outras imediatamente a seguir. Um par de exemplos:
  1. Uma página de autenticação usa a seguinte instrução:
    SELECT
        COUNT(*)
    FROM
        tabela_utilizadores
    WHERE
        nome_utilizador = $USER AND pass_utilizador = '$PASS'
    

    e fonecemos estes argumentos:
    'john_doe'
    'dummy'' OR ( nome_utilizador = ''john_doe'' )'
    

  2. Uma aplicação de banco online utiliza esta instrução SQL:
    UPDATE
        tabela_contas
    SET
        saldo = saldo - $VALUE
    WHERE
        numero_conta = $UM_NUMERO
    

    e fornecemos estes argumentos:
    - 1000
    our_account_number
    

Bom, depois de ter criado os procedimentos, e após alguns testes básicos de funcionalidade, tive um pouco mais de tempo para examinar o código e verifiquei que estava a usar a instrução "EXECUTE IMMEDIATE...", e estava apenas a concatenar um pedaço de SQL com os argumentos fornecidos. Alguns tinham algum tipo de validação muito básica, mas outros não eram validados de todo. Fiquei alarmado e envergonhado com algum daquele código e decidi provar a mim mesmo que aquilo não prestava.... Tentei enviar parâmetros compostos de forma específica, incluind um ";" e uma instrução completa em seguida. A título de exemplo considere algo como:

CREATE PROCEDURE test_proc(table_name VARCHAR(20))
    EXECUTE IMMEDIATE "DROP TABLE " || table_name
END PROCEDURE;
E tentei usar como argumento "tabela_teste;DROP DATABASE d"

(considere que "tabela_teste" era o nome de uma tabela existente e que "d" era o nome de uma base de dados também existente)
Obtive um erro:

26058: EXECUTE IMMEDIATE and PREPARE in SPL cannot allow multiple SQL statements
Isto foi um pouco surpreendente. Tentei outras variações e todas falharam.
A descrição do erro parecia clara. E o manual também:

http://www-01.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.sqls.doc/ids_sqs_0768.htm?lang=en

Por medida de segurança ou não, o EXECUTE IMMEDIATE e o PREPARE dentro de procedimentos SPL não permitem a execução de mais que uma instrução. Uma razão para tal pode ser evitar este tipo específico de exploração de SQL injection. A ser assim foi uma surpresa agradável que o pessoal de I&D se tenha lembrado de algo que eu me esqueci (na primeira versão). Isto constitui uma boa medida de segurança. Mas não fique demasiado entusiasmado.... Terminar uma instrução e incluir outra é apenas uma das variantes do SQL injection. É inútil nos dois exemplos acima. Portanto esteja atento e nunca cometa o mesmo erro que estive á beira de cometer: verifique sempre os parâmetros e se possível utilize o PREPARE das suas instruções SQL. Essa é ainda a melhor forma de evitar estes problemas.
Para as instruções baseadas em cursores podemos usar o PREPARE, DECLARE, OPEN, FETCH, CLOSE e FREE. Para instruções que não retornem um conjunto de resultados necessitamos de usar o EXECUTE IMMEDIATE. Em qualquer caso é essencial validar todos os inputs!

Wednesday, February 19, 2014

New feature? / Nova funcionalidade?

This article is written in English and Portuguese (original version here)
Este artigo está escrito em Inglês e Português (versão original aqui)


English version:

The fun...

Working with Informix has been much fun, but sometimes for strange reasons. One of those is the consequence of not being considered a "mainstream" database. From time to time I see references to features of "mainstream" databases that do amuse me. It surely happens the other way around, but the echoes of that are naturally smaller and could be expected from what bloggers and analysts would consider a non-Tier 1 database. So, when this happens It really makes my day...
This time, while browsing the Net, I noticed several articles or posts talking about a "new fascinating feature" of SQL Server 2014 CTP2 (pre-release) called Delayed Transaction Durability. Well... After reading some of those posts including the "official source" I was a bit surprised that this is just what we call buffered logging! Yes... The ability to delay logical log buffer flush until the logical log buffer is full. And yes, same as us, it means that an application can assume something is committed while if there is a database crash it won't (the fast recovery process will rollback the transaction).
So, as you may expect, most bloggers were careful to note this could lead to data loss. In fact the database integrity is preserved, but because the application receives the commit "ok" message before it was actually written to disk, a crash in the specific interval would mean the transaction would be incomplete so a rollback would happen during recovery.
So why use it? Performance... But in fact most customers don't want to risk and they usually choose unbuffered logging.

What we have

But why am I writing this? Just to make fun of our competitor and the fact that they're announcing and talking about a feature that everybody else (Informix, Oracle, DB2, MySQL, Postgres...) seems to have? Not really... although it is funny to see this situation over and over again (happened recently with SQL Server's high availability options also...).
The fact is that there's more to this than what immediately comes to mind. First, I'd bet most of our customers know about the [BUFFERED] LOG option of the CREATE DATABASE statement, but they possibly don't know about the SET [BUFFERED] LOG statement. Did I catch you? Read on... Secondly, because there are at least two databases that implemented this better than us (and I find it very little ambitious from Microsoft to implement just what I'd call "basic" - if you're doing something new, you may as well aim for the best available). So, let's start by the SQL statement SET [BUFFERED] LOG.
I could track this down to at least version 7.3 of Informix Dynamic Server's (1998) documentation as well as the Online engine. And this matches more or less the functionality that SQL Server is implementing now (16 years later, not bad, right?). It means that even in an unbuffered database, you can ask the server to work with your session as if it was setup for BUFFERED logging. In other words, COMMITs issued by sessions that execute SET BUFFERED LOG won't cause the flush of the logical log buffer to disk. They will behave as if you had created the database with BUFFERED LOG. Consequently you're possibly contributing to the database performance, while you open the window to "data loss" only in your session.
Alternatively you can execute the SET LOG statement and ask the server to flush the logical log buffer on every COMMIT you make. You'll make sure that your commits are persisted to disk even if you're working on a BUFFERED database.
We can see the effect of this statement quite easily. The test case I created is fairly simple:
  1. Create a very simple table with an ID (INTEGER) and some other column - VAL (CHAR(1)) - with 1M rows in an UNBUFFERED LOG database
  2. Create a procedure that accepts the number of records to update, the commit interval and the new value
  3. Reset the engine counters (onstat -z)
  4. Set either BUFFERED or UNBUFFERED LOG level for the session
  5. Execute the procedure with some values
  6. Check the statistics with onstat -l
  7. Repeat from 3 using a different logging mode and compare the times and specially the counter values
So let's do it. The table and procedure SQL is this:
castelo@primary:informix-> cat test_buf.sql 
DROP PROCEDURE IF EXISTS test_proc;
DROP TABLE IF EXISTS test_data;
SELECT LEVEL id,"A" val FROM sysmaster:sysdual CONNECT BY LEVEL <= 1000000 INTO RAW test_data IN dbs1 EXTENT SIZE 5000 NEXT SIZE 5000;
ALTER TABLE test_data TYPE(standard);

CREATE PROCEDURE test_proc(total_rec INTEGER, commit_interval INTEGER, new_value CHAR) RETURNING INTEGER;

DEFINE total_counter, commit_counter, v_id, cycle INTEGER;

LET total_counter=0;
LET commit_counter=0;
LET cycle = 0;

BEGIN WORK;
FOREACH c1 WITH HOLD FOR
SELECT
        id
INTO v_id
FROM
        test_data

        UPDATE test_data SET val = new_value WHERE CURRENT OF c1;
        LET total_counter = total_counter + 1;
        LET commit_counter = commit_counter + 1;
        IF commit_counter = commit_interval
        THEN
                LET cycle = cycle + 1;
                COMMIT WORK;
                LET commit_counter = 0;
                BEGIN WORK;
        END IF;
        IF total_counter = total_rec
        THEN
                COMMIT WORK;
                RETURN cycle;
        END IF
END FOREACH;

END PROCEDURE;
Now, let's try it with a COMMIT interval of 100 records and UNBUFFERED LOG. The code and output is this:
castelo@primary:informix-> dbaccess -e stores run_unbuf.sql 

Database selected.

SET LOG;
Log set.


EXECUTE FUNCTION sysadmin:task('onstat', '-z');


(expression)  
              IBM Informix Dynamic Server Version 12.10.FC2 -- On-Line -- Up 09
              :01:52 -- 287720 Kbytes
              
               

1 row(s) retrieved.


SELECT CURRENT YEAR TO FRACTION FROM systables WHERE tabid = 1;

(expression)            

2014-02-17 18:57:09.622

1 row(s) retrieved.


EXECUTE PROCEDURE test_proc(500000,100,'U');

(expression) 

        5000

1 row(s) retrieved.


SELECT CURRENT YEAR TO FRACTION FROM systables WHERE tabid = 1;

(expression)            

2014-02-17 18:57:20.242

1 row(s) retrieved.



Database closed. 

It took around 11-12s but the real important part is this:
castelo@primary:informix-> onstat -l

IBM Informix Dynamic Server Version 12.10.FC2 -- On-Line -- Up 09:02:15 -- 287720 Kbytes

Physical Logging
Buffer bufused  bufsize  numpages   numwrits   pages/io
  P-2  15       64       14         0          0.00
      phybegin         physize    phypos     phyused    %used   
      2:53             62500      50947      44         0.07    

Logical Logging
Buffer bufused  bufsize  numrecs    numpages   numwrits   recs/pages pages/io
  L-2  0        64       510094     20018      5015       25.5       4.0     
        Subsystem    numrecs    Log Space used
        OLDRSAM      510094     38569892

Note that we've done 5015 write operations to disk. On each of them, on average we were writing four pages of logical log buffer. Each page contains around 25 records, so as we've asked for a COMMIT interval each 100 rows, everything matches what we'd expect.
Let's try with BUFFERED LOG:
castelo@primary:informix-> dbaccess -e stores run_buf.sql 

Database selected.

SET BUFFERED LOG;
Log set.


EXECUTE FUNCTION sysadmin:task('onstat', '-z');


(expression)  
              IBM Informix Dynamic Server Version 12.10.FC2 -- On-Line -- Up 09
              :07:52 -- 287720 Kbytes
              
               

1 row(s) retrieved.


SELECT CURRENT YEAR TO FRACTION FROM systables WHERE tabid = 1;

(expression)            

2014-02-17 19:03:08.698

1 row(s) retrieved.


EXECUTE PROCEDURE test_proc(500000,100,'B');

(expression) 

        5000

1 row(s) retrieved.


SELECT CURRENT YEAR TO FRACTION FROM systables WHERE tabid = 1;

(expression)            

2014-02-17 19:03:17.004

1 row(s) retrieved.



Database closed.
It took 8-9s, so it's a bit faster, but this is a VM, with no more activity... But the more interesting part is the logical log statistics we get from onstat -l:

castelo@primary:informix-> onstat -l

IBM Informix Dynamic Server Version 12.10.FC2 -- On-Line -- Up 09:10:44 -- 287720 Kbytes

Physical Logging
Buffer bufused  bufsize  numpages   numwrits   pages/io
  P-1  18       64       17         0          0.00
      phybegin         physize    phypos     phyused    %used   
      2:53             62500      50974      29         0.05    

Logical Logging
Buffer bufused  bufsize  numrecs    numpages   numwrits   recs/pages pages/io
  L-2  0        64       510095     19119      313        26.7       61.1    
        Subsystem    numrecs    Log Space used
        OLDRSAM      510095     38570264


Let's compare both outputs:
  • The number of records and log space used it roughly the same
  • The number of records per page is roughly the same
  • The number of writes (313) is much less than for UNBUFFERED mode (5015)
  • The number of pages on each write (average) if much higher now (61.1) as opposed to 4 in the previous test (I had a LOGBUFF size of 128KB)

What we're missing

Now, let's look at the other more interesting aspect of this.... I mentioned earlier that at least two databases do this in a smarter way than Informix. I'm thinking about DB2 and Oracle. How can this be done in a smarter way? Well, as you notice, the BUFFERED logging is a trade-off. You exchange security for performance (you give away the first and gain on the second). What if there was a better solution? What if you could gain on I/O performance, by reducing the number of operations while not giving away the durability of your data? It may seem impossible, but it's actually very easy and has been done. Let's assume what we have right now in most customers:
  • Lots of sessions and most of them do a commit from time to time
  • Many sessions making commits from time to time, usually means a very frequent commit rate
  • Very frequent commit rates means that we'll do a lot of logical log flushes per second. This is usually noticeable from the average pages per logical log flush. On busy systems with UNBUFFERED LOG this tends to be 1
The way other RDBMs can be configured is to don't flush on every commit but:
  1. Flush when the buffer is full (this always happen)
  2. Flush the logical log buffer if an amount of time has elapsed since the last flush, or flush only after a specific number of COMMITS have been issued
  3. Only send the ok to the application after you effectively flush the buffer that contains the COMMIT
This may seem a bit strange, because you're effectively "holding back" the applications. But keep in mind that this delay can be very small and is optional. The difference between this and the BUFFERED LOG is that the application will probably get only a slight delay, but more importantly, it won't receive an OK of an "uncommitted" COMMIT. When it gets the "ok", the data is securely flushed to the logical logs. Assuming this can be configure at the session level, we can get the best of both worlds (as there  is no gain without loss, the loss here is the probably slight delay, which for interactive applications at least would be unnoticeable)

I've seen situations where the I/O rate on the logical logs can be a bottleneck. As such I've created an RFE (Request For Enhancement) 45166 . If you like the idea and you've seen this happen on your system, vote for it


Versão Portuguesa:

A parte engraçada...

Trabalhar com Informix tem sido bastante engraçado, mas por vezes é por razões estranhas. Uma delas é a consequência de não ser considerada uma base de dados mainstream. De tempos a tempos vejo referências a "novas" funcionalidades nas bases de dados mais populares que me fazem sorrir. Certamente que o contrário também acontece, mas os ecos dessas "novas" funcionalidades no Informix são sempre menores que nos outros,  e seria algo normal numa base de dados que muitos bloggers e analistas não consideram Tier-1. Portanto quando tal acontece, ganho o dia...
Desta feita, ao navegar pela Internet, reparei em vários artigos referindo-se a (minha tradução) "funcionalidade nova e fascinante" do SQL Server 2014 CTP2 (ante-visão) chamada Delayed Transaction Durability. Bom... Depois de ler alguns destes artigos, incluindo o "oficial" fiquei um pouco surpreendido que isto seja apenas aquilo a que chamamos buffered logging! Sim... A possibilidade de atrasar o flush do buffer do logical log até que o mesmo buffer se encontre cheio, em vez de o fazer a cada COMMIT. E sim, tal como nós, isto significa que a aplicação assume que algo foi efetivamente "COMMITed", ao passo que se houver uma queda inesperada da base de dados na verdade não foi (o processo de fast recovery irá fazer rollback da transação).
Portanto, como seria de esperar, muitos autores de blogs foram cautelosos e referiram que isto pode levar à perda de dados. Na verdade a integridade da base de dados é mantida, mas como a aplicação recebe o "ok" antes de os dados estarem efetivamente escritos em disco, uma queda num intervalo específico, significaria que a transação estaria incompleta , levando portanto a um rollback durante o processo de recovery.
Então para quê usar isto? Rapidez... Mas na realidade a maioria dos clientes não quer arriscar, e habitualmente escolhem unbuffered logging.

A parte que temos

Mas porque estou a escrever isto? Apenas para brincar com a concorrência, realçando o facto de estarem a anunciar uma funcionalidade que todas a bases de dados (Informix, DB2, Oracle, MySQL, Postgres...) já têm? Não... não é por isso. Apesar de ser divertido verificar este tipo de situações com frequência (aconteceu recentemente com as suas funcionalidades de alta disponibilidade...).
O ponto é que este assunto tem outros aspetos interessantes para além do óbvio. Primeiro, apostaria que a maioria dos nossos clientes conhecem a opção [BUFFERED] LOG da instrução CREATE DATABASE. mas possivelmente desconhecem a instrução SET [BUFFERED] LOG. Apanhei-o? Continue a ler... Em segundo, existem pelo menos duas bases de dados que implementaram isto de forma mais "inteligente" que o Informix (e parece-me pouco ambicioso da parte da Microsoft fazer a implementação "básica" - se vamos criar algo de novo, porque não apontar para o melhor possível?). Veremos como isso pode ser feito e quais as diferenças. Comecemos então pela instrução SET [BUFFERED] LOG.
Consegui encontrar referências a esta instrução pelo menos tão antigas quanto a versão 7.3 do Informix Dynamic Server (1998), e também na documentação do motor Online. E isto mapeia mais ou menos diretamente com a funcionalidade que o SQL Server está a receber agora (16 anos depois não é mau, certo?). Significa que mesmo numa base de dados criada com unbuffered logging, podemos pedir ao servidor que trabalhe na nossa sessão como se estivesse em BUFFERED LOG. Por outras palavras, o COMMIT efetuado por sessões que executem o SET BUFFERED LOG, não força o flush do buffer do logical log. As sessões comportam-se como se tivéssemos criado a base de dados com BUFFERED LOG. Assim estaremos a contribuir para o aumento da performance da base de dados, ao mesmo tempo que limitamos a possibilidade de "perda de dados" apenas à(s) sessão que executou esta instrução.
Noutro cenário podemos executar a instrução SET LOG e pedir ao servidor que faça o flush do logical log buffer em cada COMMIT que façamos. Garantiremos que todos os nossos COMMITs são escritos em disco, antes de recebermos o "ok", mesmo que a base de dados esteja em modo BUFFERED.
Podemos ver o efeito desta instrução de forma bastante fácil. O caso de teste que criei é bastante simples:
  1. Criar uma tabela muito simples com um ID (INTEGER) e uma outra coluna - VAL (CHAR(1)) - com 1M de registos numa base de dados criada com UNBUFFERED LOG
  2. Criar um procedimento que aceita o número de registos a alterar, o intervalo de COMMIT e um novo valor para a coluna VAL
  3. Fazer o reset dos contadores do motor (com onstat -z)
  4. Estabelecer o modo BUFFERED ou UNBUFFERED LOG na nossa sessão
  5. Executar o procedimento com certos valores
  6. Verificar as estatísticas com onstat -l
  7. Repetir a partir do ponto 3 usando um modo de LOG diferente e comparar os tempos e mais importante os valores dos contadores
Vamos lá então fazê-lo. A tabela e o procedimento são os seguintes:
castelo@primary:informix-> cat test_buf.sql 
DROP PROCEDURE IF EXISTS test_proc;
DROP TABLE IF EXISTS test_data;
SELECT LEVEL id,"A" val FROM sysmaster:sysdual CONNECT BY LEVEL <= 1000000 INTO RAW test_data IN dbs1 EXTENT SIZE 5000 NEXT SIZE 5000;
ALTER TABLE test_data TYPE(standard);

CREATE PROCEDURE test_proc(total_rec INTEGER, commit_interval INTEGER, new_value CHAR) RETURNING INTEGER;

DEFINE total_counter, commit_counter, v_id, cycle INTEGER;

LET total_counter=0;
LET commit_counter=0;
LET cycle = 0;

BEGIN WORK;
FOREACH c1 WITH HOLD FOR
SELECT
        id
INTO v_id
FROM
        test_data

        UPDATE test_data SET val = new_value WHERE CURRENT OF c1;
        LET total_counter = total_counter + 1;
        LET commit_counter = commit_counter + 1;
        IF commit_counter = commit_interval
        THEN
                LET cycle = cycle + 1;
                COMMIT WORK;
                LET commit_counter = 0;
                BEGIN WORK;
        END IF;
        IF total_counter = total_rec
        THEN
                COMMIT WORK;
                RETURN cycle;
        END IF
END FOREACH;

END PROCEDURE;
Vamos tentar com um intervalo de de COMMIT e UNBUFFERED LOG. O código e o resultado é o seguinte:
castelo@primary:informix-> dbaccess -e stores run_unbuf.sql 

Database selected.

SET LOG;
Log set.


EXECUTE FUNCTION sysadmin:task('onstat', '-z');


(expression)  
              IBM Informix Dynamic Server Version 12.10.FC2 -- On-Line -- Up 09
              :01:52 -- 287720 Kbytes
              
               

1 row(s) retrieved.


SELECT CURRENT YEAR TO FRACTION FROM systables WHERE tabid = 1;

(expression)            

2014-02-17 18:57:09.622

1 row(s) retrieved.


EXECUTE PROCEDURE test_proc(500000,100,'U');

(expression) 

        5000

1 row(s) retrieved.


SELECT CURRENT YEAR TO FRACTION FROM systables WHERE tabid = 1;

(expression)            

2014-02-17 18:57:20.242

1 row(s) retrieved.



Database closed. 
Demorou à volta de 11-12s, mas a parte mais importante é esta:
castelo@primary:informix-> onstat -l

IBM Informix Dynamic Server Version 12.10.FC2 -- On-Line -- Up 09:02:15 -- 287720 Kbytes

Physical Logging
Buffer bufused  bufsize  numpages   numwrits   pages/io
  P-2  15       64       14         0          0.00
      phybegin         physize    phypos     phyused    %used   
      2:53             62500      50947      44         0.07    

Logical Logging
Buffer bufused  bufsize  numrecs    numpages   numwrits   recs/pages pages/io
  L-2  0        64       510094     20018      5015       25.5       4.0     
        Subsystem    numrecs    Log Space used
        OLDRSAM      510094     38569892

Repare que fizemos 5015 operações de escrita em disco. Em cada uma delas, em média, escrevemos 4 páginas do logical log buffer. Cada página contém em média 25 registos (de log), portanto como pedimos COMMITs de 100 em 100 registos os valores batem certo com o que seria expectável.
Vamos tentar com BUFFERED LOG:
castelo@primary:informix-> dbaccess -e stores run_buf.sql 

Database selected.

SET BUFFERED LOG;
Log set.


EXECUTE FUNCTION sysadmin:task('onstat', '-z');


(expression)  
              IBM Informix Dynamic Server Version 12.10.FC2 -- On-Line -- Up 09
              :07:52 -- 287720 Kbytes
              
               

1 row(s) retrieved.


SELECT CURRENT YEAR TO FRACTION FROM systables WHERE tabid = 1;

(expression)            

2014-02-17 19:03:08.698

1 row(s) retrieved.


EXECUTE PROCEDURE test_proc(500000,100,'B');

(expression) 

        5000

1 row(s) retrieved.


SELECT CURRENT YEAR TO FRACTION FROM systables WHERE tabid = 1;

(expression)            

2014-02-17 19:03:17.004

1 row(s) retrieved.



Database closed.
Demorou 8-9s, por isso foi um pouco mais rápido, mas isto é uma máquina virtual sem mais actividade... Mas a parte mais interessante são as estatísticas do logical log que obtemos com o onstat -l:

castelo@primary:informix-> onstat -l

IBM Informix Dynamic Server Version 12.10.FC2 -- On-Line -- Up 09:10:44 -- 287720 Kbytes

Physical Logging
Buffer bufused  bufsize  numpages   numwrits   pages/io
  P-1  18       64       17         0          0.00
      phybegin         physize    phypos     phyused    %used   
      2:53             62500      50974      29         0.05    

Logical Logging
Buffer bufused  bufsize  numrecs    numpages   numwrits   recs/pages pages/io
  L-2  0        64       510095     19119      313        26.7       61.1    
        Subsystem    numrecs    Log Space used
        OLDRSAM      510095     38570264

Vamos comparar ambos os outputs:
  • O número de registos e o espaço em log é praticamente o mesmo
  • O número de registos por página é praticamente o mesmo
  • O número de escritas (313) é muito menos que o efetuado em modo UNBUFFERED  (5015)
  • O número de páginas escritas em cada operação (média) é muito maior (61.1) do que o teste anterior que deu 4 páginas por escrita (tinha o LOGBUFF definido como 128KB)

O que nos falta

Bom, vamos agora ver outro aspecto importante deste assunto... Como referi, existem pelo menos duas bases de dados que fazem isto de forma mais eficiente e interessante que o Informix. Estou a pensar no DB2 e no Oracle. Como é que isto pode ser feito de forma mais inteligente? Bom, como terá reparado, o BUFFERED logging é uma troca. Trocamos segurança por rapidez (damos a primeira e recebemos a segunda). Mas e se houver uma melhor solução? E se conseguissemos ganhar rapidez (fazendo menos I/O) e ao mesmo tempo não abdicar da segurança que a escrita prévia nos dá? Pode parecer impossível, mas na verdade pode ser muito fácil e já foi feito. Vamos assumir o cenário que encontro em muitos clientes atualmente:
  • Muitas sessões e a maioria delas fazem um COMMIT de vez em quando
  • Muitas sessões a fazerem COMMIT "de vez em quando", traduz-se normalmente num ritmo bastante alto de COMMITs
  • Um ritmo de COMMITs muito alto implica que façamos muitos flushes do logical log buffer por segundo. Isto é normalmente visível pelo número médio de páginas escritas em cada operação de I/O (flush), que em sistemas configurados em UNBUFFERED e com bastante actividade tende a ser 1
A forma como outras RDBMS podem ser configuradas é não fazer flush em cada COMMIT, mas:
  1. Fazer o flush quando o bufer enche (isto acontece sempre)
  2. Fazer o flush do logical log biffer se passou um determinado tempo desde o último flush, ou fazer o flush após um certo número de COMMITS terem sido executados
  3. Apenas enviar o "ok" às aplicacções quando fazemos efectivamente o flush do biuffer que contém o COMMIT por elas executado
Isto pode parecer um pouco estranho, porque estamos efetivamente a "atrasar" as aplicações. Mas considere que este atraso é muito pequeno e opcional. A diferença entre isto e o BUFFERED LOG é que a aplicação apenas sofre um ligeiro atraso, mas mais importante não recebe "ok" de um COMMIT que efectuou mas que ainda não foi garantido em disco. Quando recebe o "ok" é certo que os registos do log já foram escritos e persistidos em disco. Tendo em conta que isto pode ser configurado ao nível da sessão, podemos obter o melhor dos dois mundos (embora como não haja ganhos sem perdas, a perda aqui será o pequeno atraso, mas este para aplicações interativas é provavelmente negligenciável)

Já vi situações onde o ritmo de operações de I/O nos logical logs pode ser um "fúnil". Dái ter registado um RFE (Request For Enhancement) 45166 . Se gosta da ideia e já viu o mesmo acontecer no seu sistema vote neste pedido.

Saturday, April 07, 2012

Database wars are over? / As guerras das bases de dados terminaram?

This article is written in English and Portuguese
Este artigo está escrito em Inglês e Português


English Version

"Database wars are over...", "...and relational won", "...and Oracle won". If you search for these terms on your favorite search engine you'll get enough answers to keep you busy for a long time.
At a certain point many believed this was true. And I'm sure many others still do. But if you've been paying attention lately you'll notice this can still be under discussion.
Currently there is a lot of movement in the database arena... Let's see:

  • New versions are popping out: DB2 v10 for LUW, SQL Server 2012 are the most recent examples. Informix is in the early stages for vNext also. Meanwhile we have Informix Warehouse Accelerator that although not a new database per si, it's new technology
  • Datawarehouse appliances and dedicated servers are alive and kicking: Netezza (IBM), GreenPlum (EMC), Parallel Data Warehouse (HP/MS Sql Server), Exadata (Oracle)
  • NoSQL is "the" buzzword. Hadoop and everything about it seems like the next big thing
  • SAP makes bold statements about wanting to be a major database player. More details this Tuesday (April 10)
  • Oracle's CEO, Larry Ellison, says they (SAP) "must be on drugs"

So, we are definitively seeing news on the technology front. And although it's true that these days databases are a commodity, the fact is that no system is implemented without some sort of database. And it's a key part of any system, because it makes the bridge between bits and bytes and the least intelligible information (which of course needs BI tools for enrichment). And also because if it's critical for performance and availability of the information systems.
Given all this I think great times are ahead of us, assuming you like challenges and new technology to play with.
Focusing on Informix, I think we are seeing the introduction of some of this new technology. Informix Warehouse accelerator walked silently in 11.70.FC2, but new functionality is being delivered on each and every fixpack. FC3 saw the introduction of automatic data mart definition and several new locales. FC4 included the possibility of cluster installation, which brings enormous scalability and also data loading concurrently to queries and some other minor improvements. According to this post from Fred Ho FC5 will bring two other great features: possibility to load the marts from MACH-11 secondary clusters and the possibility to load only partitions that have changed (as opposed to the whole tables)
This clearly shows we have a roadmap, and yes... there's a lot of work to do. Specially as it's being adopted by customers who will easily find more uses than what they anticipated for.


Versão Portuguesa


"Database wars are over...", "...and relational won", "...and Oracle won". Se procurar estes termos (que por opção não traduzi) no seu motor de busca favorito vai obter respostas suficientes para o manterem ocupado durante bastante tempo.
Em dada altura muitos acreditaram que isto era verdade. E tenho a certeza que muitos ainda acreditam. Mas se tem prestado atenção ultimamente já terá notado que isto ainda está sob discussão.

Atualmente existem muitas movimentações no mercado de bases de dados. Vejamos:


  • Há novas versões a aparecer: DB2 v10 para LUW e SQL Server 2012 são os exemplos mais recentes. O Informix está a preparar a próxima versão também. Entretanto temo o Informix Warehouse Accelerator que não sendo em si uma nova base de dados incluí tecnologia nova
  • As appliances de Datawarehouse e servidores dedicados também estão a criar muita agitação: Netezza (IBM), GreenPlum (EMC), Parallel Data Warehouse (HP/MS Sql Server), Exadata (Oracle)
  • NoSQL é "o" novo chavão. Hadoop e tudo à sua volta parece ser o próximo grande boom
  • A SAP faz afirmações ousadas sobre desejar tornar-se num dos maiores vendedores de bases de dados. Mais detalhes serão divulgados esta terça-feira (10 de Abril)
  • O CEO da Oracle, Larry Ellison, afirma que eles (SAP) "must be on drugs" (devem estar sob o efeito de drogas)

Portanto estamos mesmo a assistir a novidades na vertente tecnológica. E apesar de ser aceite que hoje em dia a base de dados é uma comodidade, a verdade é que nenhum sistema é implementado sem algum tipo de base de dados. E estas são uma peça chave em qualquer sistema porque fazem a ponte entre os bits e bytes e o mínimo a que podemos chamar informação (que naturalmente necessita de ferramentas de BI para enriquecimento da mesma). E as BDs são também peças chave na performance e disponibilidade dos sistemas.
Tento tudo isto em conta, julgo que temos tempos interessantes pela frente, assumindo que gosta de desafios e nova tecnologia para "brincar".

Pondo o foco no Informix, penso que estamos a assistir à introdução de alguma desta nova tecnologia. O Informix Warehouse Accelerator entrou silenciosamente na versão 11.70.FC2, mas novas funcionalidades estão a ser incluídas em todos os fixpacks. A FC3 viu a introdução da definição automática de data marts e vários novos locales. A FC4 incluí a possibilidade de utilização em cluster, que oferece enorme escalabilidade, e também carregamento de dados em simultâneo com a execução de queries e mais alguns melhoramentos. Segundo este artigo do Fred Ho a FC5 vai trazer duas novas funcionalidades: A possibilidade de carregar os data marts a partir de nós secundários de um cluster MACH-11 e a possibilidade de carregar apenas partições que tenham sido alteradas (em vez de carregar a totalidade das tabelas).
Isto mostra claramente que existe um roadmap e sim... existe muito trabalho para fazer. Especialmente à medida que o produto vai sendo adotado pelos clientes que irão facilmente encontrar mais usos do que tinham antecipado.

Friday, March 30, 2012

Why or why not? / Porquê ou porque não?

This article is written in English and Portuguese
Este artigo está escrito em Inglês e Português

English Version:
The Internet is a wonderful thing... You get to find all sorts of things and it's easy to spread your word, specially since the creation of the so called social networks... On a recent search on twitter I found a very interesting question from "SQLMountain / Michael Sexton". The question was:

"Why o why do vendors still use Informix?!? Looking at u #cisco"

After digging a bit I've learned that the author is a database architect with 12 years of experience. And apparently he works mainly with SQL Server. So I think that the apparent surprise is perfectly understandable in that context... But on the other hand, again by searching the net, I could find some answers to that question. In particular:

So, I'd say that the question is not properly formulated. It's not why "still". The chronology above shows an increasing, and not decreasing trend.
So I then tried to reverse the question: Why would you not use Informix? And here are some possible reasons (I'm obviously playing devil's advocate here) together with some thoughts:

  • It's not stable
    But it is, and customers keep telling me that, and showing me their uptimes to prove it
  • It's too complex
    But it isn't... Many Informix shops don't have a classic DBA (full time job of a specialized person). Usually the person taking care of Informix is a "many hats" kind of person
  • It lacks functionality
    I'm always wanting more... But the ones I wish for are usually not widely used in competitor products. And it has first class features like the high availability, the replication (ER), the extensibility
  • It's slow
    It isn't... I know that from personal experience, but that's what customers tell me also. It works well with less hardware than other competitors
  • The support is not good
    Err... though point, because I work for IBM. But because I work for IBM and because I have the privilege to work in customer environments that include many other (non-IBM) products, I know that Informix tech support is one of the best (if not the best) technical supports I've worked with or I've heard of. Yes, I may not be a trustworthy source of information from the readers point of view... But just recently I've heard the same comment from two people that don't even know each other, both talking about one of Informix's major competitors: "the first five interactions with ? technical support look like program ELIZA interactions". At the time I did not know what program ELIZA was. The incredible part of this story is that those two persons told be exactly the same within a couple of weeks.
  • It's expensive
    Well... this one is hard to discuss. The price lists are not really the price customers pay. But Informix has a wide variety of editions that range from free to everything (except compression) included. Some competitors charge extra for features even in the most expensive edition. And have lower limits (memory, processor, data size) on the free versions (which sometimes are not up to date with the current product versions, while IBM keeps the free versions on the same fixpack levels as the payed versions)
  • It lacks interoperability with other products
    Not really although this is a widespread idea. It has the usual interfaces (ODBC, JDBC, .NET), supports several languages (Java, C, PHP, Ruby, C#) and interacts with a ton of products (not only from IBM). To name a few examples:
    • Non IBM:
      • Oracle NetVault (backup)
      • Oracle ODI (Data Integrator)
      • Oracle WebLogic (J2EE application server)
      • Oracle BI
      • Informatica PowerCenter
      • Pentaho
      • Tomcat
      • Hibernate
      • JBoss
      • Alfresco
      • SugarCRM
      • Joomla
      • Drupal
      • Veritas Netbackup
      • HP OpenView (last time I was in touch with it)
      • HP DataProtector (backup)
    • IBM:
      • WebSphere Application Server
      • WebSphere MQ
      • WebSphere MQ Broker
      • DataStage (Information Server)
      • Optim
      • Guardium
      • Tivoli Storage Manager
      • Tivoli Monitoring (through Universal Agent)
      • Lotus Mashup Center
      • Cognos
  • It's not supported by third party application providers
    This is possibly the only real problema. But just acknowledging it may be a bit misleading and can hide one very obvious thought. We've been seeing a lot of concentration of applications under the same companies (Oracle bought PeopleSoft, Siebel, JDEdwards and had already an application division, Microsoft has Navision, SAP is entering the Database scene)... So, what does this tell you as a third party application developer? That most database providers will compete with you. So why not choose one database which supplier is not competing in the application market?
And then we could go through Informix's unique features:
  • Extensibility
    Every database has it, but things like TimeSeries, MQ datablade, Basic Text Search, GeoSpatial etc. are built around it. And I've experienced quite a few times how we can overcome the lack of some specific function. Easily and reliably.
  • Performance and efficiency
    These days we're seeing an hardware escalation. In part this happens because hardware is becoming cheaper and end user application code is getting more functional, but less efficient. This leads to the old "throw iron to the problem" paradigm. But I keep seeing heavy loads on top of Informix instances running on modest hardware. This represents cost savings
  • Replication and high availability features
    No other database on the market has so advanced features with such a low cost of implementation and maintenance. The competitors which include comparable functionality typically require extra hardware (like Infiniband) and several software products to make it work. We need just the database and the connection manager (included). A lightweight solution which again translates into cost savings and less complexity
  • Ease of upgrades
    The simplicity and reliability of the Informix upgrades have always been a fantastic feature. You can easily upgrade from very old versions "in place" (without moving data). The only concern you have currently is the time it may take to UPDATE STATISTCS. The traditional concern of what you'd have to do if the conversion failed was mostly mitigated by the CONVERSION GUARD feature. And of course, you can now migrate a cluster with no downtime (although the workload to do it may be complex for big systems)
  • Flexible Grid
    The ability to integrate different engine versions and hardware platforms under the same administration "unit" is a terrific feature.
  • The Warehouse Accelerator
    Effectively new technology (columnar in memory database) seamlessly integrated into the traditional disk based row store. Completely transparent to the applications
So, in short, I believe the correct question would be "why not?" instead of "why?". Feel free to comment and tell me I'm wrong (as long as you explain why).



Versão Portuguesa:

A Internet é uma coisa fantástica... É fácil encontrar todo o tipo de coisas e espalhar a nossa voz, especialmente após a criação das chamadas redes sociais... Numa pesquisa no Twitter há umas semanas encontrei uma questão interessante de alguém que usa o nome "SQLMountain (Michael Sexton". A questão era:

"Why o why do vendors still use Informix?!? Looking at u #cisco"

Ou se me permitem a tradução:

"Porquê, mas porque é que os fornecedores ainda usam Informix?!? Estou a olhar para vocês #cisco"

Após ter vasculhado um pouco percebi que o autor é um arquiteto de bases de dados, com 12 anos de experiência. E que aparentemente trabalha maioritariamente com SQL Server. Neste contexto penso que a aparente surpresa é perfeitamente compreensível... Mas por outro lado, e novamente procurando na net, podemos encontrar respostas a essa questão. Especificamente:

Assim, parece-me que a questão não está corretamente formulada. Não será porquê "ainda". A cronologia acima demonstra uma tendência crescente e não decrescente
Por isso tentei reverter a questão. Porque não deveria-mos usar Informix? E posso avançar algumas possíveis razões (obviamente vou fazer de advogado do diabo) juntamente com algumas ideias:

  • Não é estável
    Mas é... É isso que oiço dos clientes, e mostram-me os uptimes para o provar
  • É demasiado complexo
    Mas não é... A maioria das empresas que usam Informix não têm um DBA no sentido clássico (trabalho a tempo inteiro de uma pessoa especializada). Habitualmente a pessoa encarregue do Informix é um profissional multi-facetado com várias ocupações
  • Falta-lhe funcionalidades.
    Estou sempre a desejar mais... Mas as que mais falta sinto normalmente nem existem ou não são geralmente usadas nos produtos concorrentes. E tem funcionalidades de excelência como as características de alta disponibilidade, a replicação e a extensibilidade
  • É lento
    Mas não é...Tenho aprendido isso com a minha própria experiência, mas é a ideia que me chega dos clientes. E regra geral consegue resolver o mesmo tipo de carga com menos hardware que os concorrentes
  • O suporte é deficiente
    Hmmm... ponto difícil, porque trabalho para a IBM. Mas porque eu trabalho para a IBM e porque tenho o privilégio de passar muito tempo em clientes que usam muitos outros produtos (não IBM), posso atestar que o suporte Informix é um dos melhores (senão o melhor) dos que tive oportunidade de contactar ou de ouvir falar. Sim, dificilmente serei considerado uma fonte fidedigna deste tipo de informação... Mas ainda recentemente ouvi o mesmo comentário vindo de duas pessoas que nem se conhecem, em relação ao suporte de um dos maiores concorrentes do Informix: "as primeiras cinco interacções com o suporte técnico de ? pareciam interações com o programa ELIZA". Na altura nem sabia o que era o programa ELIZA. O que me espantou mesmo nesta história foi as duas pessoas me terem dito exatamente a mesma coisa num intervalo de poucas semanas. Não tenho ideia que isto aconteça com o suporte de Informix.
  • É caro
    Bom... Isto é difícil de discutir. Julgo que a maioria dos clientes não pagam o preço de lista. Mas o Informix tem um leque de edições que vão do completamente gratuito até ao que tem tudo (excepto a compressão) incluído. Muitos concorrentes cobram extras por determinadas funcionalidades mesmo na edição mais cara. E nas edições gratuitas têm mais restrições que o Informix (e por vezes não as mantêm atualizadas ao passo que a IBM lança os mesmos fixpacks em todas as edições)
  • Falta suporte a outros produtos ou não é suportado por outros produtos
    Nem tanto embora isto seja uma ideia instalada. Tem as habituais interfaces (ODBC, JDBC, .NET), suporta várias linguagens (Java, C, PHP, Ruby, C#, Perl) e interage com um grande número de produtos (não apenas IBM). Para nomear alguns:
    • Não IBM:
      • Oracle NetVault (backup)
      • Oracle ODI (Data Integrator)
      • Oracle WebLogic (servidor aplicacional J2EE)
      • Oracle BI
      • Informatica PowerCenter
      • Pentaho
      • Tomcat
      • Hibernate
      • JBoss
      • Alfresco
      • SugarCRM
      • Joomla
      • Drupal
      • Veritas Netbackup
      • HP OpenView (na última vez que tive contacto com ele)
      • HP DataProtector (backup)
    • IBM:
      • WebSphere Application Server
      • WebSphere MQ
      • WebSphere MQ Broker
      • DataStage (Information Server)
      • Optim
      • Guardium
      • Tivoli Storage Manager
      • Tivoli Monitoring (via Universal Agent)
      • Lotus Mashup Center
      • Cognos
  • Não é suportado por fornecedores aplicacionais
    Este será porventura o único problema real. Mas apenas reconhecer isso seria simplista e esconderia algo realmente importante. Nos últimos anos temos assistido a uma grande concentração de aplicações sob as mesmas empresas (a Oracle adquiriu a PeopleSoft, a Siebel, a JD Edwards e já tinha a sua própria divisão aplicacional, a Microsoft tem o Navision e a SAP está a entrar nas bases de dados)... O que é que isto lhe diz se for um produtor de uma aplicação? Que a maioria dos fornecedores de bases de dados irão competir consigo. Assim, porque não usar uma base de dados cujo fornecedor não está a competir no mercado de aplicações?

E depois podemos percorrer algumas das características únicas do Informix:
  • Extensibilidade
    Todas as bases de dados a têm, mas coisas como TimeSeries, o MQ datablade, o Basic Text Search (BTS), o Geo Espacial são construídos com base nessa extensibilidade. E já por diversas vezes atestei como usando a extensibilidade podemos resolver de forma simples alguns problemas e mesmo a falta de alguma função nativa
  • Performance e eficiência
    Actualmente estamos a assistir a uma "escalada" do hardware. Em parte isso acontece por causa do cada vez mais baixo custo do hardware ao mesmo tempo porque o código aplicacional corrido pelo utilizador final ganha funcionalidades e perde eficiência. Isto leva ao velho paradigma de "atirar ferro para o problema". No entanto continuo a ver utilizações intensas  em cima de instâncias Informix a correrem em hardware bastante modesto. Isto traduz-se em poupanças de custos
  • Replicação e funcionalidades de alta disponibilidade
    Nenhuma outra base de dados no mercado possuí funcionalidades tão avançadas com um custo de implementação e manutenção tão baixo. Os concorrentes que incluem funcionalidades comparáveis requerem hardware extra (como Infiniband) e vários produtos ou componentes de software para funcionarem. Nós necessitamos apenas da base de dados e do Connection Manager (incluído). Uma solução mais simples e leve que ao reduzir a complexidade baixa custos e requer menos conhecimentos para instalar, manter e operar.
  • Facilidade de upgrades
    A simplicidade e confiança dos upgrades de Informix sempre foram uma característica fantástica. Podemos fazer atualizações mesmo a versões bastante antigas "in place" (sem movimentação de dados). A única preocupação que temos atualmente prende-se com o tempo que demorará a atualizar as estatísticas. A preocupação tradicional sobre o que teríamos de fazer se uma conversão abortasse foi na sua maioria mitigada pela introdução da funcionalidade CONVERSION GUARD. E claro, agora podemos migrar um cluster sem paragem (embora o processo de o fazer se possa traduzir em operações complexas em sistemas grandes)
  • Flexible Grid
    A possibilidade de integrar motores de versões diferentes e a correr em hardware heterogéneo sob a mesma "unidade" de administração é um grande salto em frente.
  • O Warehouse Accelerator
    Tecnologia efetivamente nova (colunar e in--memory) integrada de forma simples no sistema tradicional de armazenamento em disco com formato ou organização de linha. Completamente transparente para as aplicações
Portanto, em resumo, acredito que a questão correta seria "porque não?" em vez de "porquê?". Sinta-se à vontade para comentar e dizer-me que estou enganado (desde que explique porquê)

Thursday, March 08, 2012

Too little, too late? / Muito pouco, muito tarde?

This article is written in English and Portuguese
Este artigo está escrito em Inglês e Português


English Version:

I recently got an advice on how to make better use of Twitter... And so I did... I increased the number of people or accounts I'm following and today I was flooded by messages about the launch of one of the database competitors. If you've been paying attention to the net you probably know which one I'm talking about... I've seen some references before and I decided to investigate a little further what were the new features causing all this buzz around it... I must grant credit to the company behind it, since it was not difficult to get information and find several articles and papers and people talking about it.

I think that in the IT field we tend to close ourselves around what we know better. I've seen it in Oracle DBAs, in people working with Informix (you should know it's much harder to find an Informix DBA than a DBA from any other database since we tend to have several hats and play several roles) and with people working in different environments (z/OS is a classical example). And apparently it also happens with people working with SQL Server. I'd say that only this can explain all this enthusiasm... Let me explain why, by picking two of the flagship features of it's new version (I'll be using the terms I've found on the Internet in blogs, articles and so on):
  • AlwaysOn
    Believe it or not this is a form of replication that allows databases to be put together in groups that use a primary server and one or more secondary servers. The replication can be synchronous, or asynchronous. The secondary servers can accept read only queries. It includes some sort of connection redirection and something I could not exactly understand that allows temporary statistics to be computed on the secondaries and stored in temporary spaces...
  • ColumnStore indexes
    This is interesting.... It combines several technologies like in-memory database, columnar storage and star model optimization. This allows incredible time savings, but has some drawbacks, like not being able to update a table with an index of this type (several workaround are mentioned, but all of them have serious implications). It's up to the optimizer to decide if it will use this kind of index or the traditional query plans.
I'm sure that if you're an Informix user, or someone paying attention to the Informix scene, you have a smile on your face by now... And I would not need to explain why. But for the people who are a bit more distracted, or as I mentioned above live on a closed world, let me explain why Informix people have a smile on their faces at this point in the article:

In 2007 (yes, five years ago), IBM introduced version 11.1, code named Chetah, and one of the features was something called MACH-11. This did not cause half the buzz that we're seeing today, but in very short words, it was the ability to configure a set of Informix instances (where we can have several databases) with a primary server, a "close" secondary server, called HDR (which can by synchronous), and several remote secondary servers (RSS) which receive the logs. The communication between these can be encrypted (there are known customer cases using the Internet to ship their logical logs to the other side of the world). Note that the single node HDR existed since version 7 (can't remember the year, because it was before I joined Informix). The HDR was always readable. The RSS are naturally also readable. In 2009 (if memory serves me well, yes, 3 years ago) IBM introduced version 11.5, called Panther where MACH-11 was extended: We can now configure the secondary servers to accept write instructions which are transparently sent to the primary server. A new piece of software was introduced, called the Connection Manager, that can redirect clients based on pre-defined criteria (or SLAs) which are mapped to the several kinds of servers (or to specific server names). Finally, the statistics gathered on the primary are automatically available on the secondary servers, so there is no need to re-calculate them on the secondary servers. All this works in shared nothing architecture which allows for big geographic dispersion and naturally allows for disaster recover... Oh... and it's terribly simple to setup and use, and it's included even in the free product versions (with some restrictions). And I could continue, writing that in 2010 IBM launched version 11.7 which included the concept of flexible grid, ideal for truly distributed systems that need to dhare data.

Last year, (Q1) IBM announced the addition of new technology to the Informix product line, which targeted BI environments with a star schema design that needed very fast response times for analytical queries. This has the name of Informix Warehouse Accelerator, and combines several technologies: in-memory database, columnar storage and full cluster capabilities (for horizontal scaling). It duplicates the data into the accelerator memory and the Informix optimizer redirects the queries that can be accelerated and that would benefit from that acceleration. You can keep using the base tables as usual, you don't have to change the application layer, and you can control through SQL if you want to use the most recent data (stored in the traditional row storage) (slower) or the possibly older data stored in the accelerator (faster). Note that this creates full star (fact tables and dimensions) data duplication for full power acceleration.

So, although as expectable there are a few technical differences that can make us prefer one or the other, the biggest difference between some of these features seems to be the year they were launched... And yes, the buzz generated around them... and that with Informix you have more platform choices. At times like this I tend to agree with people that complain about IBM (they used to complain about Informix) marketing... Maybe, just maybe, IBM should concentrate on marketing instead of product development... That seems to be what others do with apparently good results... But again, if you're an Informix user, I'm sure you prefer the opposite.



Versão Portuguesa:


Recentemente fui aconselhado sobre como tirar mais partido to Twitter... E assim fiz... Aumentei o número de pessoas ou contas que sigo, e hoje fui inundado de mensagens sobre o lançamento de um dos fornecedores de base de dados concorrentes. Se tem prestado atenção à Internet deve saber a qual me estou a referir... Já tinha visto algumas referências antes e decidi investigar um pouco mais quais eram as novas funcionalidades que causavam toda esta movimentação... Tenho de reconhecer e dar crédito à empresa por detrás do produto, pois não foi difícil obter informação e encontrar vários artigos, papers e pessoas a escrever sobre o assunto.


Tenho para mim que as pessoas na área das TIs tendem a fechar-se sobre aquilo que conhecem melhor. Tenho visto isto em DBAs Oracle, em pessoas que trabalham com Informix (deverá saber que é muito mais difícil encontrar um DBA Informix que um DBA de qualquer outra base de dados, dado que tendemos a usar vários chapéus e desempenhar várias funções) e também em pessoas que trabalham em diferentes ambientes (o mundo dos mainframes é um exemplo clássico). E aparentemente isto também acontece com pessoas que trabalham com SQL Server. Diria que essa é a única explicação para tamanho entusiasmo... Deixem-me explicar porquê, pegando em duas das funcionalidades mais badaladas por esses blogs e twits que se referem a este lançamento (vou usar os termos originais em Inglês, que encontrei na Internet):

  • AlwaysOn
    Acredite-se ou não, parece ser uma forma de replicação que permite colocar várias bases de dados em grupos que usam um servidor principal e um ou mais servidores secundários. A replicação pode ser síncrona ou assíncrona. Os servidores secundários podem aceitar queries só de leitura. Incluí algum tipo de redirecionamento de conexões e algo que não consegui compreender totalmente mas que permite que sejam calculadas estatísticas nos nós secundários que são guardadas em espaços temporários.
  • ColumnStore indexes
    Isto é interessante... Combina várias tecnologias, como base de dados em memória, armazenamento em colunas e optimização de modelos em estrela. Isto permite enormes poupanças de tempo, mas traz algumas desvantagens, como não permitir alterações (INSERTs, UPDATEs, DELETEs) em tabelas com este tipo de índices (são apresentadas várias formas de contornar a limitação, mas todas com sérias implicações). Cabe ao optimizador decidir se deve usar este tipo de índice ou usar os planos de execução tradicionais.
Tenho a certeza que se é um utilizador de Informix, ou se tem estado atento ao mundo Informix, deverá ter um sorriso na cara por esta altura... E não necessitaria de explicar porquê, podendo encerrar já aqui este artigo. Mas para as pessoas mais distraídas, ou como disse acima, para quem viva num mundo mais fechado, vou explicar porque é que os utilizadores de Informix estarão a sorrir neste momento.

  Em 2007 (sim, há cinco anos atrás), a IBM lançou a versão 11.1, com o nome de código Cheetah, e uma das suas funcionalidades foi o MACH-11. Isto não causou metade do alarido de hoje, mas em breves palavras, é a capacidade de configurar um conjunto de instâncias Informix (onde podemos ter várias bases de dados) com um servidor primário, um servidor secundário "próximo", chamado HDR (que pode ser síncrono) e vários servidores secundários remotos (RSS) que recebem os logs. A comunicação entre os servidores pode ser encriptada (há casos conhecidos de clientes que usam a Internet para enviar os logical logs para o outro lado do mundo). Note-se que o nó secundário único (HDR) existia desde a versão 7 (não sei o ano, pois foi antes de entrar na Informix). O HDR sempre disponibilizou acesso para leitura. Os RSS incluíram desde o início a capacidade de aceitar queries para leitura. Em 2009 (se a memória não me falha, sim, há três anos atrás) a IBM introduziu a versão 11.50, chamada Panther onde o MACH-11 foi melhorado. Podemos agora configurar os servidores secundários para aceitar instruções de escrita que são enviadas de forma transparente para o primário. Uma nova peça de software foi introduzida com o nome de Connection Manager, que permite redirecionar os clientes baseado em critérios pré-definidos (ou SLAs) que são mapeados nos vários tipos de servidores (ou em identificadores específicos de cada servidor). Finalmente as estatísticas calculadas no servidor primário estão automaticamente disponíveis nos servidores secundários, por isso não há necessidade de as re-calcular nos secundários. Tudo isto funcionam numa arquitetura shared nothing o que permite uma vasta dispersão geográfica e automaticamente disponibiliza disaster recovery. Ah... E é terrivelmente fácil de criar e usar, e vem incluído até nas versões gratuitas do produto (com algumas restrições). E poderia continuar, dizendo que em 2010 a IBM lançou a versão 11.7 que introduziu o conceito de flexibale grid, algo verdadeiramente pensado para ambientes distribuídos mas com necessidade de partilhar dados.



O ano passado (Q1) a IBM anunciou a adição de nova tecnologia á linha de produtos Informix, cujo alvo foi ambientes de BI com modelos em estrela que precisem de tempos de resposta muito rápidos em queries analíticas. Tem o nome de Informix Warehouse Accelerator e combina várias tecnologias: base de dados em memória, armazenamento de colunas, capacidade de trabalhar em cluster (para crescimento horizontal). Duplica os dados para a memória do acelerador e o optimizador do Informix redirecciona as queries que podem ser aceleradas (se daí vier proveito). Podemos continuar a fazer o uso normal das tabelas de base e não é necessário mexer na camada aplicacional, e podemos controlar através de SQL se queremos ver os dados mais recentes (guardados no formato de linha tradicional) (mais lento) ou a versão possivelmente mais antiga guardada no acelerador (muito mais rápido). Note-se que isto duplica completamente o modelo em estrela (tabela de factos e as dimensões) para atingir uma maior performance (toda a query é resolvida no acelerador).


Portanto, embora como seja expectável, existam algumas diferenças técnicas que nos façam gostar mais de uma abordagem ou da outra, a maior diferença entre algumas destas funcionalidades parece residir mais no ano em que apareceram... E sim, no ruído à volta... e no facto de em Informix podermos escolher a plataforma. Em alturas como esta sinto-me tentado a concordar com quem se queixa do marketing da IBM (já se queixavam da Informix). Talvez, quem sabe, a IBM se devesse concentrar mais no marketing do que no desenvolvimento dos produtos... Parece ser o que outros fazem e com aparentes bons resultado... Por outro lado, se é um utilizador Informix tenho a certeza que prefere o contrário.