<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-35024011</id><updated>2012-02-03T11:19:51.068Z</updated><category term='syntax error'/><category term='intance'/><category term='biztalk'/><category term='spanish'/><category term='2009'/><category term='partição'/><category term='aquisição'/><category term='11.170.FC2'/><category term='free'/><category term='community'/><category term='new'/><category term='conversion'/><category term='speakers'/><category term='11.50.UC3'/><category term='ds'/><category term='upgrade'/><category term='service'/><category term='2010 conference'/><category term='application development'/><category term='extent size'/><category term='11.50.xC4'/><category term='extensibilidade'/><category term='redbook'/><category term='Vercelletto'/><category term='lsof'/><category term='optimização'/><category term='informix pam'/><category term='lenexa'/><category term='in memory database'/><category term='study'/><category term='extents'/><category term='fixpack'/><category term='strace'/><category term='#panther'/><category term='pdq'/><category term='dbspace'/><category term='implicito'/><category term='cosmo'/><category term='oninit -i'/><category term='EC2'/><category term='distribuições'/><category term='economic'/><category term='brasil'/><category term='tabela'/><category term='IBM'/><category term='external tables'/><category term='informix tco'/><category term='IBM Portugal Informix warehouse evento Forum Lisboa'/><category term='visual explain'/><category term='agenda'/><category term='dbaccess'/><category term='udr'/><category term='fastest informix dba contest'/><category term='embebido'/><category term='procedure'/><category term='next informix version'/><category term='comunidade informix'/><category term='base dados'/><category term='suporte'/><category term='ibm tv'/><category term='storage clause'/><category term='advanced data tools'/><category term='grupo de utilizadores'/><category term='#informix'/><category term='201'/><category term='rownum'/><category term='iinovator-c'/><category term='136'/><category term='tatukgis'/><category term='roadshow'/><category term='dns'/><category term='DEHEMS'/><category term='11.70.xc3'/><category term='columnar database'/><category term='dbschema'/><category term='optimization'/><category term='marketing'/><category term='Edições Informix'/><category term='banco de dados grátis'/><category term='was'/><category term='no error message'/><category term='11.70.uc3'/><category term='11.50.UC2'/><category term='physical log'/><category term='error'/><category term='transacção'/><category term='comunidade'/><category term='informix new editions'/><category term='vendor rate tco informix'/><category term='conferência'/><category term='tcpdump'/><category term='packaging'/><category term='support'/><category term='IDS'/><category term='planet'/><category term='data capture'/><category term='out of support'/><category term='instancia'/><category term='funcao'/><category term='null concatenation'/><category term='francês'/><category term='informix locking'/><category term='solutions'/><category term='versões'/><category term='demo'/><category term='stored'/><category term='tasks'/><category term='itanium'/><category term='kansas city'/><category term='lisbon'/><category term='11.50.FC3'/><category term='drop'/><category term='survey'/><category term='plugin'/><category term='IFX_LARGE_PAGES'/><category term='espaco livre'/><category term='oledb'/><category term='optimizador'/><category term='select list'/><category term='logical logs'/><category term='Informix FUD IBM roadmap training iiug virtual appliance'/><category term='sql syntax'/><category term='virtual machine'/><category term='pdqpriority'/><category term='embebida'/><category term='if not exists'/><category term='embedable'/><category term='mi_integer'/><category term='roi'/><category term='scripts'/><category term='OAT'/><category term='erro'/><category term='driver'/><category term='transaction'/><category term='OLAP'/><category term='11.70.fc3'/><category term='chunks'/><category term='informix support'/><category term='header'/><category term='Eric'/><category term='peformance'/><category term='informix compression'/><category term='#mysql'/><category term='return on investment'/><category term='informix beta'/><category term='S3'/><category term='join'/><category term='create'/><category term='simon david'/><category term='projection clause'/><category term='ns_cache'/><category term='IIUG'/><category term='databases'/><category term='isolation level'/><category term='IDS 11.50UC4 11.50.xC4 11.50.FC4 compression IIUG'/><category term='if exists'/><category term='bases de dados grátis'/><category term='lisboa'/><category term='grátis'/><category term='end of service'/><category term='index'/><category term='Rob Thomas'/><category term='Real Time Loader'/><category term='DSS'/><category term='11.50.FC2'/><category term='informix roi'/><category term='Informix Stategy'/><category term='plano de execução'/><category term='installation'/><category term='apresentações'/><category term='end of support'/><category term='philip howard'/><category term='initialize'/><category term='estudo'/><category term='informix upgrades'/><category term='eos'/><category term='update statistics'/><category term='client sdk'/><category term='apresentadores'/><category term='centric'/><category term='11.50.TC2'/><category term='explain_sql'/><category term='informixpy'/><category term='encryption'/><category term='11.50UC4'/><category term='informix change password'/><category term='informix green initiative smarter planet'/><category term='datawarehouse accelerator'/><category term='cast'/><category term='websphere'/><category term='row_number'/><category term='tarefas'/><category term='história'/><category term='informix user'/><category term='function'/><category term='IPA'/><category term='free space'/><category term='pam'/><category term='TimeSeries'/><category term='performance'/><category term='embeber'/><category term='11.50.TC3'/><category term='informix community'/><category term='Vormetric'/><category term='reverse'/><category term='virtual image'/><category term='SQLTRACE'/><category term='conection'/><category term='Database Security Expert'/><category term='956'/><category term='acquisition'/><category term='asp'/><category term='future'/><category term='11.7'/><category term='mysql'/><category term='informix feature'/><category term='conexão'/><category term='choice edition'/><category term='optimizer'/><category term='reverse dns'/><category term='beneficios'/><category term='11.70'/><category term='oracle'/><category term='growth edition'/><category term='swift'/><category term='webSphereDefaultIsolationLevel'/><category term='pending'/><category term='informix sites'/><category term='dbspaces'/><category term='software'/><category term='11.70.FC4'/><category term='11.70.TC4'/><category term='base de dados gratuita'/><category term='redirected writes'/><category term='LAST COMMITTED'/><category term='partition'/><category term='china'/><category term='release'/><category term='extensibility'/><category term='11.70.xC4'/><category term='#databases'/><category term='hp'/><category term='11.50.FC4'/><category term='RUNasroot'/><category term='chunk overwrite'/><category term='datasource'/><category term='trust'/><category term='11.70.UC2'/><category term='FULL_DISK_INIT'/><category term='cache'/><category term='connection'/><category term='2011'/><category term='custos'/><category term='javier gray'/><category term='inplace alter'/><category term='inicializar'/><category term='query plan'/><category term='951'/><category term='benchmark'/><category term='conference'/><category term='Informix Warehouse Accelerator'/><category term='datablade'/><category term='evento'/><category term='informix user group'/><category term='iwa'/><category term='new version'/><category term='null comparison'/><category term='IIUG 2010'/><category term='stack trace'/><category term='CIO'/><category term='compression'/><category term='problem solving'/><category term='nova versao'/><category term='2012'/><category term='castilian'/><category term='bank'/><category term='OLTP'/><category term='bloor'/><category term='ixlocks'/><category term='amazon'/><category term='forrester'/><category term='função'/><category term='truss'/><category term='informix demo'/><category term='smarter'/><category term='encryption expert'/><category term='versions'/><category term='windows'/><category term='feature requests'/><category term='continuing support pilot'/><category term='Open Admin Tool'/><category term='trusted connection'/><category term='returning null'/><category term='no more extents'/><category term='11.70.TC3'/><category term='database'/><category term='presentations'/><category term='discover informix'/><category term='panther'/><category term='monitorizacao'/><category term='PCI'/><category term='stored procedure'/><category term='cheetah'/><category term='NULL'/><category term='distributions'/><category term='gis'/><category term='plano execução'/><category term='/etc/hosts'/><category term='monitoring'/><category term='informix blogs'/><category term='IATEMPDIR'/><category term='PCI DSS'/><category term='Informix Genero'/><category term='blog'/><category term='datatype precedence'/><category term='brazil'/><category term='tco'/><category term='reorg'/><category term='french'/><category term='instalação'/><category term='informix locks'/><category term='john miller'/><category term='implicit'/><category term='informix comunity'/><category term='uiltimate edition'/><category term='instance layout'/><category term='ultimate edition'/><category term='history'/><category term='microsoft'/><category term='sobreposicao chunk'/><category term='genoncfg'/><category term='slot'/><category term='informix'/><category term='savepoint'/><category term='11.70.UC4'/><category term='retorno do investimento'/><category term='futuro'/><title type='text'>Informix technology</title><subtitle type='html'>This is a small repository of information and a few articles about IBM Informix technology</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default?start-index=101&amp;max-results=100'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>120</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-35024011.post-3483473239075138924</id><published>2012-01-31T15:05:00.000Z</published><updated>2012-01-31T15:07:13.776Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='function'/><category scheme='http://www.blogger.com/atom/ns#' term='datablade'/><category scheme='http://www.blogger.com/atom/ns#' term='extensibilidade'/><category scheme='http://www.blogger.com/atom/ns#' term='#informix'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='rownum'/><category scheme='http://www.blogger.com/atom/ns#' term='udr'/><category scheme='http://www.blogger.com/atom/ns#' term='mi_integer'/><category scheme='http://www.blogger.com/atom/ns#' term='row_number'/><category scheme='http://www.blogger.com/atom/ns#' term='funcao'/><category scheme='http://www.blogger.com/atom/ns#' term='extensibility'/><title type='text'>UDRs: ROWNUM in Informix / ROWNUM em Informix</title><content type='html'>&lt;br /&gt;This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;English version&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;ROWNUM again?!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is more or less a FAQ. If you search the Internet for "rownum informix" you'll get a lot of links and several possible answers. I don't plan to give you a final answer, but I'll take advantage of this frequent topic to go back to something I do enjoy: User Defined functions in C language.&lt;br /&gt;Most of the questions regarding ROWNUM appear in the form "does Informix support XPTO database system's ROWNUM", or "does Informix support ROW_NUMBER like database XPTO?" or even "does Informix allow the retrieval of the top N rows?" So, if you ever need something that resembles ROWNUM, the first thing you should do it to establish a clear understanding of what you need. Because the above three questions can represent three different needs, and for each need there may be a different answer. Let's see:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Does Informix support ROWNUM?&lt;br /&gt;Quick answer would be no. But usually ROWNUM referes to an Oracle "magic" column that's added to the result set and that represents the position of the row in the result set. Note that this number is associated before doing ORDER BY and other clauses. So the result may not be very intuitive. Many times the purpose of using it is just to restrict the number of rows returned. Something that in ANSI (2008) SQL would be done by using the FETCH FIRST n ROWS clause. And this can be done in Informix very simply by puting a "FIRST n" before the select list:&lt;br /&gt;&lt;br /&gt;SELECT FIRST n * FROM customer&lt;br /&gt;&lt;br /&gt;But if you want to associate an incremental number to each row we can implement other solutions.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Does Informix allow the retrieval of the top N rows?&lt;br /&gt;Yes. I just showed how to do it in the previous section. Just use the FIRST n clause. Also note that you can also use the SKIP n clause. This options are applied after all the other clauses in the SELECT. So you could use them for pagination (although it would require running the same query several times, which is not efficient).&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Does Informix support row_number()?&lt;br /&gt;No. And there's not much we could do. The row_number clause or function is a complex construct that can associate an incremental number to a result set, but with very flexible options that allows the numbering to restart on specific conditions etc. In order to achieve this we would need to be able to change how the query is solved. And we can't. But read on...&lt;/li&gt;&lt;/ol&gt;So, the initial purpose of this article is to explain how we can create a simple function that will generate an incremental number for each row of the result set. Sometimes this can be useful, and you'll possibly be amazed by how simple it is. There are a few challenges though... And you must be aware of how it works, or the results may surprise you.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;The implementation in C&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You probably heard that we can create functions in C, Java and SPL (Stored Procedure Language), but most of us only used SPL. Informix extensibility through the user defined routines (UDR) is one of it's greatest strengths, but unfortunately it's also one of the least used features. This is unfortunate not only because we're wasting a lot of potential, but also because a greater usage would probably lead to greater improvement. I'm taking this opportunity to show you how simple it can be to create a function.&lt;br /&gt;In order to do it, we must follow some rules, and we should know a bit about the available API. A good place to start understanding how we can create UDRs is the &lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.udr.doc/udr.htm" target="_blank"&gt;User's Defined Routines and Datatypes Developer's Guide&lt;/a&gt;. This explains the generic concepts and the kind of UDRs we can create. Then we can check the &lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.dapip.doc/dapip.htm" target="_blank"&gt;Datablade API Programer's Guide&lt;/a&gt;. This has a more technical description of several aspects (like memory management, processing input and output etc.). Finally we have the &lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.dapif.doc/dapif.htm" target="_blank"&gt;Datablade API Function Reference&lt;/a&gt;, for specific function help and description. But of course.... reading all this without practice is more or less useless. We could use a list of examples to get us going...&lt;br /&gt;&lt;br /&gt;So, what I propose is to create a very simple C function that can be embedded in the engine. It's use is as easy as if it was a native function. And it's creation is really simple. The language used will be C. SPL is less flexible (although it can be very handy, useful and quick). Java doesn't have easy access to the internal API, but can eventually be even more flexible for certain tasks, although a bit more complex and slower. But it really depends on your background and needs.&lt;br /&gt;&lt;br /&gt;Before we start I should mention a few points which are in fact the hardest part of the process:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;IBM bundles a few scripts with the engine that are necessary to get us started. Inside $INFORMIXDIR/incl/dbdk there are a few scripts that are simple makefiles. We may need to adapt these to the platform or compiler we're using. In my system I have:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;makeinc.gen&lt;/li&gt;This is a generic cross platform makefile used by the next one&lt;li&gt;makeinc.linux&lt;/li&gt;This is a makefile specific for your platform which includes the previous one&lt;li&gt;makeinc.rules&lt;/li&gt;This is a makefile containing basic compilation rules These scripts can and should be used by your own makefile &lt;/ul&gt;&lt;/li&gt;&lt;li&gt;The function code needs to include some files and follow several rules.&lt;/li&gt;&lt;li&gt;After you create the function code, we need to compile it to object code and generate a dynamic loadable library. This is the way we make it available for the engine&lt;/li&gt;&lt;li&gt;After installing the library we have to create the function, telling the engine where it is available&lt;/li&gt;&lt;/ol&gt;Let's start by creating the code. As this is a crash course, I'll try to keep explanations to a minimum...:&lt;br /&gt;&lt;pre&gt;1    /*&lt;br /&gt;2    ------------------------------------------&lt;br /&gt;3     include section&lt;br /&gt;4    ------------------------------------------&lt;br /&gt;5    */&lt;br /&gt;6    #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;7    #include &amp;lt;milib.h&amp;gt;&lt;br /&gt;8    #include &amp;lt;sqlhdr.h&amp;gt;&lt;br /&gt;9    #include &amp;lt;value.h&amp;gt;&lt;br /&gt;10    &lt;br /&gt;11    mi_integer ix_rownum( MI_FPARAM *fp)&lt;br /&gt;12    {&lt;br /&gt;13     mi_integer *my_udr_state, ret;&lt;br /&gt;14    &lt;br /&gt;15     /*&lt;br /&gt;16     ----------------------------------------------------------&lt;br /&gt;17     check to see if we've been called before on this statement&lt;br /&gt;18     ----------------------------------------------------------&lt;br /&gt;19     */&lt;br /&gt;20     my_udr_state = (mi_integer *) mi_fp_funcstate(fp);&lt;br /&gt;21     if ( my_udr_state == NULL )&lt;br /&gt;22     {&lt;br /&gt;23      // No... we haven't... Let's create the persistent structure&lt;br /&gt;24      my_udr_state = (mi_integer *)mi_dalloc(sizeof(mi_integer),PER_STMT_EXEC);&lt;br /&gt;25      if ( my_udr_state == (mi_integer *) NULL)&lt;br /&gt;26      {&lt;br /&gt;27       ret = mi_db_error_raise (NULL, MI_EXCEPTION, "Error in ix_rownum: Out of memory");&lt;br /&gt;28       return(ret);&lt;br /&gt;29      }&lt;br /&gt;30      // We created it, so let's register it and initialize it to 1&lt;br /&gt;31      mi_fp_setfuncstate(fp, (void *)my_udr_state);&lt;br /&gt;32      (*my_udr_state)=1;&lt;br /&gt;33     }&lt;br /&gt;34     else&lt;br /&gt;35     {&lt;br /&gt;36      // If it's not the first time, then just increment the counter...&lt;br /&gt;37      (*my_udr_state)++;&lt;br /&gt;38     }&lt;br /&gt;39     // return the counter...&lt;br /&gt;40     return(*my_udr_state);&lt;br /&gt;41    }&lt;stdio.h&gt;&lt;milib.h&gt;&lt;sqlhdr.h&gt;&lt;value.h&gt;&lt;br /&gt;&lt;/value.h&gt;&lt;/sqlhdr.h&gt;&lt;/milib.h&gt;&lt;/stdio.h&gt;&lt;/pre&gt;The important points are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Lines 1-10 are just the normal and required includes&lt;/li&gt;&lt;li&gt;Line 11 is the function header. We define it as returning an mi_integer (on this functions we should use the mi_* datatypes). We accept one parameter which is a pointer to a function context&lt;/li&gt;&lt;li&gt;Line 13 where we define auxiliary variables&lt;/li&gt;&lt;li&gt;Line 20, we try to retrieve the previous value we kept stored in a persistent memory area. For that we use a datablade API function called &lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.dapif.doc/ids_dapif_182.htm" target="_blank"&gt;mi_fp_funcstate&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Lines 21-30, if the previous call returned a NULL pointer we try to allocate (&lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.dapif.doc/ids_dapif_135.htm" target="_blank"&gt;mi_dalloc&lt;/a&gt;) memory for keeping the counter. This may be one of the most important steps. We define that the persistence criteria is PER_STMT_EXEC. This means we're keeping the context only while we're executing the same statement. We test the result and raise an error if the allocation fails&lt;/li&gt;&lt;li&gt;Line 31 we register the memory we have allocated as the function automatic parameter by calling &lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.dapif.doc/ids_dapif_201.htm" target="_blank"&gt;mi_fp_setfuncstate&lt;/a&gt;()&lt;/li&gt;&lt;li&gt;Line 32 is the counter initialization. On the first call we define it as 1&lt;/li&gt;&lt;li&gt;Line 37 is the just the case for all the calls except the first. And in the generic case we just increment the counter&lt;/li&gt;&lt;li&gt;Line 40 is just the return of the value after initializing or incrementing it&lt;/li&gt;&lt;/ul&gt;Except for some strange but powerful functions, the code is trivial. But how do we make it available to the SQL layer? First we need to compile it and generate the dinamic library. For that I created a simple makefile:&lt;br /&gt;&lt;pre&gt;include $(INFORMIXDIR)/incl/dbdk/makeinc.linux&lt;br /&gt;&lt;br /&gt;MI_INCL = $(INFORMIXDIR)/incl&lt;br /&gt;CFLAGS = -DMI_SERVBUILD $(CC_PIC) -I$(MI_INCL)/public $(COPTS)&lt;br /&gt;LINKFLAGS = $(SHLIBLFLAG) $(SYMFLAG)&lt;br /&gt;&lt;br /&gt;all: ix_rownum&lt;br /&gt;&lt;br /&gt;clean:&lt;br /&gt; rm *.udr *.o&lt;br /&gt;&lt;br /&gt;ix_rownum: ix_rownum.udr&lt;br /&gt; @echo "Library genaration done"&lt;br /&gt;&lt;br /&gt;ix_rownum.o: ix_rownum.c&lt;br /&gt; @echo "Compiling..."&lt;br /&gt; $(CC) $(CFLAGS) -o $@ -c $?&lt;br /&gt;&lt;br /&gt;ix_rownum.udr: ix_rownum.o&lt;br /&gt; @echo "Creating the library..."&lt;br /&gt; $(SHLIBLOD) $(LINKFLAGS) -o $@ $?&lt;/pre&gt;&lt;br /&gt;Note the inclusion of the Linux makefile I mentioned earlier. If everything goes well, after I run&amp;nbsp;&lt;i&gt;make&lt;/i&gt; I will have a dynamic loadable library called ix_rownum.udr&lt;br /&gt;&lt;pre&gt;panther@pacman.onlinedomus.com:informix-&amp;gt; make&lt;br /&gt;Compiling...&lt;br /&gt;cc -DMI_SERVBUILD -fpic -I/usr/informix/srvr1170uc4/incl/public -g -o ix_rownum.o -c ix_rownum.c&lt;br /&gt;Creating the library...&lt;br /&gt;gcc -shared -Bsymbolic -o ix_rownum.udr ix_rownum.o&lt;br /&gt;Library genaration done&lt;br /&gt;panther@pacman.onlinedomus.com:informix-&amp;gt; &lt;br /&gt;&lt;/pre&gt;Having done this we need to create the funcion using SQL, as an external function. The syntax can be:&lt;br /&gt;&lt;pre&gt;CREATE FUNCTION rownum() RETURNING INTEGER&lt;br /&gt;WITH (VARIANT)&lt;br /&gt;EXTERNAL NAME '/home/informix/udr_tests/ix_rownum.udr(ix_rownum)'&lt;br /&gt;LANGUAGE C;&lt;/pre&gt;We're telling the engine to create a function called rownum, which does not receive any parameter and returns an INTEGER. We specify that it's written in C and the location. Note that I'm giving it the full dynamic library path (/home/informix/udr_tests/ix_rownum.udr) and the function name inside that library (a single library can contain more than one function). And I left the explanation for "WITH(VARIANT)" for last... The external function creation allows us to specify several properties for the functions. This one, VARIANT, tells the engine that the function may return different values when called with the same parameters. This is critical since we're not passing any parameters. If we told the engine it was NOT VARIANT it would only call it once. After that it would assume the return value was 1. This is an optimization, but in our case we don't want it, since it would break the function logic. VARIANT is the default and I just include it for clarity. You can find more about the function properties &lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.sqls.doc/ids_sqs_1656.htm#ids_sqs_1656" target="_blank"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Working with it&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Well, after the above we are able to use ROWNUM() in SQL. Let's see a few examples:&lt;br /&gt;&lt;pre&gt;-- Example 1:&lt;br /&gt;SELECT customer_num, rownum() row_num&lt;br /&gt;FROM customer;&lt;br /&gt;customer_num     row_num&lt;br /&gt;         101           1&lt;br /&gt;         102           2&lt;br /&gt;         103           3&lt;br /&gt;         104           4&lt;br /&gt;         105           5&lt;br /&gt;         106           6&lt;br /&gt;         107           7&lt;br /&gt;         108           8&lt;br /&gt;         109           9&lt;br /&gt;[...]&lt;br /&gt;-- Example 2&lt;br /&gt;SELECT customer_num, rownum()&lt;br /&gt;FROM customer&lt;br /&gt;WHERE rownum() &amp;lt; 5;&lt;br /&gt;customer_num     row_num&lt;br /&gt;&lt;br /&gt;         101           1&lt;br /&gt;         102           2&lt;br /&gt;         103           3&lt;br /&gt;         104           4&lt;br /&gt;&lt;br /&gt;-- Example 3&lt;br /&gt;SELECT&lt;br /&gt;        FIRST 4&lt;br /&gt;        customer_num, lname&lt;br /&gt;FROM&lt;br /&gt;        customer&lt;br /&gt;ORDER BY lname DESC;&lt;br /&gt;&lt;br /&gt;customer_num lname&lt;br /&gt;&lt;br /&gt;         106 Watson&lt;br /&gt;         121 Wallack&lt;br /&gt;         105 Vector&lt;br /&gt;         117 Sipes&lt;br /&gt;&lt;br /&gt;-- Example 4&lt;br /&gt;SELECT&lt;br /&gt;        customer_num , lname, rownum() row_num&lt;br /&gt;FROM&lt;br /&gt;        customer&lt;br /&gt;WHERE rownum() &amp;lt; 5&lt;br /&gt;ORDER BY lname DESC;&lt;br /&gt;&lt;br /&gt;customer_num lname               row_num&lt;br /&gt;&lt;br /&gt;         102 Sadler                    2&lt;br /&gt;         101 Pauli                     1&lt;br /&gt;         104 Higgins                   4&lt;br /&gt;         103 Currie                    3&lt;br /&gt;&lt;br /&gt;-- Example 5&lt;br /&gt;SELECT&lt;br /&gt;        t1.*, rownum() row_num&lt;br /&gt;FROM (SELECT customer_num, lname FROM customer ORDER BY lname DESC) as t1 &lt;br /&gt;WHERE rownum() &amp;lt;5;&lt;br /&gt;&lt;br /&gt;customer_num lname               row_num&lt;br /&gt;&lt;br /&gt;         106 Watson                    1&lt;br /&gt;         121 Wallack                   2&lt;br /&gt;         105 Vector                    3&lt;br /&gt;         117 Sipes                     4&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Let's comment the above examples. There are very important aspects to consider.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Example 1&lt;br /&gt;This is the simplest example. And works as expected&lt;/li&gt;&lt;li&gt;Example 2&lt;br /&gt;Here we are using ROWNUM() also as a filter for the WHERE clause.&lt;/li&gt;&lt;li&gt;Example 3&lt;br /&gt;This is a auxiliary example to show a possible problem. It's just a select of customer_num and lname ordered by this in a decremental order.&lt;/li&gt;&lt;li&gt;Example 4&lt;br /&gt;Here we're trying the same thing, but using ROWNUM() to limit the number of rows. Note that this alters the result set. Why? Because ROWNUM() is applied immediately on the full table scan. The first 4 rows are retrieved and then the ORDER BY is applied. So using ROWNUM changes the the result set, because it's applied (in the WHERE clause) before the ORDER BY.&lt;/li&gt;&lt;li&gt;Example 5&lt;br /&gt;If we wanted to reproduce the result set from example 3, but still add a row number we could use the syntax presented here&lt;/li&gt;&lt;/ul&gt;I mentioned above that we could not reproduce the functionality of the ROW_NUMBER() construct of the SQL standard. This allows us to specify an ORDER BY clause and a PARTITION BY clause.&lt;br /&gt;The ORDER BY inside the ROW_NUMBER() tells the database to order the sequence numbers by the specified filed(s). The PARTITION BY tells it to "restart" the count each time the field specified changes (similar to the effect of GROUP BY and aggregate functions). Note that this ORDER BY does not influence the order of the result set.&lt;br /&gt;If you're wondering if we could implement the same functionality using functions, the answer is "sort of..." But I'll leave that for another article.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;Versão Portuguesa&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;ROWNUM outra vez?!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Isto é uma questão que pode fazer parte dos FAQs. Se pesquisar na Internet por "rownum informix" vai obter uma série de &lt;i&gt;links&lt;/i&gt; e algumas possíveis respostas. Não espero dar uma resposta definitiva, mas vou aproveitar este tema para voltar a um assunto que me agrada bastante: Funções definidas pelo utilizador em C.&lt;br /&gt;Muitas das questões em torno do &lt;i&gt;ROWNUM&lt;/i&gt; parecem numa das formas "o Informix suporta o &lt;i&gt;ROWNUM &lt;/i&gt;tal como a base de dados XPTO?", ou "o Informix suporta o &lt;i&gt;ROW_NUM&lt;/i&gt; como a base de dados XPTO?" ou ainda "o Informix suporta obter apenas as &lt;i&gt;N&lt;/i&gt; primeiras linhas de uma query?". Assim se as suas necessidades parecem ir ao encontro do &lt;i&gt;ROWNUM&lt;/i&gt; a primeira coisa a fazer é perceber exactamente o que se pretende. Necessidades diferentes podem ter soluções diferentes. Vamos ver:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;O Informix suporta o ROWNUM?&lt;br /&gt;A resposta rápida seria não. Mas habitualmente a referência a ROWNUM diz respeita a uma coluna "mágica" do Oracle, que é adicionada ao conjunto de resultados e que representa a posição de cada linha nesse mesmo conjunto. Note que este número é adicionado antes do processamento do ORDER BY e outras cláusulas e isso pode tornar o resultado pouco intuitivo. Muitas vezes é usado apenas para limitar o número de linhas obtido. Algo que em ANSI (2008) SQL seria feito com a cláusula FETCH FIRST n ROWS. E isto pode ser feito em Informix muito simplesmente com um FIRST n antes da lista de colunas:&lt;br /&gt;&lt;br /&gt;SELECT FIRST n * FROM customer&lt;br /&gt;&lt;br /&gt;Mas se o que pretende é associar um número incremental a cada linha podemos implementar outras soluções.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&amp;nbsp;O Informix suporta obter apenas as primeiras N linhas?&lt;br /&gt;Sim. Mostrei como no parágrafo anterior. Basta usar a cláusula FIRST N. Note-se que podemos também usar a cláusula SKIP n. Estas opções são aplicadas após todas as outras cláusulas do SELECT, nomeadamente o ORDER BY. Podem portanto ser usadas para paginação de resultados, embora isso leve à execução da mesma query várias vezes, o que não será muito eficiente&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;O Informix suporta ROW_NUMBER?&lt;br /&gt;Não. E não há muito que possamos fazer. A cláusula ROW_NUMBER é complexa. Permite associar um sequência incremental de valores a um conjunto de resultados, mas com opções muito flexíveis que permitem ordenar a sequência segundo um critério e recomeçar do valor 1 sempre que certas colunas mudam. Para conseguir fazer isto teríamos de conseguir controlar a forma como o motor resolve as &lt;i&gt;queries&lt;/i&gt;. E tal não é possível... Mas já vamos ver o que se pode fazer...&lt;/li&gt;&lt;/ol&gt;Sendo assim, o proprósito inicial deste artigo é explicar como criar uma função simples que gera un número sequencial para cada linha do conjunto de resultados. Isto pode ser útil e possivelmente ficará admirado com a simplicidade de o fazer. No entanto existem alguns desafios.... E tem de estar atento à forma como funciona, ou os resultados podem parecer inesperados.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;A implementação em C&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Já deve ter ouvido ou lido que podemos criar funções em C, Java e SPL (&lt;i&gt;Stored Procedure Language&lt;/i&gt;), mas a maioria de nós apenas lidou com SPL. A capacidade de extensão do Informix através das funções definidas pelo utilizador (UDRs) é uma das suas melhores vantagens, mas infelizmente é também uma das menos usadas. Isto é mau não só porque estamos a desperdiçar muito potencial, mas também porque uma maior utilização levaria certamente a mais melhorias e desenvolvimentos. Vou aproveitar esta oportunidade para mostrar o quão simples pode ser criar uma função.&lt;br /&gt;Para o fazer, temos de seguir algumas regras e devemos saber alguma coisa sobre a API disponível. Um bom sítio para começar a entender como podemos criar UDRs é o &lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.udr.doc/udr.htm" target="_blank"&gt;User's Defined Routines and Datatypes Developer's Guide&lt;/a&gt;. Isto explica os conceitos genéricos e os tipos de UDRs que podemos criar. Depois podemos consultar o &lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.dapip.doc/dapip.htm" target="_blank"&gt;Datablade API Programer's Guide&lt;/a&gt;.  Este contém uma descrição mais técnica sobre vários aspectos (como gestão de memória, processamento de &lt;i&gt;input&lt;/i&gt; e &lt;i&gt;output&lt;/i&gt; etc.). Por último temos o &lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.dapif.doc/dapif.htm" target="_blank"&gt;Datablade API Function Reference&lt;/a&gt;,  para informação e ajuda em funções específicas. Mas claro... ler isto tudo sem praticar é mais ou menos inútil. Seria bom termos uma lista de exemplos que nos permitissem arrancar....&lt;br /&gt;&lt;br /&gt;Assim o que proponho é criar uma função muito simples em C que possa ser embebida no motor. O seu uso é tão fácil como se fosse uma função nativa do motor. E a sua criação é bastante simples. A linguagem usada será C, pois SPL é menos fléxivel (embora possa ser bastante prática, útil e rápida). O Java não tem o acesso tão fácil às funções da API interna, mas pode ainda ser mais fléxivel para algumas tarefas, embora possa ser mais complexo e lento. Mas a escolha deverá depender sempre das nossas necessidades e mesmo do nosso &lt;i&gt;background&lt;/i&gt; com cada uma das linguagens.&lt;br /&gt;&lt;br /&gt;Antes de começar devo referir alguns pontos que na verdade serão os mais difícieis do processo:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;A IBM inclui alguns &lt;i&gt;scripts&lt;/i&gt; no motor que são necessários para arrancarmos. Dentro de $INFORMIXDIR/incl/dbdk existem alguns &lt;i&gt;makefiles&lt;/i&gt; simples. Poderá ser necessário adaptá-los à plataforma e/ou compilador que vamos usar.No meu sistema tenho:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;makeinc.gen&lt;/li&gt;Um &lt;i&gt;makefile&lt;/i&gt; genérico (várias paltaformas) usado pelo próximo&lt;li&gt;makeinc.linux&lt;/li&gt;&lt;i&gt;Makefile&lt;/i&gt; específico para Linux que referencia o anterior&lt;li&gt;makeinc.rules&lt;/li&gt;&lt;i&gt;Makefile&lt;/i&gt; com regras genéricas de compilaçãoEstes &lt;i&gt;scripts&lt;/i&gt; podem e devem ser usados pelo nosso próprio &lt;i&gt;makefile&lt;/i&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;O código da função tem de incluir alguns ficheiros e seguir determinadas regras&lt;/li&gt;&lt;li&gt;Depois de criarmos o código da função temos de a compilar para código objecto e a partir deste gerar uma biblioteca dinâmica. Esta será a forma de disponibilizar a função ao motor&lt;/li&gt;&lt;li&gt;Depois de instalar a biblioteca temos de usar SQL para criar a função indicando ao motor onde a mesma se encontra&lt;/li&gt;&lt;/ol&gt;Vamos começar por criar o código. Como isto é um algo do tipo "mãos na massa", vou tentar manter as explicações no mínimo...:&lt;br /&gt;&lt;pre&gt;1    /*&lt;br /&gt;2    ------------------------------------------&lt;br /&gt;3     secao de includes&lt;br /&gt;4    ------------------------------------------&lt;br /&gt;5    */&lt;br /&gt;6    #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;7    #include &amp;lt;milib.h&amp;gt;&lt;br /&gt;8    #include &amp;lt;sqlhdr.h&amp;gt;&lt;br /&gt;9    #include &amp;lt;value.h&amp;gt;&lt;br /&gt;10    &lt;br /&gt;11    mi_integer ix_rownum( MI_FPARAM *fp)&lt;br /&gt;12    {&lt;br /&gt;13     mi_integer *my_udr_state, ret;&lt;br /&gt;14    &lt;br /&gt;15     /*&lt;br /&gt;16     ----------------------------------------------------------&lt;br /&gt;17     Ver se já fomos chamados antes nesta instrução SQL&lt;br /&gt;18     ----------------------------------------------------------&lt;br /&gt;19     */&lt;br /&gt;20     my_udr_state = (mi_integer *) mi_fp_funcstate(fp);&lt;br /&gt;21     if ( my_udr_state == NULL )&lt;br /&gt;22     {&lt;br /&gt;23      // Não... não fomos... Vamos criar a estrutura persistente&lt;br /&gt;24      my_udr_state = (mi_integer *)mi_dalloc(sizeof(mi_integer),PER_STMT_EXEC);&lt;br /&gt;25      if ( my_udr_state == (mi_integer *) NULL)&lt;br /&gt;26      {&lt;br /&gt;27       ret = mi_db_error_raise (NULL, MI_EXCEPTION, "Erro em ix_rownum: Memória insuficiente");&lt;br /&gt;28       return(ret);&lt;br /&gt;29      }&lt;br /&gt;30      // Já criámos, portanto vamos registar e inicializar a 1&lt;br /&gt;31      mi_fp_setfuncstate(fp, (void *)my_udr_state);&lt;br /&gt;32      (*my_udr_state)=1;&lt;br /&gt;33     }&lt;br /&gt;34     else&lt;br /&gt;35     {&lt;br /&gt;36      // Se não é a primeira vez vamos incrementar o contador...&lt;br /&gt;37      (*my_udr_state)++;&lt;br /&gt;38     }&lt;br /&gt;39     // retornamos o contador...&lt;br /&gt;40     return(*my_udr_state);&lt;br /&gt;41    }&lt;br /&gt;&lt;/pre&gt;Os pontos importantes são:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Linhas 1-10 são os &lt;i&gt;includes&lt;/i&gt; normais e necessários&lt;/li&gt;&lt;li&gt;Linha 11 é o cabeçalho da função. Definimos como retornando um mi_integer (nestas funções devemos usar os tipos de dados mi_*). Aceitamos um parâmetro que será um ponteiro para uma estrutura de contexto da função. Este parâmetro não será visível na assinatura "externa" da função (ao nível do SQL)&lt;/li&gt;&lt;li&gt;Linha 13 onde definimos variáveis auxiliares&lt;/li&gt;&lt;li&gt;Linha 20, tentamos obter o valor anterior que mantivemos na estrutura persistente de memória. Para isso usamos uma função da API dos &lt;i&gt;datblades&lt;/i&gt; chamada&amp;nbsp;&lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.dapif.doc/ids_dapif_182.htm" target="_blank"&gt;mi_fp_funcstate&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Linhas 21-30, se a chamada anterior devolver um ponteiro NULL, tentamos alocar (&lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.dapif.doc/ids_dapif_135.htm" target="_blank"&gt;mi_dalloc&lt;/a&gt;) memória para manter o contador. Este será um dos passos mais importantes. Definimos que o critério de persistência é PER_STMT_EXEC. Isto significa que mantemos o contexto apenas durante a execução da mesma instrução SQL. Testamos o resultado e criamos uma excepção de a alocação falhar.&lt;/li&gt;&lt;li&gt;Linha 31 registamos a memória alocada anteriormente como o parâmetro automático da função através da chamada &lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.dapif.doc/ids_dapif_201.htm" target="_blank"&gt;mi_fp_setfuncstate&lt;/a&gt;()&lt;/li&gt;&lt;li&gt;Linha 32 é a inicialização do contador. Na primeira chamada definimo-lo como 1&lt;/li&gt;&lt;li&gt;Linha 37 é apenas o caso geral, para todas as chamadas excepto a primeira. E no caso geral apenas incrementamos o contador&lt;/li&gt;&lt;li&gt;Linha 40 é o retorno da função, ou seja o valor do contador após inicialização ou incremento&lt;/li&gt;&lt;/ul&gt;À excepção de algumas funções estranhas, mas poderosas, o código é trivial. Mas como o disponibilizamos à camada de SQL? Antes de mais necessitamos de o compilar e gerar a biblioteca dinâmica. Para isso criamos um &lt;i&gt;makefile&lt;/i&gt; simples:&lt;br /&gt;&lt;pre&gt;include $(INFORMIXDIR)/incl/dbdk/makeinc.linux&lt;br /&gt;&lt;br /&gt;MI_INCL = $(INFORMIXDIR)/incl&lt;br /&gt;CFLAGS = -DMI_SERVBUILD $(CC_PIC) -I$(MI_INCL)/public $(COPTS)&lt;br /&gt;LINKFLAGS = $(SHLIBLFLAG) $(SYMFLAG)&lt;br /&gt;&lt;br /&gt;all: ix_rownum&lt;br /&gt;&lt;br /&gt;clean:&lt;br /&gt; rm *.udr *.o&lt;br /&gt;&lt;br /&gt;ix_rownum: ix_rownum.udr&lt;br /&gt; @echo "Geração da biblioteca completa..."&lt;br /&gt;&lt;br /&gt;ix_rownum.o: ix_rownum.c&lt;br /&gt; @echo "Compilando..."&lt;br /&gt; $(CC) $(CFLAGS) -o $@ -c $?&lt;br /&gt;&lt;br /&gt;ix_rownum.udr: ix_rownum.o&lt;br /&gt; @echo "Creando a biblioteca..."&lt;br /&gt; $(SHLIBLOD) $(LINKFLAGS) -o $@ $?&lt;/pre&gt;&lt;br /&gt;Note-se a inclusão do &lt;i&gt;makefile&lt;/i&gt; Linux que mencionei anteriormente. Se tudo correr bem, após corrermos &lt;i&gt;make&lt;/i&gt; teremos uma biblioteca dinâmica chamada&amp;nbsp; ix_rownum.udr&lt;br /&gt;&lt;pre&gt;panther@pacman.onlinedomus.com:informix-&amp;gt; make&lt;br /&gt;Compilando...&lt;br /&gt;cc -DMI_SERVBUILD -fpic -I/usr/informix/srvr1170uc4/incl/public -g -o ix_rownum.o -c ix_rownum.c&lt;br /&gt;Creando a biblioteca...&lt;br /&gt;gcc -shared -Bsymbolic -o ix_rownum.udr ix_rownum.o&lt;br /&gt;Geração da biblioteca completa...&lt;br /&gt;panther@pacman.onlinedomus.com:informix-&amp;gt; &lt;br /&gt;&lt;/pre&gt;Após termos feito isto, necessitamos de criar a função usando SQL, como uma função externa. A sintaxe será:&lt;br /&gt;&lt;pre&gt;CREATE FUNCTION rownum() RETURNING INTEGER&lt;br /&gt;WITH (VARIANT)&lt;br /&gt;EXTERNAL NAME '/home/informix/udr_tests/ix_rownum.udr(ix_rownum)'&lt;br /&gt;LANGUAGE C;&lt;/pre&gt;Estamos a dizer ao motor para criar uma função chamada &lt;i&gt;rownum&lt;/i&gt;, a qual não recebe nenhum parâmetro, e retorna um INTEGER. Especificamos que é escrita em C e qual a localização. Note-se que estou a dar o caminho completo da biblioteca  (/home/informix/udr_tests/ix_rownum.udr) e o nome da função dentro da biblioteca (uma única biblioteca pode conter mais que uma função). Deixei a explicação para "WITH(VARIANT)" para último lugar... A criação de uma função externa permite-nos especificar várias propriedades para as funções. Esta, VARIANT, indica ao motor que a função pode retornar valores diferentes quando chamada duas ou mais vezes com os mesmos parâmetros. Isto é critico dado que não estamos a passar nenhum parâmetro. Se indicássemos ao motor que a função era NOT VARIANT apenas a chamaria uma vez. Depois disso assumiria que o valor de retorno era 1. Isto é uma optimização, mas no nosso caso não queremos que tal aconteça, dado que quebraria a lógica da função. VARIANT é o valor pré-definido, e apenas o incluí por clareza. Pode aprender mais sobre as propriedades das funções &lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.sqls.doc/ids_sqs_1656.htm#ids_sqs_1656" target="_blank"&gt;aqui&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Trabalhando com a função&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Depois do exposto acima, podemos usar ROWNUM() no SQL. Vejamos alguns exemplos:&lt;br /&gt;&lt;pre&gt;-- Exemplo 1:&lt;br /&gt;SELECT customer_num, rownum() row_num&lt;br /&gt;FROM customer;&lt;br /&gt;customer_num     row_num&lt;br /&gt;         101           1&lt;br /&gt;         102           2&lt;br /&gt;         103           3&lt;br /&gt;         104           4&lt;br /&gt;         105           5&lt;br /&gt;         106           6&lt;br /&gt;         107           7&lt;br /&gt;         108           8&lt;br /&gt;         109           9&lt;br /&gt;[...]&lt;br /&gt;-- Exemplo 2&lt;br /&gt;SELECT customer_num, rownum()&lt;br /&gt;FROM customer&lt;br /&gt;WHERE rownum() &amp;lt; 5;&lt;br /&gt;customer_num     row_num&lt;br /&gt;&lt;br /&gt;         101           1&lt;br /&gt;         102           2&lt;br /&gt;         103           3&lt;br /&gt;         104           4&lt;br /&gt;&lt;br /&gt;-- Exemplo 3&lt;br /&gt;SELECT&lt;br /&gt;        FIRST 4&lt;br /&gt;        customer_num, lname&lt;br /&gt;FROM&lt;br /&gt;        customer&lt;br /&gt;ORDER BY lname DESC;&lt;br /&gt;&lt;br /&gt;customer_num lname&lt;br /&gt;&lt;br /&gt;         106 Watson&lt;br /&gt;         121 Wallack&lt;br /&gt;         105 Vector&lt;br /&gt;         117 Sipes&lt;br /&gt;&lt;br /&gt;-- Exemplo 4&lt;br /&gt;SELECT&lt;br /&gt;        customer_num , lname, rownum() row_num&lt;br /&gt;FROM&lt;br /&gt;        customer&lt;br /&gt;WHERE rownum() &amp;lt; 5&lt;br /&gt;ORDER BY lname DESC;&lt;br /&gt;&lt;br /&gt;customer_num lname               row_num&lt;br /&gt;&lt;br /&gt;         102 Sadler                    2&lt;br /&gt;         101 Pauli                     1&lt;br /&gt;         104 Higgins                   4&lt;br /&gt;         103 Currie                    3&lt;br /&gt;&lt;br /&gt;-- Exemplo 5&lt;br /&gt;SELECT&lt;br /&gt;        t1.*, rownum() row_num&lt;br /&gt;FROM (SELECT customer_num, lname FROM customer ORDER BY lname DESC) as t1 &lt;br /&gt;WHERE rownum() &amp;lt;5;&lt;br /&gt;&lt;br /&gt;customer_num lname               row_num&lt;br /&gt;&lt;br /&gt;         106 Watson                    1&lt;br /&gt;         121 Wallack                   2&lt;br /&gt;         105 Vector                    3&lt;br /&gt;         117 Sipes                     4&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Vamos comentar os exemplos acima. Há aspectos muito importantes a considerar:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Exemplo1&lt;br /&gt;Este é o exemplo mais simples. Funciona como se esperaria&lt;/li&gt;&lt;li&gt;Exemplo 2&lt;br /&gt;Aqui estamos a usar o ROWNUM() também como filtro da cláusula WHERE&lt;/li&gt;&lt;li&gt;Exemplo 3&lt;br /&gt;Este é um exemplo auxiliar para ajudar a demonstrar um possível problema. É apenas um SELECT do customer_num e lname ordenado por este de forma descrescente&lt;/li&gt;&lt;li&gt;Exemplo 4&lt;br /&gt;Aqui estamos a tentar a mesma coisa, mas usando o ROWNUM() para limitar o número de linhas. Note-se que isto altera o conjunto de resultados. Porquê? Porque o ROWNUM() é aplicado imediatamente durante o &lt;i&gt;full table scan&lt;/i&gt; que é feito para resolver a query. As primeiras quatro linhas são obtidas, e depois o ORDER BY é aplicado. Portanto o uso do ROWNUM() altera o resultado porque é aplicado (na cláusula WHERE) antes do ORDER BY&lt;/li&gt;&lt;li&gt;Exemplo 5&lt;br /&gt;Se quiséssemos reprodudir o resultado do exemplo 3, mas ainda assim adicionar um número de linha a cada elemento dos resultados, poderíamos usar a sintaxe apresentada aqui&lt;/li&gt;&lt;/ul&gt;Referi acima que não poderíamos reproduzir a funcionalidade da instrução ROW_NUMBER(), do standard SQL. Esta permite-nos especificar uma cláusula de ORDER BY e outra de PARTITION BY.&lt;br /&gt;O ORDER BY dentro do ROW_NUMBER() indica ao motor que deve ordenar a sequência de números pelos campos indicados. O PARTITION BY diz-lhe para recomeçar a numeração cada vez que o campo indicado mudar de valor (semelhante ao efeito de um GROUP BY em agregados). Note-se que este ORDER BY não afecta a ordem dos resultados apresentados. &lt;br /&gt;Se está a imaginar se não poderíamos implementar uma funcionalidade semelhante usando funções, a resposta é "mais ou menos...". Mas vou deixar isso para outro possível artigo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-3483473239075138924?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/3483473239075138924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=3483473239075138924' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/3483473239075138924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/3483473239075138924'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2012/01/udrs-rownum-in-informix-rownum-em.html' title='UDRs: ROWNUM in Informix / ROWNUM em Informix'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-4757346027332052570</id><published>2012-01-09T10:30:00.000Z</published><updated>2012-01-09T10:52:30.813Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='trust'/><category scheme='http://www.blogger.com/atom/ns#' term='reverse'/><category scheme='http://www.blogger.com/atom/ns#' term='956'/><category scheme='http://www.blogger.com/atom/ns#' term='dns'/><category scheme='http://www.blogger.com/atom/ns#' term='#informix'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='ns_cache'/><category scheme='http://www.blogger.com/atom/ns#' term='/etc/hosts'/><category scheme='http://www.blogger.com/atom/ns#' term='951'/><title type='text'>DNS impact on Informix / Impacto do DNS no Informix</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;English version:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;You decided...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This article if the first "on-demand" topic I write about. I had a few options for topics I'd like to cover and I initiated a poll on a &lt;a href="http://www.facebook.com/pages/Informix-Portugal/169091949374" target="_blank"&gt;Facebook page&lt;/a&gt;. The impact of &lt;a href="http://en.wikipedia.org/wiki/Domain_Name_System" target="_blank"&gt;DNS&lt;/a&gt; on Informix was the most voted. So you asked for it, here it is. I will probably keep doing this from now on.&lt;br /&gt;Personally I also like this topic, partially because I had several problems related to this in more than one customer. This is a relatively common issue in complex environments.&lt;br /&gt;I have a public and generic disclaimer about the material I publish here, but for this case I'd like to stretch this just a bit... Beside the normal disclaimer, I'd like to state that most of the information presented here lies a bit far from my regular competencies. This is the result of a lot of digging and investigation over the time (not only from me), and there may be a few (hopefully minor) errors on the information provided. Feel free to comment, email me etc.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Very short introduction about DNS&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;DNS is the acronym for Domain Name System which is a protocol/service that is able to convert a hostname (e.g. onlinedomus.com)&amp;nbsp; into an IP address (e.g. 89.1.2.3) and the opposite. It can also do a lot of other stuff, like telling which mail server is responsible for a specific domain etc. but this is out of the scope of the article.&lt;br /&gt;Without DNS there would be no Internet as we know it. It's a critical component of the Internet infra-structure and it's performance and security is crucial for us, the users.&lt;br /&gt;In a small network you can work without DNS for the basic name resolution functions, by using files. But if your network is larger, it can be very hard to use those files.&lt;br /&gt;The DNS system uses an hierarchical architecture and the &lt;a href="http://en.wikipedia.org/wiki/User_Datagram_Protocol" target="_blank"&gt;UDP protocol&lt;/a&gt; (U does not stand for unreliable but it could be...) for performance reasons. Proper configuration of a DNS system can be a complex task, and my personal experience tells me it's not very easy to find who knows how to do it properly. Furthermore, many times people don't realize the terrible impact a DNS misconfiguration or malfunction may have on the systems.&lt;br /&gt;I will not explain (and I wouldn't know how to) all the DNS configuration aspects, but I'd like to reference a few points:&lt;br /&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;u&gt;/etc/nsswitch.conf&lt;/u&gt;&lt;div&gt;This file (on Unix/Linux systems, but the name can vary) defines how the name resolution (and other services) are used. In particular it can define if the system uses files, NIS, the DNS servers or other mechanism and the order it uses. As an example, a line like:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;hosts:      dns files&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;indicates that for hostname lookups the system will first ask the DNS servers and then looks in the files&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;/etc/hosts&lt;/u&gt;&lt;div&gt;This file can map IP addresses into hostnames (and vice-versa). As an example:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;89.1.2.3 www.onlinedomus.com onlinedomus.com&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This tells the system that the IP address 89.1.2.3 will map to "www.onlinedomus.com" (and vice-versa). As you can imagine, a lookup for "onlinedomus.com" will also map to the same IP address.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;/etc/resolv.conf&lt;/u&gt;&lt;div&gt;This contains the list of DNS servers that will be used for lookups and possibly a few other options (like requests timeout, names of domains that will be appended to simple hostnames, if the lookups for those hostnames fail etc.). An example:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;nameserver 192.168.112.2&lt;/div&gt;&lt;div&gt;nameserver 9.64.162.21&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;How does Informix use the DNS?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;From the DNS perspective, Informix is just another application. The /etc/nsswitch.conf file will tell if Informix will use the files (/etc/hosts) or the DNS servers (specified in /etc/resolv.conf). The first important thing to note is that all interaction between Informix and the DNS system goes through system calls. In particular these two functions or their equivalents or replacements:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;gethostbyname()&lt;br /&gt;In short, this receives an hostname and returns a structure containing the IP address&lt;/li&gt;&lt;li&gt;gethostbyaddr()&lt;br /&gt;This receives an IP address and returns the hostname that matches it&lt;/li&gt;&lt;/ul&gt;So, if something is not working, we need to understand how/when Informix calls these two functions and how they work. Typically customers blame Informix when it's not to blame (not completely, but more on this later). Most (if not all) problems I've seen in DNS affecting Informix can affect other applications and are reproducible with very short C language programs. This does not mean we couldn't do a few things differently (better?). But again, I'll cover this later (keep in mind the disclaimer! :) )&lt;br /&gt;This article is written mainly from the database server perspective. But the DNS has obvious implications for the client too... Let's start there and then I'll jump into the server.&lt;br /&gt;When a client tool tries to connect to an Informix server, it starts by looking up the $INFORMIXSERVER (or equivalent given in the connection string) in the $INFORMIXSQLHOSTS file (for Java it can look up LDAP or HTTP servers for the info, but let's stick to the files for easier understanding). The file contains lines in the following format:&lt;br /&gt;&lt;pre&gt;INFORMIXSERVER PROTOCOL HOSTNAME/IP_ADDRESS PORT_NUMBER/SERVICE_NAME OPTIONS&lt;/pre&gt;when the client libraries find the line matching the INFORMIXSERVER, they check the hostname (or IP&amp;nbsp; address) and the port number (or service name).&lt;br /&gt;Typically, if a service name is used, we look the port number in /etc/services (this can be configured in /etc/nsswitch.conf). Personally I tend to use the port number to avoid that lookup...&lt;br /&gt;Then, if a hostname is used, the client must map it to an IP address. For that it calls the gethostbyname() function. This function will behave as specified in /etc/nsswitch.conf, and will try to map the name to an IP address. A failure to do that will raise error -930. This can be reproduced:&lt;br /&gt;&lt;pre&gt;cheetah@pacman.onlinedomus.com:fnunes-&amp;gt; echo $INFORMIXSERVER; grep $INFORMIXSERVER $INFORMIXSQLHOSTS; dbaccess sysmaster -&lt;br /&gt;blogtest&lt;br /&gt;blogtest     onsoctcp     nowhere.onlinedomus.com 1500&lt;br /&gt;&lt;br /&gt;930: Cannot connect to database server (nowhere.onlinedomus.com).&lt;br /&gt;cheetah@pacman.onlinedomus.com:fnunes-&amp;gt;&lt;br /&gt;&lt;/pre&gt;and if you need evidences of what's going on behind the scenes we can use strace (or truss):&lt;br /&gt;&lt;pre&gt;strace -o /tmp/strace.out dbaccess sysmaster -&lt;/pre&gt;This is an edited extract of /tmp/strace.out generated by the command above. If you have the patience, you can see it doing the following:&lt;br /&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Open /etc/nsswitch.conf&lt;/li&gt;&lt;li&gt;Open $INFORMIXSQLHOSTS (/home/informix/etc/sqlhosts)&lt;/li&gt;&lt;li&gt;Open /etc/services (exceptionally I used a name instead of a port number)&lt;/li&gt;&lt;li&gt;Open /etc/resolv.conf to find out the configured nameservers&lt;/li&gt;&lt;li&gt;Open a socket to 192.168.112.2 (my configured DNS server)&lt;/li&gt;&lt;li&gt;Ask for nowhere.onlinedomus.com&lt;/li&gt;&lt;li&gt;Open /etc/hosts (in /etc/nsswtich.conf I configured to search the files if the DNS lookup fails)&lt;/li&gt;&lt;li&gt;Read the error message from the Informix message files&lt;/li&gt;&lt;li&gt;Write the error message to stderr&lt;/li&gt;&lt;li&gt;Exit with error code -1&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;pre&gt;cheetah@pacman.onlinedomus.com:fnunes-&amp;gt; cat /tmp/strace.out&lt;br /&gt;[...]&lt;br /&gt;open("/etc/nsswitch.conf", O_RDONLY)    = 3&lt;br /&gt;fstat64(3, {st_mode=S_IFREG|0644, st_size=1803, ...}) = 0&lt;br /&gt;mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7862000&lt;br /&gt;read(3, "#\n# /etc/nsswitch.conf\n#\n# An ex"..., 4096) = 1803&lt;br /&gt;read(3, "", 4096)                       = 0&lt;br /&gt;close(3)                                = 0&lt;br /&gt;[...]&lt;br /&gt;open("/home/informix/etc/sqlhosts", O_RDONLY|O_LARGEFILE) = 4&lt;br /&gt;_llseek(4, 0, [0], SEEK_SET)            = 0&lt;br /&gt;read(4, "blogtest     onsoctcp     nowher"..., 4096) = 1389&lt;br /&gt;[...]&lt;br /&gt;open("/etc/services", O_RDONLY|O_CLOEXEC) = 4&lt;br /&gt;fstat64(4, {st_mode=S_IFREG|0644, st_size=644327, ...}) = 0&lt;br /&gt;mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7862000&lt;br /&gt;read(4, "# /etc/services:\n# $Id: services"..., 4096) = 4096&lt;br /&gt;close(4)                                = 0&lt;br /&gt;[...]&lt;br /&gt;open("/etc/resolv.conf", O_RDONLY)      = 4&lt;br /&gt;[...]&lt;br /&gt;read(4, "", 4096)                       = 0&lt;br /&gt;close(4)                                = 0&lt;br /&gt;[...]&lt;br /&gt;open("/lib/libresolv.so.2", O_RDONLY)   = 4&lt;br /&gt;read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0Pf\256\0004\0\0\0"..., 512) = 512&lt;br /&gt;[...]&lt;br /&gt;close(4)                                = 0&lt;br /&gt;[...]&lt;br /&gt;socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 4&lt;br /&gt;connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, 16) = 0&lt;br /&gt;gettimeofday({1325590403, 502576}, NULL) = 0&lt;br /&gt;poll([{fd=4, events=POLLOUT}], 1, 0)    = 1 ([{fd=4, revents=POLLOUT}])&lt;br /&gt;send(4, "tl\1\0\0\1\0\0\0\0\0\0\7nowhere\vonlinedomus"..., 41, MSG_NOSIGNAL) = 41&lt;br /&gt;poll([{fd=4, events=POLLIN}], 1, 5000)  = 1 ([{fd=4, revents=POLLIN}])&lt;br /&gt;ioctl(4, FIONREAD, [101])               = 0&lt;br /&gt;recvfrom(4, "tl\201\203\0\1\0\0\0\1\0\0\7nowhere\vonlinedomus"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, [16]) = 101&lt;br /&gt;close(4)                                = 0&lt;br /&gt;[...]&lt;br /&gt;open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 4&lt;br /&gt;[...]&lt;br /&gt;read(4, "127.0.0.1\tpacman1.onlinedomus.ne"..., 4096) = 439&lt;br /&gt;[...]&lt;br /&gt;close(4)                                = 0&lt;br /&gt;[...]&lt;br /&gt;read(3, "Cannot connect to database serve"..., 40) = 40&lt;br /&gt;write(2, "\n", 1)                       = 1&lt;br /&gt;write(2, "  930: Cannot connect to databas"..., 68) = 68&lt;br /&gt;exit_group(-1)                          = ?&lt;br /&gt;cheetah@pacman.onlinedomus.com:fnunes-&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, we should move to the Informix server side. This requires a bit more work and preliminary explanations. To start, we must understand what the engine needs in order to establish the connection. One of those things is to do a reverse name lookup (IP address to hostname). This is not essential, but it's always tried. Informix may need the hostname for trust relation validation and to provide information to the DBA.&lt;/div&gt;&lt;div&gt;As you know, the Informix database engine comprises several operating system processes. From the OS perspective they all look the same (oninit), but every one has a specific role and runs certain engine threads. We can see the threads with:&lt;br /&gt;&lt;pre&gt;panther@pacman.onlinedomus.com:fnunes-&amp;gt; onstat -g ath&lt;br /&gt;&lt;br /&gt;IBM Informix Dynamic Server Version 11.70.UC4 -- On-Line -- Up 00:17:01 -- 411500 Kbytes&lt;br /&gt;&lt;br /&gt;Threads:&lt;br /&gt; tid     tcb      rstcb    prty status                vp-class       name&lt;br /&gt; 2       5583fa38 0        1    IO Idle                 3lio*        lio vp 0&lt;br /&gt; 3       558551f8 0        1    IO Idle                 4pio*        pio vp 0&lt;br /&gt; 4       5586b1f8 0        1    IO Idle                 5aio*        aio vp 0&lt;br /&gt; 5       558811f8 8f59dc0  1    IO Idle                 6msc*        msc vp 0&lt;br /&gt; 6       558af1f8 0        1    IO Idle                 7fifo*       fifo vp 0&lt;br /&gt; 7       558c9590 0        1    IO Idle                 9aio*        aio vp 1&lt;br /&gt; 8       558df3b8 54267018 3    sleeping secs: 1        8cpu         main_loop()&lt;br /&gt; 9       559276f8 0        1    running                10soc*        soctcppoll&lt;br /&gt; 10      5593ed18 0        2    sleeping forever        1cpu*        soctcplst&lt;br /&gt; 11      55927d20 542675fc 1    sleeping secs: 1        8cpu         flush_sub(0)&lt;br /&gt; 12      55988018 54267be0 1    sleeping secs: 1        8cpu         flush_sub(1)&lt;br /&gt; 13      559881f0 542681c4 1    sleeping secs: 1        8cpu         flush_sub(2)&lt;br /&gt; 14      559883c8 542687a8 1    sleeping secs: 1        8cpu         flush_sub(3)&lt;br /&gt; 15      559885a0 54268d8c 1    sleeping secs: 1        8cpu         flush_sub(4)&lt;br /&gt; 16      55988778 54269370 1    sleeping secs: 1        8cpu         flush_sub(5)&lt;br /&gt; 17      55988bf0 54269954 1    sleeping secs: 1        8cpu         flush_sub(6)&lt;br /&gt; 18      559fb468 54269f38 1    sleeping secs: 1        8cpu         flush_sub(7)&lt;br /&gt; 19      559fb640 0        3    IO Idle                 8cpu*        kaio&lt;br /&gt; 20      55ab6018 5426a51c 2    sleeping secs: 1        8cpu         aslogflush&lt;br /&gt; 21      55ab6960 5426ab00 1    sleeping secs: 92       1cpu         btscanner_0&lt;br /&gt; 22      55b6a408 5426b0e4 3    cond wait  ReadAhead    1cpu         readahead_0&lt;br /&gt; 39      55bcd5c8 0        3    IO Idle                 1cpu*        kaio&lt;br /&gt; 40      55bcd7a0 5426bcac 3    sleeping secs: 1        1cpu*        onmode_mon&lt;br /&gt; 41      55d3e148 5426c874 3    sleeping secs: 1        8cpu         periodic&lt;br /&gt; 49      55e80a78 5426da20 1    sleeping secs: 177      1cpu         dbScheduler&lt;br /&gt; 51      55f340f8 5426d43c 1    sleeping forever        1cpu         dbWorker1&lt;br /&gt; 52      55f34d80 5426ce58 1    sleeping forever        8cpu         dbWorker2&lt;br /&gt; 59      562ee228 5426e5e8 1    cond wait  bp_cond      1cpu         bf_priosweep()&lt;br /&gt;&lt;/pre&gt;And the OS processes with:&lt;br /&gt;&lt;pre&gt;panther@pacman.onlinedomus.com:fnunes-&amp;gt; onstat -g glo&lt;br /&gt;&lt;br /&gt;IBM Informix Dynamic Server Version 11.70.UC4 -- On-Line -- Up 00:18:48 -- 411500 Kbytes&lt;br /&gt;&lt;br /&gt;MT global info:&lt;br /&gt;sessions threads  vps      lngspins&lt;br /&gt;0        29       10       3       &lt;br /&gt;&lt;br /&gt;          sched calls     thread switches yield 0   yield n   yield forever&lt;br /&gt;total:    9589515         8992470         597961    14485     4457836  &lt;br /&gt;per sec:  0               0               0         0         0        &lt;br /&gt;&lt;br /&gt;Virtual processor summary:&lt;br /&gt; class       vps       usercpu   syscpu    total   &lt;br /&gt; cpu         2         11.51     94.06     105.57  &lt;br /&gt; aio         2         3.57      75.44     79.01   &lt;br /&gt; lio         1         0.01      0.01      0.02    &lt;br /&gt; pio         1         0.00      0.01      0.01    &lt;br /&gt; adm         1         0.01      0.15      0.16    &lt;br /&gt; soc         1         0.04      0.15      0.19    &lt;br /&gt; msc         1         0.00      0.01      0.01    &lt;br /&gt; fifo        1         0.00      0.01      0.01    &lt;br /&gt; total       10        15.14     169.84    184.98  &lt;br /&gt;&lt;br /&gt;Individual virtual processors:&lt;br /&gt; vp    pid       class       usercpu   syscpu    total     Thread    Eff  &lt;br /&gt; 1     29395     cpu         5.63      46.80     52.43     66.41     78%&lt;br /&gt; 2     29398     adm         0.01      0.15      0.16      0.00       0%&lt;br /&gt; 3     29399     lio         0.01      0.01      0.02      0.02     100%&lt;br /&gt; 4     29400     pio         0.00      0.01      0.01      0.01     100%&lt;br /&gt; 5     29401     aio         3.29      74.30     77.59     77.59    100%&lt;br /&gt; 6     29402     msc         0.00      0.01      0.01      0.03      31%&lt;br /&gt; 7     29403     fifo        0.00      0.01      0.01      0.01     100%&lt;br /&gt; 8     29404     cpu         5.88      47.26     53.14     64.45     82%&lt;br /&gt; 9     29405     aio         0.28      1.14      1.42      1.42     100%&lt;br /&gt; 10    29406     soc         0.04      0.15      0.19      NA         NA&lt;br /&gt;                 tot         15.14     169.84    184.98&lt;br /&gt;&lt;/pre&gt;The threads that are listening on the engine TCP ports are the poll threads (soctcppoll) running on SOC class (this depends on the NETTYPE parameter). When a new request is received by them they call the listener threads (soctcplst) running on the cpu class to initiate the authentication process. Parts of this task are run by the MSC virtual processor. As we can see in the last output this has the PID 29402. So, in order to see what happens I'll trace that OS process. For reasons that I'll explain later, I will turn off the NS_CACHE feature (Informix 11.7) and I will restart the engine. So, for the first connection attempt we get (some parts cut off):&lt;br /&gt;&lt;pre&gt;1      0.000000 semop(753664, {{5, -1, 0}}, 1) = 0&lt;br /&gt;2      7.009868 socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3&lt;br /&gt;3      0.000107 connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)&lt;br /&gt;4      0.000242 close(3)                  = 0&lt;br /&gt;5      0.000060 socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3&lt;br /&gt;6      0.000063 connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)&lt;br /&gt;7      0.000095 close(3)                  = 0&lt;br /&gt;8      [...]&lt;br /&gt;9      0.000000 open("/etc/resolv.conf", O_RDONLY) = 3&lt;br /&gt;10     0.000000 fstat64(3, {st_mode=S_IFREG|0644, st_size=55, ...}) = 0&lt;br /&gt;11     0.000000 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xab4000&lt;br /&gt;12     0.000000 read(3, "# Generated by NetworkManager\nna"..., 4096) = 55&lt;br /&gt;13     0.000926 read(3, "", 4096)         = 0&lt;br /&gt;14     0.000050 close(3)                  = 0&lt;br /&gt;15     [...]&lt;br /&gt;16     0.000057 futex(0x29ab44, FUTEX_WAKE_PRIVATE, 2147483647) = 0&lt;br /&gt;17     0.000256 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3&lt;br /&gt;18     0.000089 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, 16) = 0&lt;br /&gt;19     0.000107 gettimeofday({1325605320, 167025}, NULL) = 0&lt;br /&gt;20     0.000072 poll([{fd=3, events=POLLOUT}], 1, 0) = 1 ([{fd=3, revents=POLLOUT}])&lt;br /&gt;21     0.000083 send(3, "\363\337\1\0\0\1\0\0\0\0\0\0\0011\003112\003168\003192\7in-ad"..., 44, MSG_NOSIGNAL) = 44&lt;br /&gt;22     0.000322 poll([{fd=3, events=POLLIN}], 1, 5000) = 1 ([{fd=3, revents=POLLIN}])&lt;br /&gt;23     2.061369 ioctl(3, FIONREAD, [121]) = 0&lt;br /&gt;24     0.000111 recvfrom(3, "\363\337\201\203\0\1\0\0\0\1\0\0\0011\003112\003168\003192\7in-ad"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, [16]) = 121&lt;br /&gt;25     0.000155 close(3)                  = 0&lt;br /&gt;26     0.000090 open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3&lt;br /&gt;27     0.000377 fstat64(3, {st_mode=S_IFREG|0644, st_size=439, ...}) = 0&lt;br /&gt;28     0.000089 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf22000&lt;br /&gt;29     0.000057 read(3, "127.0.0.1\tpacman1.onlinedomus.ne"..., 4096) = 439&lt;br /&gt;30     0.000130 close(3)                  = 0&lt;br /&gt;31     [...]&lt;br /&gt;32     0.000072 semop(753664, {{7, 1, 0}}, 1) = 0&lt;br /&gt;33     0.000069 semop(753664, {{7, 1, 0}}, 1) = 0&lt;br /&gt;34     0.007558 semop(753664, {{5, -1, 0}}, 1 &lt;unfinished ...=""&gt;&lt;br /&gt;&lt;/unfinished&gt;&lt;/pre&gt;&lt;br /&gt;Please note that for clarity I added line numbers and time differences between each call (this will be important later). Let's explain this.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;On line 1) we have a semop() which is the way MSC VP stays idle. That was before the connection attempt.&lt;/li&gt;&lt;li&gt;7 seconds later it tries to "talk" with nscd daemon (lines 2-8). This is kind of a Linux specific mechanism that I'm not running. Then accesses the /etc/nsswitch.conf.&amp;nbsp; Just keep in memory that it did this on the first attempt&lt;/li&gt;&lt;li&gt;Then it accesses /etc/resolv.conf (lines 9-15) and finds the nameserver address&lt;/li&gt;&lt;li&gt;On lines 16-25 it talks to the DNS server (192.168.112.2) and asks for the reverse name of the connecting IP address&lt;/li&gt;&lt;li&gt;Since the answer is inconclusive, it goes to /etc/hosts (lines 26-31)&lt;/li&gt;&lt;li&gt;I have cut the remaining part which is related to the authentication (opening the /etc/passwd, /etc/group, /etc/shadow etc.).&lt;/li&gt;&lt;li&gt;Finally it returns to the normal idle state&lt;/li&gt;&lt;/ul&gt;A few important points about this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;div&gt;It all happened pretty quick (values are in seconds)&lt;/div&gt;&lt;/li&gt;&lt;li&gt;We don't see the gethostbyaddr() call. This is not a "system call" for strace. So we see the lower level calls, but not the gethostbyaddr() function. We can catch it by attaching a debugger to the same process. This is important because usually it's hard to discuss this issues with the network and OS administrators because they tend to assume all this is done by Informix. It isn't! Informix just calls gethostbyaddr() (or equivalent fiunctions)&lt;/li&gt;&lt;/ol&gt;Now, let's see the same for the second attempt. We would expect it to be the same, but it isn't. I have cut exactly the same parts:&lt;br /&gt;&lt;pre&gt;1      0.000000 semop(753664, {{5, -1, 0}}, 1) = 0&lt;br /&gt;2      6.452154 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3&lt;br /&gt;3      0.000099 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, 16) = 0&lt;br /&gt;4      0.008816 gettimeofday({1325605445, 534040}, NULL) = 0&lt;br /&gt;5      0.000089 poll([{fd=3, events=POLLOUT}], 1, 0) = 1 ([{fd=3, revents=POLLOUT}])&lt;br /&gt;6      0.000100 send(3, "\233\t\1\0\0\1\0\0\0\0\0\0\0011\003112\003168\003192\7in-ad"..., 44, MSG_NOSIGNAL) = 44&lt;br /&gt;7      0.000417 poll([{fd=3, events=POLLIN}], 1, 5000) = 1 ([{fd=3, revents=POLLIN}])&lt;br /&gt;8      2.089726 ioctl(3, FIONREAD, [121]) = 0&lt;br /&gt;9      0.000118 recvfrom(3, "\233\t\201\203\0\1\0\0\0\1\0\0\0011\003112\003168\003192\7in-ad"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, [16]) = 121&lt;br /&gt;10     0.000132 close(3)                  = 0&lt;br /&gt;11     0.000069 open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3&lt;br /&gt;12     0.000102 fstat64(3, {st_mode=S_IFREG|0644, st_size=439, ...}) = 0&lt;br /&gt;13     0.000092 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xe1f000&lt;br /&gt;14     0.000064 read(3, "127.0.0.1\tpacman1.onlinedomus.ne"..., 4096) = 439&lt;br /&gt;15     0.000099 close(3)                  = 0&lt;br /&gt;16     [...]&lt;br /&gt;17     0.000068 semop(753664, {{0, 1, 0}}, 1) = 0&lt;br /&gt;18     0.000096 semop(753664, {{0, 1, 0}}, 1) = 0&lt;br /&gt;19     0.000076 semop(753664, {{5, -1, 0}}, 1 &lt;unfinished ...=""&gt;&lt;br /&gt;&lt;/unfinished&gt;&lt;/pre&gt;&lt;br /&gt;So, again the analysis:&lt;br /&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;The first part accessing the nscd daemon, the /etc/nsswitch.conf and the /etc/resolv.conf is completely gone.&lt;br /&gt;As you can see it starts by connecting to the DNS.&lt;/li&gt;&lt;li&gt;Then it reads the files (/etc/hosts)&lt;/li&gt;&lt;li&gt;Then I cut the authentication part as before&lt;/li&gt;&lt;li&gt;Finally it returns to the idle state&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;The important point to note here is that the first attempt is different from the others. And again, Informix just calls gethostbyaddr()... just the same call each time. Well... to be correct the function we call may depend on the platform. As I mentioned earlier, only by using a debugger we can find the gethostbyaddr() call. I've done it and here is the result:&lt;/div&gt;&lt;pre&gt;(gdb) break connect&lt;br /&gt;Breakpoint 1 at 0x95f640&lt;br /&gt;(gdb) continue&lt;br /&gt;Continuing.&lt;br /&gt;&lt;br /&gt;Breakpoint 1, 0x0095f640 in connect () from /lib/libpthread.so.0&lt;br /&gt;(gdb) where&lt;br /&gt;#0  0x0095f640 in connect () from /lib/libpthread.so.0&lt;br /&gt;#1  0x00aec9ab in reopen () from /lib/libresolv.so.2&lt;br /&gt;#2  0x00aee542 in __libc_res_nsend () from /lib/libresolv.so.2&lt;br /&gt;#3  0x00aeb24e in __libc_res_nquery () from /lib/libresolv.so.2&lt;br /&gt;#4  0x002b6dc7 in _nss_dns_gethostbyaddr2_r () from /lib/libnss_dns.so.2&lt;br /&gt;#5  0x002b6f1a in _nss_dns_gethostbyaddr_r () from /lib/libnss_dns.so.2&lt;br /&gt;#6  0x0020890b in gethostbyaddr_r@@GLIBC_2.1.2 () from /lib/libc.so.6&lt;br /&gt;#7  0x00211f77 in getnameinfo () from /lib/libc.so.6&lt;br /&gt;#8  0x08c0e664 in ifx_getipnodebyaddr ()&lt;br /&gt;#9  0x08c0f79c in ifx_gethostbyaddr ()&lt;br /&gt;#10 0x08c0f8a2 in __osgethostbyaddr ()&lt;br /&gt;#11 0x08b0c055 in aio_workon ()&lt;br /&gt;#12 0x08b0c9c3 in aiothread ()&lt;br /&gt;#13 0x08b0dbcb in iothread ()&lt;br /&gt;#14 0x08b00762 in startup ()&lt;br /&gt;#15 0x558749e8 in ?? ()&lt;br /&gt;#16 0x00000000 in ?? ()&lt;br /&gt;(gdb)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;As you can see I've setup a breakpoint for connect(). Then I "continue" the execution and I try the connection. gdb stops the program at the breakpoint and I get the stack trace (read bottom up).&lt;br /&gt;So, it shows we call getnameinfo() which in turn calls gethostbyaddr_r() etc. All this belongs to the system libraries, not to Informix code.&lt;br /&gt;&lt;br /&gt;There are two additional considerations we need to be aware. First, the Informix MSC VP processes it's requests in a serial manner. For each connection it asks what it needs from the DNS servers and/or files and makes the authentication. By default we only have one MSC VP... so if one request gets stuck.... yes... the following connections will suffer delays. This delays can be a fraction of second, or a few seconds, but on some systems I've seen tens (heard about hundreds) of connections per second, so even a few seconds will have large impact.&lt;br /&gt;The second consideration relates to the differences between the first call and the subsequent ones. As we've seen above, on the first call the process checks the configuration (the /etc/nsswitch.conf and /etc/resolv.conf files). After that first check it does not do that anymore. And this causes a problem. Again this is the behavior of the system functions (but not necessarily the end of the story....)&lt;br /&gt;&lt;br /&gt;So, hopefully I was able to explain how Informix interacts with the DNS system. The important technical deep dive should be over. We'll proceed to the implications. It's important you understand all the above before proceeding to the next paragraphs.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;What problems can we face?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Above I've tried to show you how things work when everything is ok. But what happens when something is wrong? Let's see what can go wrong first and then the implications. I'll also try to explain who to blame (and again the disclaimer...). The purpose of course is not to finger point, but knowing where the problem lies is the first step to solve it.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;u&gt;Network problems prevent the connection to the DNS servers&lt;/u&gt;&lt;br /&gt;If this happens, the requests sent by the MSC VP will have to timeout (typically a few seconds) before the OS call returns. This delay will cause all the other connection requests to stay on hold (assuming we just have one MSC VP). If the network problems persist, it really doesn't matter how many MSC VPs we have, since they'll all get stuck and all our connection attempts will suffer delays&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;The DNS server dies, is stopped, or is extremely slow&lt;/u&gt;&lt;br /&gt;The effect of this is very similar to the previous. Anything that causes delays in the DNS requests will potentially cause delays in the engine connections. Note that this can be a generic issue that affects all the requests, or it can affect only some requests. Due to the hierarchical and distributed nature of the DNS system, it may be able to answer most requests, but get slow or event try to "talk" to an unavailable server for some specific names or IP addresses. Needless to say this makes the debug of these problems very difficult to do&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;Something goes wrong with the DSN system. The reverse lookups fail and this affects the trusted connections.&lt;/u&gt;&lt;br /&gt;You start to see -956 errors in the online.log and -951 is sent to the client side&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;You need to change your DNS servers&lt;/u&gt;&lt;br /&gt;Then you''ll need to restart Informix. This is a nasty problem caused by Informix (we could do better). As I mentioned above, the OS function calls keep the configurations in memory for efficiency reasons (it would be very "expensive" to re-read that for each call). So, the problem in how it works is that if you want to change the policy (/etc/nsswitch.conf) or the DNS servers (/etc/resolv.conf), the Informix processes will not pick up the change. I can assure you that Informix is not the only daemon that suffers with this. The first time I had a similar problem with this, I noticed that for example sendmail was also suffering... (trying to talk with the older servers)&lt;/li&gt;&lt;/ol&gt;From the above problems it's easy to understand that the three first are not Informix's fault. When a customer decides (presumably because it needs) to use a DNS infra-structure people have to understand that it automatically becomes a critical component of the system. Any problems in it will cause problems in the layers above, specifically in the Informix system.&lt;br /&gt;And that leaves us with the forth problem. I wrote before and it's true that this is how the functions work (and I'll show this in action), so why do I write that this is Informix's fault? Well, because there is a way to handle this. There is another system call named res_init() that does precisely what we need. From the Linux manual, I quote:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;i&gt;&lt;b&gt;The  res_init()  function  reads the configuration files&lt;/b&gt; (see resolv.conf(5)) to get the default domain name, search order and name server address(es).&lt;br /&gt;If no server is given, the local host is tried.  If no domain is given, that associated with the local host is used.  It can  be  overridden  with  the environment variable LOCALDOMAIN.  &lt;b&gt;res_init() is normally executed by the first call to one of the other functions&lt;/b&gt;&lt;/i&gt;.&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;So, my point is that Informix should provide a way by which the DBA would request all the MSC VPs to call this function. This would refresh the information that is cached by the first call.&lt;br /&gt;In fact IBM has a pending feature request about this. I really hope this could be implemented in a future release. This is something that we may live without for years, but if you need it, it really would make a difference&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Knowing if you have the problem&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;How do we know that we have a problem in DNS and that Informix is being impacted? Typically you'll get some sort of complain from the Informix clients. Usually something like "the database is terribly slow", or "it takes a long time to connect", or eventually you'll have connections refused with server side error -956 (not trusted). In extreme situations you can have weird errors in the online.log (-25xxx ). In all these situations you'll notice that the already existing sessions are working smoothly.&lt;br /&gt;But in order to be sure you may follow two paths:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The most simple is to run a "netstat -a" command on the database server. This shows all the TCP/UDP connections to and from the machine. By default it will go through all the socket connections and will try to reverse lookup the respective IP addresses. If you're having problems you'll see that the netstat output will be very slow or at least with some "bumps". But for this simple tests to provide meaningful conclusions, you must be sure that the system is still configured to use the same configuration (/etc/nsswitch.conf and /etc/resolv.conf) that was in place when the Informix engine was started. Otherwise you'll not be comparing apples to apples&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The most complex is to run a truss or strace command against the MSC VP with timings. This can show slow response from the calls to the DNS hosts. Be aware that running truss/strace requires root privileges and that even if everything is running fine, it will cause delays on systems with a large number of connects per second&lt;/li&gt;&lt;/ol&gt;I wrote earlier that I could demonstrate the facts presented here without using Informix. For that I created a simple program (line numbers included):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;1  #include &amp;lt;sys/time.h&amp;gt;&lt;br /&gt;2  #include &amp;lt;netdb.h&amp;gt;&lt;br /&gt;3  #include &amp;lt;resolv.h&amp;gt;&lt;br /&gt;4  #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;5  #include &amp;lt;string.h&amp;gt;&lt;br /&gt;6  &lt;br /&gt;7  int main(int argc, char **argv)&lt;br /&gt;8  {&lt;br /&gt;9    struct hostent *hp;&lt;br /&gt;10    in_addr_t data;&lt;br /&gt;11    char buff[100];&lt;br /&gt;12    struct timeval ts_initial, ts_final;&lt;br /&gt;13  &lt;br /&gt;14    if (argc == 2) {&lt;br /&gt;15      strcpy(buff,argv[1]);&lt;br /&gt;16    }&lt;br /&gt;17    else {&lt;br /&gt;18      printf("Introduce an IP address: ");&lt;br /&gt;19      if (fscanf(stdin,"%s", buff) == EOF)&lt;br /&gt;20        exit(0);&lt;br /&gt;21    }&lt;br /&gt;22  &lt;br /&gt;23    while (1 == 1) {&lt;br /&gt;24      data = inet_addr(buff);&lt;br /&gt;25      gettimeofday(&amp;amp;ts_initial, NULL);&lt;br /&gt;26      hp = gethostbyaddr(&amp;amp;data, 4, AF_INET);&lt;br /&gt;27      gettimeofday(&amp;amp;ts_final, NULL);&lt;br /&gt;28  &lt;br /&gt;29      if (hp == NULL) {&lt;br /&gt;30        printf("Unknown host (%s). Took %f seconds\n", buff, (double)((ts_final.tv_sec * 1000000 + ts_final.tv_usec) - (ts_initial.tv_sec * 1000000 + ts_initial.tv_usec))/1000000);&lt;br /&gt;31      }&lt;br /&gt;32      else {&lt;br /&gt;33        printf("Name (%s): %s Took %f seconds\n", buff, hp-&amp;gt;h_name, (double)((ts_final.tv_sec * 1000000 + ts_final.tv_usec) - (ts_initial.tv_sec * 1000000 + ts_initial.tv_usec))/1000000);&lt;br /&gt;34      }&lt;br /&gt;35      printf("Next: ");&lt;br /&gt;36      if (fscanf(stdin,"%s", buff) == EOF)&lt;br /&gt;37        exit(0);&lt;br /&gt;38      if ( strncmp("refresh", buff, 7) == 0 )&lt;br /&gt;39      {&lt;br /&gt;40         res_init();&lt;br /&gt;41         printf("Called res_init()\n");&lt;br /&gt;42         printf("Next: ");&lt;br /&gt;43         if (fscanf(stdin,"%s", buff) == EOF)&lt;br /&gt;44           exit(0);&lt;br /&gt;45      }&lt;br /&gt;46    }&lt;br /&gt;47  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is basically a loop that reads an IP address (which are not validated, so it's easily breakable), and runs gethostbyaddr() on it. If the "ip" provided is "refresh" then it calls res_init(). It reports the information returned by the resolver subsystem and the time it took. You can use it interactively or redirect a file with one IP address per line.&lt;br /&gt;&lt;br /&gt;I'll run it interactively with tracing in order to show the effect of calling res_init(). I have "hosts: dns,files" in /etc/nsswitch.conf and 192.168.112.2 on /etc/resolv.conf. This file also contains options do define the timeout to 2 seconds. So I call this with:&lt;br /&gt;&lt;pre&gt;cheetah@pacman1.onlinedomus.net:fnunes-&amp;gt; strace -r -o test_resolv.trace ./test_resolv&lt;br /&gt;Introduce an IP address: 1.1.1.1&lt;br /&gt;Unknown host (1.1.1.1). Took 2.010235 seconds&lt;br /&gt;Next: 1.1.1.2&lt;br /&gt;Unknown host (1.1.1.2). Took 2.003324 seconds&lt;br /&gt;Next: refresh&lt;br /&gt;Called res_init()&lt;br /&gt;Next: 1.1.1.3&lt;br /&gt;Unknown host (1.1.1.3). Took 2.004002 seconds&lt;br /&gt;Next: ^C&lt;br /&gt;&lt;/pre&gt;Before I introduce "refresh" I change the DNS nameserver in /etc/resolv.conf from 192.168.112.2 to 192.168.112.5.&lt;br /&gt;The trace is this (line numbers and timmings added):&lt;br /&gt;&lt;pre&gt;1        [...]&lt;br /&gt;2        0.000000 write(1, "Introduce an IP address: ", 25) = 25&lt;br /&gt;3        0.000000 read(0, "1.1.1.1\n", 1024) = 8&lt;br /&gt;4        3.055699 gettimeofday({1325865284, 104186}, NULL) = 0&lt;br /&gt;5        [...]&lt;br /&gt;6        0.000160 socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3&lt;br /&gt;7        0.000099 connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ECONNREFUSED (Connection refused)&lt;br /&gt;8        0.000128 close(3)                  = 0&lt;br /&gt;9        0.000053 socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3&lt;br /&gt;10       0.000123 connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ECONNREFUSED (Connection refused)&lt;br /&gt;11       0.000122 close(3)                  = 0&lt;br /&gt;12       0.000095 open("/etc/nsswitch.conf", O_RDONLY) = 3&lt;br /&gt;13       0.000108 fstat64(3, {st_mode=S_IFREG|0644, st_size=1803, ...}) = 0&lt;br /&gt;14       0.000101 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7843000&lt;br /&gt;15       0.000057 read(3, "#\n# /etc/nsswitch.conf\n#\n# An ex"..., 4096) = 1803&lt;br /&gt;16       0.000001 read(3, "", 4096)         = 0&lt;br /&gt;17       0.000000 close(3)                  = 0&lt;br /&gt;18       [...]&lt;br /&gt;19       0.000055 open("/etc/resolv.conf", O_RDONLY) = 3&lt;br /&gt;20       0.000072 fstat64(3, {st_mode=S_IFREG|0644, st_size=118, ...}) = 0&lt;br /&gt;21       0.000095 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7843000&lt;br /&gt;22       0.000050 read(3, "# Generated by NetworkManager\nna"..., 4096) = 118&lt;br /&gt;23       0.000086 read(3, "", 4096)         = 0&lt;br /&gt;24       0.000046 close(3)                  = 0&lt;br /&gt;25       [...]&lt;br /&gt;26       0.000173 open("/etc/host.conf", O_RDONLY) = 3&lt;br /&gt;27       0.000068 fstat64(3, {st_mode=S_IFREG|0644, st_size=26, ...}) = 0&lt;br /&gt;28       0.000081 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7843000&lt;br /&gt;29       0.000179 read(3, "multi on\norder hosts,bind\n", 4096) = 26&lt;br /&gt;30       0.000083 read(3, "", 4096)         = 0&lt;br /&gt;31       0.000048 close(3)                  = 0&lt;br /&gt;32       0.000049 munmap(0xb7843000, 4096)  = 0&lt;br /&gt;33       0.000160 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3&lt;br /&gt;34       0.000075 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, 16) = 0&lt;br /&gt;35       0.000640 gettimeofday({1325865284, 108850}, NULL) = 0&lt;br /&gt;36       0.000062 poll([{fd=3, events=POLLOUT}], 1, 0) = 1 ([{fd=3, revents=POLLOUT}])&lt;br /&gt;37       0.000094 send(3, "r\363\1\0\0\1\0\0\0\0\0\0\0011\0011\0011\0011\7in-addr\4arp"..., 38, MSG_NOSIGNAL) = 38&lt;br /&gt;38       0.000889 poll([{fd=3, events=POLLIN}], 1, 2000) = 0 (Timeout)&lt;br /&gt;39       2.003373 close(3)                  = 0&lt;br /&gt;40       0.000109 open("/etc/ld.so.cache", O_RDONLY) = 3&lt;br /&gt;41       0.000078 fstat64(3, {st_mode=S_IFREG|0644, st_size=72238, ...}) = 0&lt;br /&gt;42       0.000093 mmap2(NULL, 72238, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7821000&lt;br /&gt;43       0.000054 close(3)                  = 0&lt;br /&gt;44       [...]&lt;br /&gt;45       0.000105 open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3&lt;br /&gt;46       0.000097 fcntl64(3, F_GETFD)       = 0x1 (flags FD_CLOEXEC)&lt;br /&gt;47       0.000065 fstat64(3, {st_mode=S_IFREG|0644, st_size=438, ...}) = 0&lt;br /&gt;48       0.000053 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7843000&lt;br /&gt;49       0.000035 read(3, "127.0.0.1\tpacman.onlinedomus.net"..., 4096) = 438&lt;br /&gt;50       0.000137 read(3, "", 4096)         = 0&lt;br /&gt;51       0.000130 close(3)                  = 0&lt;br /&gt;52       [...]&lt;br /&gt;53       0.000101 write(1, "Unknown host (1.1.1.1). Took 2.0"..., 46) = 46&lt;br /&gt;54       0.000071 write(1, "Next: ", 6)     = 6&lt;br /&gt;55       0.000267 read(0, "1.1.1.2\n", 1024) = 8&lt;br /&gt;56       0.000071 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3&lt;br /&gt;57       0.000077 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, 16) = 0&lt;br /&gt;58       0.000049 poll([{fd=3, events=POLLOUT}], 1, 0) = 1 ([{fd=3, revents=POLLOUT}])&lt;br /&gt;59       0.000063 send(3, ":\243\1\0\0\1\0\0\0\0\0\0\0012\0011\0011\0011\7in-addr\4arp"..., 38, MSG_NOSIGNAL) = 38&lt;br /&gt;60       0.000152 poll([{fd=3, events=POLLIN}], 1, 2000) = 0 (Timeout)&lt;br /&gt;61       2.002550 close(3)                  = 0&lt;br /&gt;62       0.000088 open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3&lt;br /&gt;63       0.000077 fstat64(3, {st_mode=S_IFREG|0644, st_size=438, ...}) = 0&lt;br /&gt;64       0.000092 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7843000&lt;br /&gt;65       0.000057 read(3, "127.0.0.1\tpacman.onlinedomus.net"..., 4096) = 438&lt;br /&gt;66       0.000110 read(3, "", 4096)         = 0&lt;br /&gt;67       0.000049 close(3)                  = 0&lt;br /&gt;68       [...]&lt;br /&gt;69       0.000060 write(1, "Unknown host (1.1.1.2). Took 2.0"..., 46) = 46&lt;br /&gt;70       0.000076 write(1, "Next: ", 6)     = 6&lt;br /&gt;71       0.000253 read(0, "refresh\n", 1024) = 8&lt;br /&gt;72      17.639011 open("/etc/resolv.conf", O_RDONLY) = 3&lt;br /&gt;73       0.000088 fstat64(3, {st_mode=S_IFREG|0644, st_size=118, ...}) = 0&lt;br /&gt;74       0.000087 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7843000&lt;br /&gt;75       0.000052 read(3, "# Generated by NetworkManager\n#n"..., 4096) = 118&lt;br /&gt;76       0.000108 read(3, "", 4096)         = 0&lt;br /&gt;77       0.000047 close(3)                  = 0&lt;br /&gt;78       0.000048 munmap(0xb7843000, 4096)  = 0&lt;br /&gt;79       0.000065 write(1, "Called res_init()\n", 18) = 18&lt;br /&gt;80       0.000060 write(1, "Next: ", 6)     = 6&lt;br /&gt;81       0.000051 read(0, "1.1.1.3\n", 1024) = 8&lt;br /&gt;82       3.595382 gettimeofday({1325865312, 174933}, NULL) = 0&lt;br /&gt;83       0.000075 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3&lt;br /&gt;84       0.000078 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.5")}, 16) = 0&lt;br /&gt;85       0.000266 gettimeofday({1325865312, 175350}, NULL) = 0&lt;br /&gt;86       0.000052 poll([{fd=3, events=POLLOUT}], 1, 0) = 1 ([{fd=3, revents=POLLOUT}])&lt;br /&gt;87       0.000069 send(3, "\321\234\1\0\0\1\0\0\0\0\0\0\0013\0011\0011\0011\7in-addr\4arp"..., 38, MSG_NOSIGNAL) = 38&lt;br /&gt;88       0.000085 poll([{fd=3, events=POLLIN}], 1, 2000) = 0 (Timeout)&lt;br /&gt;89       2.002271 close(3)                  = 0&lt;br /&gt;90       0.000081 open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3&lt;br /&gt;91       0.000076 fstat64(3, {st_mode=S_IFREG|0644, st_size=438, ...}) = 0&lt;br /&gt;92       0.000087 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7843000&lt;br /&gt;93       0.000054 read(3, "127.0.0.1\tpacman.onlinedomus.net"..., 4096) = 438&lt;br /&gt;94       0.000091 read(3, "", 4096)         = 0&lt;br /&gt;95       0.000047 close(3)                  = 0&lt;br /&gt;96       0.000048 munmap(0xb7843000, 4096)  = 0&lt;br /&gt;97       0.000062 gettimeofday({1325865314, 178373}, NULL) = 0&lt;br /&gt;98       0.000058 write(1, "Unknown host (1.1.1.3). Took 2.0"..., 46) = 46&lt;br /&gt;99       0.000072 write(1, "Next: ", 6)     = 6&lt;br /&gt;100      0.000053 read(0, 0xb7844000, 1024) = ? ERESTARTSYS (To be restarted)&lt;br /&gt;101      0.918564 --- SIGINT (Interrupt) @ 0 (0) ---&lt;br /&gt;102      0.000931 +++ killed by SIGINT +++&lt;/pre&gt;&lt;br /&gt;And the explanation:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;Lines 1-5 the program starts and asks for the IP address. 1.1.1.1 is provided&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Lines 6-18 it tries to contact the nscd (Linux caching daemon) and then opens and reads /etc/nsswitch.conf&lt;/li&gt;&lt;li&gt;Lines 19-31 opens the other two configuration files (/etc/resolv.conf and /etc/host.conf)&lt;/li&gt;&lt;li&gt;Lines 33-44 contacts the DNS server on 192.168.112.2 (timeout = 2s)&lt;/li&gt;&lt;li&gt;Lines 45-52 reads /etc/hosts and prints the result (Unknown host)&lt;/li&gt;&lt;li&gt;Lines 53-68 is just the same, but doesn't read the config files since it's not the first time&lt;/li&gt;&lt;li&gt;Lines 69-79 I insert "refresh" and it calls res_init() and re-reads /etc/resolv.conf. Meanwhile, just before that I changed the /etc/resolv.conf and put 192.168.112.5&lt;/li&gt;&lt;li&gt;Lines 80-99 I insert another IP address (1.1.1.3) and it goes to the new DNS server (192.168.112.5). Failing to get a proper answer re-reads the /etc/hosts.&lt;/li&gt;&lt;li&gt;Lines 100-102 it was asking for another IP address and I pressed Control+C&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt;Hacking it just for fun!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Please don't try this at home!.. Really, the following is something risky, not supported, and for learning purposes only. I argued above that calling res_init() would allow you to change the DNS servers without restarting Informix. Let's prove it!&lt;br /&gt;Again I traced a connection, looking at MSC VP. I get this:&lt;br /&gt;&lt;pre&gt;socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3&lt;br /&gt;connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, 16) = 0&lt;br /&gt;gettimeofday({1326038028, 174740}, NULL) = 0&lt;br /&gt;poll([{fd=3, events=POLLOUT}], 1, 0)    = 1 ([{fd=3, revents=POLLOUT}])&lt;br /&gt;send(3, "+\316\1\0\0\1\0\0\0\0\0\0\0011\003112\003168\003192\7in-ad"..., 44, MSG_NOSIGNAL) = 44&lt;br /&gt;poll([{fd=3, events=POLLIN}], 1, 2000)  = 0 (Timeout)&lt;br /&gt;close(3)                                = 0&lt;br /&gt;open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 3&lt;br /&gt;fstat64(3, {st_mode=S_IFREG|0644, st_size=438, ...}) = 0&lt;br /&gt;mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x12f000&lt;br /&gt;read(3, "127.0.0.1\tpacman.onlinedomus.net"..., 4096) = 438&lt;br /&gt;close3)&lt;br /&gt;&lt;/pre&gt;It is connecting to 192.168.112.2, which is what I have on /etc/resolv.conf. If I change that on the file to 192.168.112.5 and try to connect again, the same thing happens (it's not aware of the change). But now, without further changes in the file I run a debugger against the MSC VP process:&lt;br /&gt;&lt;pre&gt;[root@pacman tmp]# gdb -p 4649&lt;br /&gt;GNU gdb (GDB) Fedora (7.1-18.fc13)&lt;br /&gt;Copyright (C) 2010 Free Software Foundation, Inc.&lt;br /&gt;License GPLv3+: GNU GPL version 3 or later &lt;http: gnu.org="" gpl.html="" licenses=""&gt;&lt;br /&gt;This is free software: you are free to change and redistribute it.&lt;br /&gt;There is NO WARRANTY, to the extent permitted by law.  Type "show copying"&lt;br /&gt;and "show warranty" for details.&lt;br /&gt;This GDB was configured as "i686-redhat-linux-gnu".&lt;br /&gt;For bug reporting instructions, please see:&lt;br /&gt;&amp;lt;http: bugs="" gdb="" software="" www.gnu.org=""&amp;gt;.&lt;br /&gt;Attaching to process 4649&lt;br /&gt;Reading symbols from /usr/informix/srvr1170uc4/bin/oninit...(no debugging symbols found)...done.&lt;/http:&gt;&lt;br /&gt;[...]&lt;br /&gt;(gdb) call __res_init()&lt;br /&gt;$1 = 0&lt;br /&gt;(gdb) detach&lt;br /&gt;Detaching from program: /usr/informix/srvr1170uc4/bin/oninit, process 4649&lt;br /&gt;(gdb) quit&lt;br /&gt;[root@pacman tmp]#&lt;br /&gt;&lt;/pre&gt;And I "call" the __res_init() function which I checked to be defined in the libc.so code. Let's trace another connection now:&lt;br /&gt;&lt;pre&gt;socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3&lt;br /&gt;connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.5")}, 16) = 0&lt;br /&gt;gettimeofday({1326038409, 784712}, NULL) = 0&lt;br /&gt;poll([{fd=3, events=POLLOUT}], 1, 0)    = 1 ([{fd=3, revents=POLLOUT}])&lt;br /&gt;send(3, "\364K\1\0\0\1\0\0\0\0\0\0\0011\003112\003168\003192\7in-ad"..., 44, MSG_NOSIGNAL) = 44&lt;br /&gt;poll([{fd=3, events=POLLIN}], 1, 2000)  = 0 (Timeout)&lt;br /&gt;close(3)                                = 0&lt;br /&gt;open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 3&lt;br /&gt;fstat64(3, {st_mode=S_IFREG|0644, st_size=438, ...}) = 0&lt;br /&gt;mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x12f000&lt;br /&gt;read(3, "127.0.0.1\tpacman.onlinedomus.net"..., 4096) = 438&lt;br /&gt;close(3)&lt;br /&gt;&lt;/pre&gt;Ups! Hacked!... Of course this is not supported. Don't try this on real servers. It just serves the purpose of proving a point.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Conclusions&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What I tried to demonstrate in this article is how Informix interacts with the DNS system, if you configure DNS in your environment. I hope that I made clear that once DNS is in place it takes a very important role in the connection process. So much that a bad function in DNS will have major impact in the database system. There are a few points that are Informix responsibility that can contribute to the impact. In particular:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The fact that the reverse DNS requests are made by the MSC VP(s) can generate delays in requests that would work ok, just because a previous one has a problem. Having more than one MSC VP can greatly alleviate this, but may not solve it&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The fact that Informix doesn't establish timeouts to the gethostbyname() calls - or equivalent - can also lead to unnecessary delays. But note that the functions signatures don't have any way to ask for this, so an alarm would have to be setup, so that the process would receive a signal and then check if it was still waiting on the function. This would cause additional overhead, that would not make sense specially because the timeouts are possible to configure in the generic DNS configuration&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The fact that the functions called, cache the configuration details, allied to the fact that Informix has no way to clear the cache, means that a change in the DNS addresses will require a stop in the database system. There is a feature request to allow this. I'd love to see this implemented.&lt;/li&gt;&lt;/ol&gt;On the other hand, Informix 11.7 introduced a great feature to ease all this. With the NS_CACHE parameter we can configure the cache times for several systems (DNS, users/passwords, services...). This can reduce to a minimum the number of requests. Of course, as with any other caching mechanism the risk is to have stalled entries. But we can clear any of the caches by using "onmode -wm NS_CACHE=..." and using a timeout of zero. This would be a great place to call res_init() by the way...&lt;br /&gt;&lt;br /&gt;To roundup the article I'd like to mention a few best practices:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Use Informix 11.7 if you can, so that you can take advantage of the caching. Your DNS servers and DNS admins will appreciate it if you have high connection rates&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Consider including "files" in the /etc/nsswitch.conf configuration. Some people consider this a bad idea, because it keeps the /etc/hosts file very busy. But if you keep it short and use the cache of Informix 11.7 it shouldn't be too bad. And it can save you if your DNS blows away (you could then add entries to the /etc/hosts file even temporarily). Note that at least in my test system (Linux) not even res_init makes the process re-read /etc/nsswitch.conf&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Make sure your DNS admins and DBA get along... They must work together and should be aware that their systems are tightly connected&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Use Informix 11.7 if you can, so that you can use REMOTE_SERVER_CFG. Many companies don't allow the DBA to manage the /etc/hosts.equiv files (system files). If you have a problem in DNS, and your reverse DNS queries start to fail, your trusted connections will fail if they use the names and not the IP addresses. So, in critical situations it may be useful that the DBAs can act immediately and add the IP addresses in the trusted lists. With REMOTE_SERVER_CFG they'll be able to do it.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Use very small &lt;i&gt;timeouts&lt;/i&gt; configured in /etc/resolvs.conf (1-2s) to minimize the waisted wait time (a successful query to a  DNS is pretty quick&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;Versão Portuguesa:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Você decidiu...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Este artigo é o primeiro publicado após opinião dos leitores. Tinha algumas opções para assuntos a abordar e iniciei um inquérito numa &lt;a href="http://www.facebook.com/pages/Informix-Portugal/169091949374" target="_blank"&gt;página do Facebook&lt;/a&gt;. O impacto do &lt;a href="http://en.wikipedia.org/wiki/Domain_Name_System" target="_blank"&gt;DNS&lt;/a&gt; no Informix foi o mais votado. E a vontade expressa foi cumprida. Provavelmente continuarei a fazer isto de ora em diante.&lt;br /&gt;Pessoalmente o assunto agrada-me porque já enfrentei problemas relacionados com o DNS em mais que um cliente É um assunto algo frequente em ambientes complexos.&lt;br /&gt;O &lt;i&gt;blog&lt;/i&gt; tem um termo de desresponsabilização público e genérico, mas neste caso gostaria de o enfatizar um pouco... Para além do normal, gostaria de deixar claro que a informação que se segue foge um pouco &amp;nbsp;às minhas competências "regulares". É o resultado de bastante investigação ao longo fo tempo (e não só minha) e pode conter alguns (espero que poucos e pouco importantes) erros. Não se acanhe de comentar, corrigir, sugerir alterações por aqui ou por &lt;i&gt;email&lt;/i&gt; etc.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Pequena introdução ao DNS&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;DNS é um acrónimo de Domain Name System, que é o protocolo/serviço capaz de converter um nome (ex: onlinedomus.com) num endereço TCP/IP (ex: 89.1.2.3) e vice-versa. Pode ainda fazer uma série de outras coisas, como indicar qual o servidor de &lt;i&gt;email&lt;/i&gt; responsável por um determinado domínio etc., mas isso já sai do âmbito deste artigo.&lt;br /&gt;Sem DNS não haveria Internet como a conhecemos. É um componente crítico da infra-estrutura da Internet, e a sua eficiência e segurança é crucial para nós, os utilizadores&lt;br /&gt;Numa pequena rede podemos passar sem DNS para as funções básicas de resolução de nomes, usando ficheiros. Mas em redes mais complexas e maiores, pode ser muito complicado e penoso gerir isso usando apenas ficheiros.&lt;br /&gt;O sistema de DNS tem uma arquitectura hierárquica e usa o&amp;nbsp; &lt;a href="http://pt.wikipedia.org/wiki/User_Datagram_Protocol" target="_blank"&gt;protocolo UDP&lt;/a&gt; (U não significa &lt;i&gt;unreliable&lt;/i&gt; mas podia...) por questões de&amp;nbsp;&lt;i&gt;performance&lt;/i&gt;. Configurar devidamente um sistema DNS pode ser uma tarefa complexa e a minha experiência diz-me que não é muito fácil encontrar quem o saiba fazer correctamente. Ainda mais, na maioria dos casos as pessoas não têm a correcta noção do terrível impacto que uma má configuração no DNS pode ter nos sistemas.&lt;br /&gt;Não vou explicar (não o saberia fazer) todos os aspectos de configuração de DNS, mas quero referir alguns pontos:&lt;br /&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;u&gt;/etc/nsswitch.conf&lt;/u&gt;&lt;div&gt;Este ficheiro (em sistemas Unix/Linux, mas o nome pode mudar) define como a resolução de nomes (e outros serviços) é efectuada. Mais especificamente define se o sistema usa ficheiros, NIS, servidores de DNS ou outros mecanismos e a ordem porque o faz. Como exemplo, uma linha como:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;hosts:      dns files&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;indica que as pesquisas de nomes e IPs são feitas primeiro usando os servidores de DNS e depois ficheiros&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;/etc/hosts&lt;/u&gt;&lt;div&gt;Este ficheiro mapeia os endereços IPs em nomes (e vice-versa). Por exemplo:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;89.1.2.3 www.onlinedomus.com onlinedomus.com&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Isto indica ao sistema que o endereço IP 89.1.2.3 mapeia para "www.onlinedomus.com" (e vice-versa). Uma pesquisa por "onlinedomus.com" irá mapear para o mesmo endereço IP.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;/etc/resolv.conf&lt;/u&gt;&lt;div&gt;Este ficheiro contém a lista de servidores de DNS que serão usados para fazer pesquisas e eventualmente mais algumas opções (como &lt;i&gt;timeouts&lt;/i&gt; para os pedidos, domínios que serão adicionados aos nomes pedidos caso o nome simples não obtenha resultados etc.). Um exemplo:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;nameserver 192.168.112.2&lt;/div&gt;&lt;div&gt;nameserver 9.64.162.21&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Como é que o Informix usa o DNS?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Da perspectiva do DNS, o Informix é apenas mais uma aplicação. O ficheiro /etc/nsswitch.conf contém &amp;nbsp;configurações que definem se o Informix irá usar ficheiros (/etc/hosts) ou servidores de DNS (configurados em /etc/resolv.conf). A primeira coisa a notar é que toda a interacção do Informix com o DNS é feito através de funções de sistema. Em particular, o Informix usa duas funções ou as suas equivalente e/ou substitutas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;gethostbyname()&lt;br /&gt;Resumidamente recebe um nome de máquina e retorna uma estrutura contendo um endereço IP&lt;/li&gt;&lt;li&gt;gethostbyaddr()&lt;br /&gt;&amp;nbsp;Esta faz o contrário, ou seja recebe uma estrutura com o endereço IP e retorna os campos relativos ao nome (ou nomes) preenchidos&lt;/li&gt;&lt;/ul&gt;Assim, se alguma coisa não estiver a funcionar, temos de entender quando e onde é que o Informix chama estas funções e como é que elas funcionam. É típico ver clientes a culpar o Informix quando tal não é justo (não completamente pelo menos, mas mais sobre isto adiante). A maioria (senão todos) dos problemas de DNS que afectam o Informix que presenciei, afectam também outras aplicações. E estes problemas são facilmente reproduzíveis com um pequeno programa em linguagem C. Quer isto dizer que não poderíamos fazer algumas coisas de forma diferente (melhor?) Não... Mas isto será abordado mais adiante (chamo a atenção para o termo de desresponsabilização :) )&lt;br /&gt;Este artigo é escrito essencialmente da perspectiva do servidor de base de dados. Mas o DNS tem implicações óbvias no lado do cliente... Vamos começar por aqui e depois saltamos para o servidor.&lt;br /&gt;Quando um cliente tenta conectar-se a um servidor Informix, começa por procurar o $INFORMIXSERVER (ou equivalente dado na &lt;i&gt;string&lt;/i&gt; de conexão) no ficheiro $INFORMIXSQLHOSTS (em Java a informação pode ser obtida via LDAP ou HTTP, mas vamos assumir só ficheiros por simplificação). O ficheiro contém linhas com o seguinte formato:&lt;br /&gt;&lt;pre&gt;INFORMIXSERVER PROTOCOLO NOME_MAQUINA/ENDERECO_IP NUMERO_PORTO/NOME_SERVICO OPCOES&lt;/pre&gt;Quando as funções das bibliotecas cliente encontram a linha que define o INFORMIXSERVER pretendido, obtêm o nome da máquina (ou endereço IP) e o número do porto (ou nome de serviço).&lt;br /&gt;Se o nome de serviço é usado, procuramos o número do porto no ficheiro /etc/services (isto também pode ser configurado no /etc/nsswitch.conf). Pessoalmente habitualmente uso o número do porto directamente para evitar mais esta consulta..&lt;br /&gt;Depois, se o nome de uma máquina foi usado, o cliente terá de o converter para um endereço IP. Para isso chama a função gethostbyname(). Esta função irá comportar-se como especificado no ficheiro /etc/nsswitch.conf e tentará mapear o nome recebido num endereço IP. Uma falha ao fazer isto irá resultar num erro -930. Isto pode ser provocado:&lt;br /&gt;&lt;pre&gt;cheetah@pacman.onlinedomus.com:fnunes-&amp;gt; echo $INFORMIXSERVER; grep $INFORMIXSERVER $INFORMIXSQLHOSTS; dbaccess sysmaster -&lt;br /&gt;blogtest&lt;br /&gt;blogtest     onsoctcp     nowhere.onlinedomus.com 1500&lt;br /&gt;&lt;br /&gt;930: Cannot connect to database server (nowhere.onlinedomus.com).&lt;br /&gt;cheetah@pacman.onlinedomus.com:fnunes-&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;e se precisar de evidências do que se está a passar pode usar o strace (ou truss conforme a plataforma):&lt;br /&gt;&lt;pre&gt;strace -o /tmp/strace.out dbaccess sysmaster -&lt;/pre&gt;O seguinte é um extracto editado do /tmp/strace.out gerado pelo comando acima. Se tiver paciência, pode vê-lo a fazer:&lt;br /&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Abrir o ficheiro etc/nsswitch.conf&lt;/li&gt;&lt;li&gt;Abrir o ficheiro $INFORMIXSQLHOSTS (/home/informix/etc/sqlhosts)&lt;/li&gt;&lt;li&gt;Abrir o ficheiro /etc/services (excepcionalmente usei um nome em vez de um porto)&lt;/li&gt;&lt;li&gt;Abrir o /etc/resolv.conf para descobrir os servidores de DNS configurados&lt;/li&gt;&lt;li&gt;Abrir um &lt;i&gt;socket&lt;/i&gt; para 192.168.112.2 (o servidor de DNS que tenho configurado)&lt;/li&gt;&lt;li&gt;Perguntar por nowhere.onlinedomus.com&lt;/li&gt;&lt;li&gt;Abrir o ficheir /etc/hosts (no /etc/nsswtich.conf eu configurei a pesquisa nos ficheiros após a pesquisa nos servidores de DNS)&lt;/li&gt;&lt;li&gt;Ler a mensagem de erro nos ficheiros de mensagens do Informix&lt;/li&gt;&lt;li&gt;Escrever a mensagem de erro no stderr&lt;/li&gt;&lt;li&gt;Sair com o erro -1&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;pre&gt;cheetah@pacman.onlinedomus.com:fnunes-&amp;gt; cat /tmp/strace.out&lt;br /&gt;[...]&lt;br /&gt;open("/etc/nsswitch.conf", O_RDONLY)    = 3&lt;br /&gt;fstat64(3, {st_mode=S_IFREG|0644, st_size=1803, ...}) = 0&lt;br /&gt;mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7862000&lt;br /&gt;read(3, "#\n# /etc/nsswitch.conf\n#\n# An ex"..., 4096) = 1803&lt;br /&gt;read(3, "", 4096)                       = 0&lt;br /&gt;close(3)                                = 0&lt;br /&gt;[...]&lt;br /&gt;open("/home/informix/etc/sqlhosts", O_RDONLY|O_LARGEFILE) = 4&lt;br /&gt;_llseek(4, 0, [0], SEEK_SET)            = 0&lt;br /&gt;read(4, "blogtest     onsoctcp     nowher"..., 4096) = 1389&lt;br /&gt;[...]&lt;br /&gt;open("/etc/services", O_RDONLY|O_CLOEXEC) = 4&lt;br /&gt;fstat64(4, {st_mode=S_IFREG|0644, st_size=644327, ...}) = 0&lt;br /&gt;mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7862000&lt;br /&gt;read(4, "# /etc/services:\n# $Id: services"..., 4096) = 4096&lt;br /&gt;close(4)                                = 0&lt;br /&gt;[...]&lt;br /&gt;open("/etc/resolv.conf", O_RDONLY)      = 4&lt;br /&gt;[...]&lt;br /&gt;read(4, "", 4096)                       = 0&lt;br /&gt;close(4)                                = 0&lt;br /&gt;[...]&lt;br /&gt;open("/lib/libresolv.so.2", O_RDONLY)   = 4&lt;br /&gt;read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0Pf\256\0004\0\0\0"..., 512) = 512&lt;br /&gt;[...]&lt;br /&gt;close(4)                                = 0&lt;br /&gt;[...]&lt;br /&gt;socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 4&lt;br /&gt;connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, 16) = 0&lt;br /&gt;gettimeofday({1325590403, 502576}, NULL) = 0&lt;br /&gt;poll([{fd=4, events=POLLOUT}], 1, 0)    = 1 ([{fd=4, revents=POLLOUT}])&lt;br /&gt;send(4, "tl\1\0\0\1\0\0\0\0\0\0\7nowhere\vonlinedomus"..., 41, MSG_NOSIGNAL) = 41&lt;br /&gt;poll([{fd=4, events=POLLIN}], 1, 5000)  = 1 ([{fd=4, revents=POLLIN}])&lt;br /&gt;ioctl(4, FIONREAD, [101])               = 0&lt;br /&gt;recvfrom(4, "tl\201\203\0\1\0\0\0\1\0\0\7nowhere\vonlinedomus"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, [16]) = 101&lt;br /&gt;close(4)                                = 0&lt;br /&gt;[...]&lt;br /&gt;open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 4&lt;br /&gt;[...]&lt;br /&gt;read(4, "127.0.0.1\tpacman1.onlinedomus.ne"..., 4096) = 439&lt;br /&gt;[...]&lt;br /&gt;close(4)                                = 0&lt;br /&gt;[...]&lt;br /&gt;read(3, "Cannot connect to database serve"..., 40) = 40&lt;br /&gt;write(2, "\n", 1)                       = 1&lt;br /&gt;write(2, "  930: Cannot connect to databas"..., 68) = 68&lt;br /&gt;exit_group(-1)                          = ?&lt;br /&gt;cheetah@pacman.onlinedomus.com:fnunes-&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Agora devemos passar para o lado do servidor. Mas isso requer um pouco mais de trabalho e explicações preliminares. Para começar temos de entender o que o motor necessita para estabelecer uma ligação ou sessão. Uma dessas coisas é fazer o chamado "reverse DNS" ou DNS inverso que não é mais que converter um endereço IP no nome de uma máquina. Isto pode não ser absolutamente essencial, mas é sempre tentado. O Informix pode precisar do nome da máquina para validar as relações de confiança (ligações sem utilizador/&lt;i&gt;password&lt;/i&gt;). O nome servirá também para informação do DBA de forma a mais facimente identificar a origem do cliente.&lt;br /&gt;Como saberá, o motor de base de dados Informix é composto por vários processos de sistema operativo. Do ponto de vista do SO, todos estes processos parecem iguais (chamam-se oninit), mas cada um tem um trabalho específico e corre&amp;nbsp;&lt;i&gt;threads&lt;/i&gt; específicas do motor.&lt;/div&gt;&lt;div&gt;Podemos listar as &lt;i&gt;threads&lt;/i&gt; com:&lt;br /&gt;&lt;pre&gt;panther@pacman.onlinedomus.com:fnunes-&amp;gt; onstat -g ath&lt;br /&gt;&lt;br /&gt;IBM Informix Dynamic Server Version 11.70.UC4 -- On-Line -- Up 00:17:01 -- 411500 Kbytes&lt;br /&gt;&lt;br /&gt;Threads:&lt;br /&gt; tid     tcb      rstcb    prty status                vp-class       name&lt;br /&gt; 2       5583fa38 0        1    IO Idle                 3lio*        lio vp 0&lt;br /&gt; 3       558551f8 0        1    IO Idle                 4pio*        pio vp 0&lt;br /&gt; 4       5586b1f8 0        1    IO Idle                 5aio*        aio vp 0&lt;br /&gt; 5       558811f8 8f59dc0  1    IO Idle                 6msc*        msc vp 0&lt;br /&gt; 6       558af1f8 0        1    IO Idle                 7fifo*       fifo vp 0&lt;br /&gt; 7       558c9590 0        1    IO Idle                 9aio*        aio vp 1&lt;br /&gt; 8       558df3b8 54267018 3    sleeping secs: 1        8cpu         main_loop()&lt;br /&gt; 9       559276f8 0        1    running                10soc*        soctcppoll&lt;br /&gt; 10      5593ed18 0        2    sleeping forever        1cpu*        soctcplst&lt;br /&gt; 11      55927d20 542675fc 1    sleeping secs: 1        8cpu         flush_sub(0)&lt;br /&gt; 12      55988018 54267be0 1    sleeping secs: 1        8cpu         flush_sub(1)&lt;br /&gt; 13      559881f0 542681c4 1    sleeping secs: 1        8cpu         flush_sub(2)&lt;br /&gt; 14      559883c8 542687a8 1    sleeping secs: 1        8cpu         flush_sub(3)&lt;br /&gt; 15      559885a0 54268d8c 1    sleeping secs: 1        8cpu         flush_sub(4)&lt;br /&gt; 16      55988778 54269370 1    sleeping secs: 1        8cpu         flush_sub(5)&lt;br /&gt; 17      55988bf0 54269954 1    sleeping secs: 1        8cpu         flush_sub(6)&lt;br /&gt; 18      559fb468 54269f38 1    sleeping secs: 1        8cpu         flush_sub(7)&lt;br /&gt; 19      559fb640 0        3    IO Idle                 8cpu*        kaio&lt;br /&gt; 20      55ab6018 5426a51c 2    sleeping secs: 1        8cpu         aslogflush&lt;br /&gt; 21      55ab6960 5426ab00 1    sleeping secs: 92       1cpu         btscanner_0&lt;br /&gt; 22      55b6a408 5426b0e4 3    cond wait  ReadAhead    1cpu         readahead_0&lt;br /&gt; 39      55bcd5c8 0        3    IO Idle                 1cpu*        kaio&lt;br /&gt; 40      55bcd7a0 5426bcac 3    sleeping secs: 1        1cpu*        onmode_mon&lt;br /&gt; 41      55d3e148 5426c874 3    sleeping secs: 1        8cpu         periodic&lt;br /&gt; 49      55e80a78 5426da20 1    sleeping secs: 177      1cpu         dbScheduler&lt;br /&gt; 51      55f340f8 5426d43c 1    sleeping forever        1cpu         dbWorker1&lt;br /&gt; 52      55f34d80 5426ce58 1    sleeping forever        8cpu         dbWorker2&lt;br /&gt; 59      562ee228 5426e5e8 1    cond wait  bp_cond      1cpu         bf_priosweep()&lt;br /&gt;&lt;/pre&gt;E os processos de sistema operativo com:&lt;br /&gt;&lt;pre&gt;panther@pacman.onlinedomus.com:fnunes-&amp;gt; onstat -g glo&lt;br /&gt;&lt;br /&gt;IBM Informix Dynamic Server Version 11.70.UC4 -- On-Line -- Up 00:18:48 -- 411500 Kbytes&lt;br /&gt;&lt;br /&gt;MT global info:&lt;br /&gt;sessions threads  vps      lngspins&lt;br /&gt;0        29       10       3       &lt;br /&gt;&lt;br /&gt;          sched calls     thread switches yield 0   yield n   yield forever&lt;br /&gt;total:    9589515         8992470         597961    14485     4457836  &lt;br /&gt;per sec:  0               0               0         0         0        &lt;br /&gt;&lt;br /&gt;Virtual processor summary:&lt;br /&gt; class       vps       usercpu   syscpu    total   &lt;br /&gt; cpu         2         11.51     94.06     105.57  &lt;br /&gt; aio         2         3.57      75.44     79.01   &lt;br /&gt; lio         1         0.01      0.01      0.02    &lt;br /&gt; pio         1         0.00      0.01      0.01    &lt;br /&gt; adm         1         0.01      0.15      0.16    &lt;br /&gt; soc         1         0.04      0.15      0.19    &lt;br /&gt; msc         1         0.00      0.01      0.01    &lt;br /&gt; fifo        1         0.00      0.01      0.01    &lt;br /&gt; total       10        15.14     169.84    184.98  &lt;br /&gt;&lt;br /&gt;Individual virtual processors:&lt;br /&gt; vp    pid       class       usercpu   syscpu    total     Thread    Eff  &lt;br /&gt; 1     29395     cpu         5.63      46.80     52.43     66.41     78%&lt;br /&gt; 2     29398     adm         0.01      0.15      0.16      0.00       0%&lt;br /&gt; 3     29399     lio         0.01      0.01      0.02      0.02     100%&lt;br /&gt; 4     29400     pio         0.00      0.01      0.01      0.01     100%&lt;br /&gt; 5     29401     aio         3.29      74.30     77.59     77.59    100%&lt;br /&gt; 6     29402     msc         0.00      0.01      0.01      0.03      31%&lt;br /&gt; 7     29403     fifo        0.00      0.01      0.01      0.01     100%&lt;br /&gt; 8     29404     cpu         5.88      47.26     53.14     64.45     82%&lt;br /&gt; 9     29405     aio         0.28      1.14      1.42      1.42     100%&lt;br /&gt; 10    29406     soc         0.04      0.15      0.19      NA         NA&lt;br /&gt;                 tot         15.14     169.84    184.98&lt;/pre&gt;As &lt;i&gt;threads&lt;/i&gt; que estão à escuta nos portos TCP do motor são as &lt;i&gt;poll threads&lt;/i&gt; (soctcppoll) que correm nos &amp;nbsp;VPs (&lt;i&gt;virtual processors&lt;/i&gt;) de classe SOC (isto depende da configuração do parâmetro NETTYPE). Quando um novo pedido de ligação é recebido por elas, chama as &lt;i&gt;listener threads&lt;/i&gt; (soctcplst) que correm na classe CPU, para iniciar o processo de autenticação. Partes deste processo são executadas pelo VP MSC. Como podemos ver na lista acima este tem o PID 29402. Portanto, para perceber o que se passa irei fazer o &lt;i&gt;trace&lt;/i&gt; a este processo. Por razões que ficarão claras mais abaixo, vou desligar a funcionalidade NS_CACHE (11.7) e vou fazer uma paragem/arranque do motor. Após isto, para a primeira tentativa de conexão obtemos (algumas partes não relevantes foram cortadas):&lt;br /&gt;&lt;pre&gt;1      0.000000 semop(753664, {{5, -1, 0}}, 1) = 0&lt;br /&gt;2      7.009868 socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3&lt;br /&gt;3      0.000107 connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)&lt;br /&gt;4      0.000242 close(3)                  = 0&lt;br /&gt;5      0.000060 socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3&lt;br /&gt;6      0.000063 connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)&lt;br /&gt;7      0.000095 close(3)                  = 0&lt;br /&gt;8      [...]&lt;br /&gt;9      0.000000 open("/etc/resolv.conf", O_RDONLY) = 3&lt;br /&gt;10     0.000000 fstat64(3, {st_mode=S_IFREG|0644, st_size=55, ...}) = 0&lt;br /&gt;11     0.000000 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xab4000&lt;br /&gt;12     0.000000 read(3, "# Generated by NetworkManager\nna"..., 4096) = 55&lt;br /&gt;13     0.000926 read(3, "", 4096)         = 0&lt;br /&gt;14     0.000050 close(3)                  = 0&lt;br /&gt;15     [...]&lt;br /&gt;16     0.000057 futex(0x29ab44, FUTEX_WAKE_PRIVATE, 2147483647) = 0&lt;br /&gt;17     0.000256 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3&lt;br /&gt;18     0.000089 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, 16) = 0&lt;br /&gt;19     0.000107 gettimeofday({1325605320, 167025}, NULL) = 0&lt;br /&gt;20     0.000072 poll([{fd=3, events=POLLOUT}], 1, 0) = 1 ([{fd=3, revents=POLLOUT}])&lt;br /&gt;21     0.000083 send(3, "\363\337\1\0\0\1\0\0\0\0\0\0\0011\003112\003168\003192\7in-ad"..., 44, MSG_NOSIGNAL) = 44&lt;br /&gt;22     0.000322 poll([{fd=3, events=POLLIN}], 1, 5000) = 1 ([{fd=3, revents=POLLIN}])&lt;br /&gt;23     2.061369 ioctl(3, FIONREAD, [121]) = 0&lt;br /&gt;24     0.000111 recvfrom(3, "\363\337\201\203\0\1\0\0\0\1\0\0\0011\003112\003168\003192\7in-ad"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, [16]) = 121&lt;br /&gt;25     0.000155 close(3)                  = 0&lt;br /&gt;26     0.000090 open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3&lt;br /&gt;27     0.000377 fstat64(3, {st_mode=S_IFREG|0644, st_size=439, ...}) = 0&lt;br /&gt;28     0.000089 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf22000&lt;br /&gt;29     0.000057 read(3, "127.0.0.1\tpacman1.onlinedomus.ne"..., 4096) = 439&lt;br /&gt;30     0.000130 close(3)                  = 0&lt;br /&gt;31     [...]&lt;br /&gt;32     0.000072 semop(753664, {{7, 1, 0}}, 1) = 0&lt;br /&gt;33     0.000069 semop(753664, {{7, 1, 0}}, 1) = 0&lt;br /&gt;34     0.007558 semop(753664, {{5, -1, 0}}, 1 &lt;unfinished ...=""&gt;&lt;br /&gt;&lt;/unfinished&gt;&lt;/pre&gt;&lt;br /&gt;Note-se que para facilitar a análise, adicionei números de linhas e diferenças de tempos entre cada uma das chamadas a funções de sistema (isto será importante adiante). Vamos explicar o que vemos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Na linha 1) tempos um semop() que é a forma de o VP MSC ficar inactivo, à espera de ser solicitado. Isto foi antes da tentativa de conexão&lt;/li&gt;&lt;li&gt;7 segundos depois, acorda e tenta "falar" com o serviço nscd (linhas 2-8). Este serviço é algo específico do Linux e eu não o tenho a correr. Depois acede a /etc/nsswitch.conf. Fixe que isto foi feito na primeira tentativa de conexão.&lt;/li&gt;&lt;li&gt;Depois acede ao ficheiro /etc/resolv.conf (linhas 9-15) e descobre os endereços IP dos servidores de DNS&lt;/li&gt;&lt;li&gt;Nas linhas 16-25 fala com o servidor de DNS (192.168.112.2) e pede o nome do endereço IP que se está a tentar ligar (obtido pela estrutura do &lt;i&gt;socket&lt;/i&gt;)&lt;/li&gt;&lt;li&gt;Como a resposta é inconclusiva, vai ao ficheiro /etc/hosts (linhas 26-31)&lt;/li&gt;&lt;li&gt;Cortei a parte restante, relativa à autenticação (abertura do /etc/passwd, /etc/group e /etc/shadow etc.)&lt;/li&gt;&lt;li&gt;Finalmente retorna ao normal estado de espera&lt;/li&gt;&lt;/ul&gt;Alguns pontos importantes sobre isto:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;div&gt;Tudo aconteceu bastante depressa (valores em segundos)&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Não vemos a chamada à função gethostbyaddr() que eu garanti que era chamada pelo Informix. Na perspectiva do &lt;i&gt;strace&lt;/i&gt; esta não é uma "system call". Só vemos chamadas de mais baixo nível, mas não a gethostbyaddr(). Podemos apanhá-la se ligar-mos um &lt;i&gt;debugger&lt;/i&gt; (dbx, gdb, adb) ao processo. Isto é importante, pois é habitual ser difícil discutir este tema com os administradores de rede e sistema operativo, pois pensam que todas estas chamadas são feitas pelo Informix. Não são! O Informix apenas chama a gethostbyaddr() ou equivalente&lt;/li&gt;&lt;/ol&gt;Agora vamos ver o mesmo processo, mas para a segunda tentativa de conexão. Seria de esperar que o resultado fosse o mesmo, mas não é. Cortei exactamente as mesmas zonas:&lt;br /&gt;&lt;pre&gt;1      0.000000 semop(753664, {{5, -1, 0}}, 1) = 0&lt;br /&gt;2      6.452154 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3&lt;br /&gt;3      0.000099 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, 16) = 0&lt;br /&gt;4      0.008816 gettimeofday({1325605445, 534040}, NULL) = 0&lt;br /&gt;5      0.000089 poll([{fd=3, events=POLLOUT}], 1, 0) = 1 ([{fd=3, revents=POLLOUT}])&lt;br /&gt;6      0.000100 send(3, "\233\t\1\0\0\1\0\0\0\0\0\0\0011\003112\003168\003192\7in-ad"..., 44, MSG_NOSIGNAL) = 44&lt;br /&gt;7      0.000417 poll([{fd=3, events=POLLIN}], 1, 5000) = 1 ([{fd=3, revents=POLLIN}])&lt;br /&gt;8      2.089726 ioctl(3, FIONREAD, [121]) = 0&lt;br /&gt;9      0.000118 recvfrom(3, "\233\t\201\203\0\1\0\0\0\1\0\0\0011\003112\003168\003192\7in-ad"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, [16]) = 121&lt;br /&gt;10     0.000132 close(3)                  = 0&lt;br /&gt;11     0.000069 open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3&lt;br /&gt;12     0.000102 fstat64(3, {st_mode=S_IFREG|0644, st_size=439, ...}) = 0&lt;br /&gt;13     0.000092 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xe1f000&lt;br /&gt;14     0.000064 read(3, "127.0.0.1\tpacman1.onlinedomus.ne"..., 4096) = 439&lt;br /&gt;15     0.000099 close(3)                  = 0&lt;br /&gt;16     [...]&lt;br /&gt;17     0.000068 semop(753664, {{0, 1, 0}}, 1) = 0&lt;br /&gt;18     0.000096 semop(753664, {{0, 1, 0}}, 1) = 0&lt;br /&gt;19     0.000076 semop(753664, {{5, -1, 0}}, 1 &lt;unfinished ...=""&gt;&lt;br /&gt;&lt;/unfinished&gt;&lt;/pre&gt;&lt;br /&gt;Novamente a análise:&lt;br /&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;A primeira parte de acesso ao servilo nscd, a abertura do /etc/nsswitch.conf e do /etc/resolv.conf não aparece. Como se pode ver começa logo com a consulta ao DNS&lt;/li&gt;&lt;li&gt;Depois lê o ficheiro /etc/hosts&lt;/li&gt;&lt;li&gt;Voltei a cortar a parte da autenticação como anteriormente&lt;/li&gt;&lt;li&gt;Finalmente regressa ao estado de espera, tal como anteriormente&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;O ponto importante a reter é que a primeira tentativa é diferente das subsequentes. E reforço novamente que o Informix apenas chama a gethostbyaddr()... exactamente a mesma chamada de cada vez. Bom... para ser exacto a função que chamamos pode depender da plataforma, mas é sempre a mesma em cada conexão. Como referi acima, apenas com a utilização de um &lt;i&gt;debugger&lt;/i&gt; podemos capturar a chamada à gethostbyaddr(). Eu fi-lo e aqui está o resultado:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;(gdb) break connect&lt;br /&gt;Breakpoint 1 at 0x95f640&lt;br /&gt;(gdb) continue&lt;br /&gt;Continuing.&lt;br /&gt;&lt;br /&gt;Breakpoint 1, 0x0095f640 in connect () from /lib/libpthread.so.0&lt;br /&gt;(gdb) where&lt;br /&gt;#0  0x0095f640 in connect () from /lib/libpthread.so.0&lt;br /&gt;#1  0x00aec9ab in reopen () from /lib/libresolv.so.2&lt;br /&gt;#2  0x00aee542 in __libc_res_nsend () from /lib/libresolv.so.2&lt;br /&gt;#3  0x00aeb24e in __libc_res_nquery () from /lib/libresolv.so.2&lt;br /&gt;#4  0x002b6dc7 in _nss_dns_gethostbyaddr2_r () from /lib/libnss_dns.so.2&lt;br /&gt;#5  0x002b6f1a in _nss_dns_gethostbyaddr_r () from /lib/libnss_dns.so.2&lt;br /&gt;#6  0x0020890b in gethostbyaddr_r@@GLIBC_2.1.2 () from /lib/libc.so.6&lt;br /&gt;#7  0x00211f77 in getnameinfo () from /lib/libc.so.6&lt;br /&gt;#8  0x08c0e664 in ifx_getipnodebyaddr ()&lt;br /&gt;#9  0x08c0f79c in ifx_gethostbyaddr ()&lt;br /&gt;#10 0x08c0f8a2 in __osgethostbyaddr ()&lt;br /&gt;#11 0x08b0c055 in aio_workon ()&lt;br /&gt;#12 0x08b0c9c3 in aiothread ()&lt;br /&gt;#13 0x08b0dbcb in iothread ()&lt;br /&gt;#14 0x08b00762 in startup ()&lt;br /&gt;#15 0x558749e8 in ?? ()&lt;br /&gt;#16 0x00000000 in ?? ()&lt;br /&gt;(gdb)&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;Como pode ver, estabeleci um &lt;i&gt;breakpoint&lt;/i&gt; na função &lt;i&gt;connect()&lt;/i&gt;. Depois executei o &lt;i&gt;continue&lt;/i&gt; para que o processo prosseguisse e tentei a conexão. O &lt;i&gt;debugger&lt;/i&gt; interrompeu a execução quando chegou ao &lt;i&gt;connect()&lt;/i&gt; e isso permitiu-me retirar um &lt;i&gt;stack trace&lt;/i&gt; (ler de baixo para cima)&lt;br /&gt;Portanto, mostra-nos que chamamos a função getnameinfo() que por sua vez chama a gethostbyaddr_r() etc. Tudo isto está contido em bibliotecas de sistema, não no código Informix.&lt;br /&gt;&lt;br /&gt;Há mais dois pontos a salientar. Primeiro, o processador virtual do Informix da classe MSC processa os &amp;nbsp;pedidos de forma sequencial. Para cada conexão é-lhe pedido que efectue o DNS inverso (pedindo aos servidores DNS ou lendo o ficheiro /etc/hosts) e faça a autenticação. Por omissão apenas temos um MSC... portanto se um pedido ficar "preso"... sim... os que vierem a seguir irão sofrer atrasos. Estes atrasos podem ser uma fracção de segundo ou alguns segundos, mas em alguns sistemas já observei dezenas de conexões por segundo (já vi referências a centenas/segundo). Portanto mesmo um atraso de alguns segundos pode ter um impacto muito notório.&lt;br /&gt;O segundo ponto refere-se à diferença entre a primeira chamada e as seguintes. Como vimos acima, na primeira chamada é verificada a configuração (ficheiros /etc/nsswitch.conf e /etc/resolv.conf). Nas seguintes tal não acontece por razões de &lt;i&gt;performance&lt;/i&gt;. E isto causa um problema. Novamente, este comportamento é das funções de sistema, não do Informix (mas não será necessariamente o fim da história)&lt;br /&gt;&lt;br /&gt;Portanto, espero que tenha conseguido explicar como é que o Informix interage com o sistema de DNS. O mergulho nos bits e bytes já terminou. Vamos prosseguir para as implicações, mas é importante que tenha ficado claro o que foi explicado acima antes de prosseguir para os próximos parágrafos.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Que problemas podemos enfrentar?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Acima tentei demonstrar como as coisas funcionam quando está tudo ok. Mas o que acontece quando algo está mal? Vamos ver o que pode correr mal e quais as implicações. Tentarei também tentar indicar de quem será a responsabilidade (mais uma vez relembro o termo de desresponsabilização...). O objectivo não é propriamente apontar o dedo a ninguém, mas saber onde é que o problema reside é meio caminho andado para o resolver.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;u&gt;Problemas de rede impedem a conexão aos servidores de DNS&lt;/u&gt;&lt;br /&gt;Se isto acontecer, os pedidos enviados pelo VP MSC terão de dar &lt;i&gt;timeout&lt;/i&gt; (tipicamente alguns segundos) antes que as chamadas às funções de sistema operativo retornem. Este atraso irá causar que todos os pedidos de conexão seguintes fiquem em espera (assumindo que só temos um MSC VP). Se os problemas de rede persistirem, não irá importar muito quantos processadores de classe MSC temos, pois à partida todos eles irão ficar presos e todos os pedidos de conexão sofrerão atrasos.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;O(s) servidor(es) de DNS caem, são parados ou ficam muito lentos&lt;/u&gt;&lt;br /&gt;O efeito disto é em tudo semelhante ao anterior. Qualquer coisa que cause atrasos nos pedidos aos DNS irá potenciar atrasos nas conexões ao motor. Note-se que isto pode ser um problema que afecte todos os pedidos, ou apenas alguns. Devido à natureza hierárquica e distribuída da estrutura de DNS, pode ser possível responder a alguns pedidos e não a outros por estes levarem a contactos com determinados servidores que possam não estar disponíveis. Escusado referir que isto torna a investigação destes problemas ainda mais difícil.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;Algo afecta o sistema de DNS. Os pedidos de DNS inverso falham e isto afecta as conexões &lt;i&gt;trusted&lt;/i&gt;&lt;/u&gt;&lt;br /&gt;Neste caso começam a aparecer erros -956 no &lt;i&gt;online.log&lt;/i&gt; da instância e os clientes começam a receber o erro -951. Naturalmente isto acontece se as relações de confiança estiverem definidas com nomes em vez de endereços IP (o uso de nomes é o mais normal e recomendado, dado que é mais frequente mudar um IP que o nome)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;Precisa de mudar os seus servidores de DNS&lt;/u&gt;&lt;br /&gt;&amp;nbsp;Então terá de parar e arrancar o Informix. Isto é um problema causado pelo Informix (podía-mos fazer melhor). Como referido acima, as funções de sistema operativo fazem &lt;i&gt;cache&lt;/i&gt; da configuração (seria muito ineficiente re-verificar a configuração em cada pedido). E esta situação leva a que o Informix não se "aperceba" que os servidores de DNS foram mudados. Portanto o problema é que se mudarmos a politica de resolução (/etc/nsswitch.conf) ou os servidores (/etc/resolv.conf) os processos de Informix não terão isso em conta&lt;/li&gt;&lt;/ol&gt;Dos problemas acima é fácil de entender que os três primeiros não são "culpa" do Informix. Quando um cliente decide usar uma infra-estrutura de DNS (supostamente porque necessita) terá de entender que isso passa automaticamente a ser um componente critico dos seus sistemas. Qualquer problema que essa infra-estrutura tenha vai afectar as camadas acima como os servidores de base de dados e outros.&lt;br /&gt;E assim ficamos com o quarto problema. Escrevi atrás e é verdade que o comportamento é das funções de sistema operativo (e vou demonstrá-lo), portanto porque é que digo que a responsabilidade é do Informix? Bom, porque existe uma forma de lidar com isto. Há uma outra função de sistema chamada res_init() que faz aquilo que necessitamos. Do manual de Linux, cito (sem tradução):&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;i&gt;&lt;b&gt;The  res_init()  function  reads the configuration files&lt;/b&gt; (see resolv.conf(5)) to get the default domain name, search order and name server address(es).&lt;br /&gt;If no server is given, the local host is tried.  If no domain is given, that associated with the local host is used.  It can  be  overridden  with  the environment variable LOCALDOMAIN.  &lt;b&gt;res_init() is normally executed by the first call to one of the other functions&lt;/b&gt;&lt;/i&gt;.&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;A minha opinião é que o Informix deveria providenciar uma forma pela qual o DBA poderia forçar que cada processador virtual da classe MSC chamasse esta função. Isto refrescaria a informação obtida na primeira chamada à gethostbyaddr() que é mantida em&amp;nbsp;&lt;i&gt;cache&lt;/i&gt; no espaço do processo.&lt;br /&gt;Na verdade a IBM tem um pedido de funcioalidade pendente que refer isto explicitamente. Gostaria bastante de o ver implementado numa versão futura. Isto é algo sem o qual podemos viver durante anos, mas se a situação se coloca pode realmente fazer a diferença entre ter de parar o servidor de base de dados ou não.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Detectar se temos um problema&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Como podemos saber se temos um problema de DNS e isso está a ter impacto no Informix? Habitualmente iremos receber algum tipo de queixa dos clientes/aplicações Informix. Tipicamente algo como "a base de dados está muito lenta", ou algo mais correcto como "leva muito tempo a estabelecer uma conexão", ou eventualmente algumas sessões serão recusadas com o erro -956 (do lado do servidor) que corresponde a um erro -951 retornado ao cliente. Nos casos mais extremos podem aparecer erros menos comuns no&amp;nbsp;&lt;i&gt;online.log&lt;/i&gt; (-25xxx). Em todos estes casos notará que depois de estabelecidas as ligações estas trabalham sem problemas.&lt;br /&gt;Mas para ter a certeza absoluta pode seguir dois caminhos:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;O mais simples é correr um simples "netstat -a" na máquina onde reside o servidor de base de dados. Isto mostra todas as ligações TCP/UDP de e para a máquina. Por omissão, vai percorrer todas as ligações&amp;nbsp;&lt;i&gt;socket&lt;/i&gt; e tentará fazer o pedido de DNS inverso sobre o respectivo endereço IP para obter os nomes das máquinas. Se estiver a ter problemas de DNS o &lt;i&gt;netstat&lt;/i&gt; irá correr muito lento ou pelo menos verificará alguns "soluços" no &lt;i&gt;output&lt;/i&gt; do mesmo. Mas para que este teste seja conclusivo, tem de garantir que as configurações de DNS que o netstat vai usar são as mesmas que o motor Informix está a usar (que serão as que tinha quando o motor foi levantado)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;O mais complexo passa por executar um comando "truss" ou "strace" contra o(s) processo do processador virtual de classe MSC, com apresentação de tempos. Isto permitirá mostrar tempos de resposta lentos das funções que trocam informação com os servidores de DNS. Tenha em atenção que correr o truss/strace requer privilégios de&amp;nbsp;&lt;i&gt;root&lt;/i&gt; e que mesmo quando tudo está a correr bem, isto causará algum impacto em sistemas com uma taxa de novas ligações por segundo elevada.&lt;/li&gt;&lt;/ol&gt;Escrevia atrás que posso demonstrar os factos apresentados aqui sem usar o Informix. Para tal criei um pequeno programa em C (números de linha adicionados):&lt;br /&gt;&lt;pre&gt;1  #include &amp;lt;sys/time.h&amp;gt;&lt;br /&gt;2  #include &amp;lt;netdb.h&amp;gt;&lt;br /&gt;3  #include &amp;lt;resolv.h&amp;gt;&lt;br /&gt;4  #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;5  #include &amp;lt;string.h&amp;gt;&lt;br /&gt;6  &lt;br /&gt;7  int main(int argc, char **argv)&lt;br /&gt;8  {&lt;br /&gt;9    struct hostent *hp;&lt;br /&gt;10    in_addr_t data;&lt;br /&gt;11    char buff[100];&lt;br /&gt;12    struct timeval ts_initial, ts_final;&lt;br /&gt;13  &lt;br /&gt;14    if (argc == 2) {&lt;br /&gt;15      strcpy(buff,argv[1]);&lt;br /&gt;16    }&lt;br /&gt;17    else {&lt;br /&gt;18      printf("Introduce an IP address: ");&lt;br /&gt;19      if (fscanf(stdin,"%s", buff) == EOF)&lt;br /&gt;20        exit(0);&lt;br /&gt;21    }&lt;br /&gt;22  &lt;br /&gt;23    while (1 == 1) {&lt;br /&gt;24      data = inet_addr(buff);&lt;br /&gt;25      gettimeofday(&amp;amp;ts_initial, NULL);&lt;br /&gt;26      hp = gethostbyaddr(&amp;amp;data, 4, AF_INET);&lt;br /&gt;27      gettimeofday(&amp;amp;ts_final, NULL);&lt;br /&gt;28  &lt;br /&gt;29      if (hp == NULL) {&lt;br /&gt;30        printf("Unknown host (%s). Took %f seconds\n", buff, (double)((ts_final.tv_sec * 1000000 + ts_final.tv_usec) - (ts_initial.tv_sec * 1000000 + ts_initial.tv_usec))/1000000);&lt;br /&gt;31      }&lt;br /&gt;32      else {&lt;br /&gt;33        printf("Name (%s): %s Took %f seconds\n", buff, hp-&amp;gt;h_name, (double)((ts_final.tv_sec * 1000000 + ts_final.tv_usec) - (ts_initial.tv_sec * 1000000 + ts_initial.tv_usec))/1000000);&lt;br /&gt;34      }&lt;br /&gt;35      printf("Next: ");&lt;br /&gt;36      if (fscanf(stdin,"%s", buff) == EOF)&lt;br /&gt;37        exit(0);&lt;br /&gt;38      if ( strncmp("refresh", buff, 7) == 0 )&lt;br /&gt;39      {&lt;br /&gt;40         res_init();&lt;br /&gt;41         printf("Called res_init()\n");&lt;br /&gt;42         printf("Next: ");&lt;br /&gt;43         if (fscanf(stdin,"%s", buff) == EOF)&lt;br /&gt;44           exit(0);&lt;br /&gt;45      }&lt;br /&gt;46    }&lt;br /&gt;47  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Isto é basicamente um ciclo que lê um endereço IP (que não é validado, portanto é fácil de causar erros no programa) e corre a gethostbyaddr() sobre o mesmo. Se o "IP" dado fôr "refresh" então chama a função res_init(). Informa das respostas obtidas pelo sistema de resolução de nomes e o tempo que demorou. Pode ser usado interactivamente ou podemos chamá-lo redireccionando o &lt;i&gt;input&lt;/i&gt; de um ficheiro que contenha um endereço IP em cada linha.&lt;br /&gt;&lt;br /&gt;Vou executá-lo interactivamente com tracing para mostrar o efeito de chamar a função res_init(). Tenho "hosts: dns, files" no ficheiro /etc/nsswitch.conf e 192.168.112.2 no /etc/resolv.conf. Este último contém também opções para definir um &lt;i&gt;timeout&lt;/i&gt; de 2 segundos. Portanto chamo-o com:&lt;br /&gt;&lt;pre&gt;cheetah@pacman1.onlinedomus.net:fnunes-&amp;gt; strace -r -o test_resolv.trace ./test_resolv&lt;br /&gt;Introduce an IP address: 1.1.1.1&lt;br /&gt;Unknown host (1.1.1.1). Took 2.010235 seconds&lt;br /&gt;Next: 1.1.1.2&lt;br /&gt;Unknown host (1.1.1.2). Took 2.003324 seconds&lt;br /&gt;Next: refresh&lt;br /&gt;Called res_init()&lt;br /&gt;Next: 1.1.1.3&lt;br /&gt;Unknown host (1.1.1.3). Took 2.004002 seconds&lt;br /&gt;Next: ^C&lt;/pre&gt;Antes de introduzir "refresh" mudo o servidor de DNS no ficheiro /etc/resolv.conf de 192.168.112.2 para 192.168.112.5.&lt;br /&gt;O resultado do &lt;i&gt;trace&lt;/i&gt; é este (números de linha e tempos adicionados):&lt;br /&gt;&lt;pre&gt;1        [...]&lt;br /&gt;2        0.000000 write(1, "Introduce an IP address: ", 25) = 25&lt;br /&gt;3        0.000000 read(0, "1.1.1.1\n", 1024) = 8&lt;br /&gt;4        3.055699 gettimeofday({1325865284, 104186}, NULL) = 0&lt;br /&gt;5        [...]&lt;br /&gt;6        0.000160 socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3&lt;br /&gt;7        0.000099 connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ECONNREFUSED (Connection refused)&lt;br /&gt;8        0.000128 close(3)                  = 0&lt;br /&gt;9        0.000053 socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3&lt;br /&gt;10       0.000123 connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ECONNREFUSED (Connection refused)&lt;br /&gt;11       0.000122 close(3)                  = 0&lt;br /&gt;12       0.000095 open("/etc/nsswitch.conf", O_RDONLY) = 3&lt;br /&gt;13       0.000108 fstat64(3, {st_mode=S_IFREG|0644, st_size=1803, ...}) = 0&lt;br /&gt;14       0.000101 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7843000&lt;br /&gt;15       0.000057 read(3, "#\n# /etc/nsswitch.conf\n#\n# An ex"..., 4096) = 1803&lt;br /&gt;16       0.000001 read(3, "", 4096)         = 0&lt;br /&gt;17       0.000000 close(3)                  = 0&lt;br /&gt;18       [...]&lt;br /&gt;19       0.000055 open("/etc/resolv.conf", O_RDONLY) = 3&lt;br /&gt;20       0.000072 fstat64(3, {st_mode=S_IFREG|0644, st_size=118, ...}) = 0&lt;br /&gt;21       0.000095 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7843000&lt;br /&gt;22       0.000050 read(3, "# Generated by NetworkManager\nna"..., 4096) = 118&lt;br /&gt;23       0.000086 read(3, "", 4096)         = 0&lt;br /&gt;24       0.000046 close(3)                  = 0&lt;br /&gt;25       [...]&lt;br /&gt;26       0.000173 open("/etc/host.conf", O_RDONLY) = 3&lt;br /&gt;27       0.000068 fstat64(3, {st_mode=S_IFREG|0644, st_size=26, ...}) = 0&lt;br /&gt;28       0.000081 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7843000&lt;br /&gt;29       0.000179 read(3, "multi on\norder hosts,bind\n", 4096) = 26&lt;br /&gt;30       0.000083 read(3, "", 4096)         = 0&lt;br /&gt;31       0.000048 close(3)                  = 0&lt;br /&gt;32       0.000049 munmap(0xb7843000, 4096)  = 0&lt;br /&gt;33       0.000160 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3&lt;br /&gt;34       0.000075 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, 16) = 0&lt;br /&gt;35       0.000640 gettimeofday({1325865284, 108850}, NULL) = 0&lt;br /&gt;36       0.000062 poll([{fd=3, events=POLLOUT}], 1, 0) = 1 ([{fd=3, revents=POLLOUT}])&lt;br /&gt;37       0.000094 send(3, "r\363\1\0\0\1\0\0\0\0\0\0\0011\0011\0011\0011\7in-addr\4arp"..., 38, MSG_NOSIGNAL) = 38&lt;br /&gt;38       0.000889 poll([{fd=3, events=POLLIN}], 1, 2000) = 0 (Timeout)&lt;br /&gt;39       2.003373 close(3)                  = 0&lt;br /&gt;40       0.000109 open("/etc/ld.so.cache", O_RDONLY) = 3&lt;br /&gt;41       0.000078 fstat64(3, {st_mode=S_IFREG|0644, st_size=72238, ...}) = 0&lt;br /&gt;42       0.000093 mmap2(NULL, 72238, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7821000&lt;br /&gt;43       0.000054 close(3)                  = 0&lt;br /&gt;44       [...]&lt;br /&gt;45       0.000105 open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3&lt;br /&gt;46       0.000097 fcntl64(3, F_GETFD)       = 0x1 (flags FD_CLOEXEC)&lt;br /&gt;47       0.000065 fstat64(3, {st_mode=S_IFREG|0644, st_size=438, ...}) = 0&lt;br /&gt;48       0.000053 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7843000&lt;br /&gt;49       0.000035 read(3, "127.0.0.1\tpacman.onlinedomus.net"..., 4096) = 438&lt;br /&gt;50       0.000137 read(3, "", 4096)         = 0&lt;br /&gt;51       0.000130 close(3)                  = 0&lt;br /&gt;52       [...]&lt;br /&gt;53       0.000101 write(1, "Unknown host (1.1.1.1). Took 2.0"..., 46) = 46&lt;br /&gt;54       0.000071 write(1, "Next: ", 6)     = 6&lt;br /&gt;55       0.000267 read(0, "1.1.1.2\n", 1024) = 8&lt;br /&gt;56       0.000071 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3&lt;br /&gt;57       0.000077 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, 16) = 0&lt;br /&gt;58       0.000049 poll([{fd=3, events=POLLOUT}], 1, 0) = 1 ([{fd=3, revents=POLLOUT}])&lt;br /&gt;59       0.000063 send(3, ":\243\1\0\0\1\0\0\0\0\0\0\0012\0011\0011\0011\7in-addr\4arp"..., 38, MSG_NOSIGNAL) = 38&lt;br /&gt;60       0.000152 poll([{fd=3, events=POLLIN}], 1, 2000) = 0 (Timeout)&lt;br /&gt;61       2.002550 close(3)                  = 0&lt;br /&gt;62       0.000088 open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3&lt;br /&gt;63       0.000077 fstat64(3, {st_mode=S_IFREG|0644, st_size=438, ...}) = 0&lt;br /&gt;64       0.000092 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7843000&lt;br /&gt;65       0.000057 read(3, "127.0.0.1\tpacman.onlinedomus.net"..., 4096) = 438&lt;br /&gt;66       0.000110 read(3, "", 4096)         = 0&lt;br /&gt;67       0.000049 close(3)                  = 0&lt;br /&gt;68       [...]&lt;br /&gt;69       0.000060 write(1, "Unknown host (1.1.1.2). Took 2.0"..., 46) = 46&lt;br /&gt;70       0.000076 write(1, "Next: ", 6)     = 6&lt;br /&gt;71       0.000253 read(0, "refresh\n", 1024) = 8&lt;br /&gt;72      17.639011 open("/etc/resolv.conf", O_RDONLY) = 3&lt;br /&gt;73       0.000088 fstat64(3, {st_mode=S_IFREG|0644, st_size=118, ...}) = 0&lt;br /&gt;74       0.000087 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7843000&lt;br /&gt;75       0.000052 read(3, "# Generated by NetworkManager\n#n"..., 4096) = 118&lt;br /&gt;76       0.000108 read(3, "", 4096)         = 0&lt;br /&gt;77       0.000047 close(3)                  = 0&lt;br /&gt;78       0.000048 munmap(0xb7843000, 4096)  = 0&lt;br /&gt;79       0.000065 write(1, "Called res_init()\n", 18) = 18&lt;br /&gt;80       0.000060 write(1, "Next: ", 6)     = 6&lt;br /&gt;81       0.000051 read(0, "1.1.1.3\n", 1024) = 8&lt;br /&gt;82       3.595382 gettimeofday({1325865312, 174933}, NULL) = 0&lt;br /&gt;83       0.000075 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3&lt;br /&gt;84       0.000078 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.5")}, 16) = 0&lt;br /&gt;85       0.000266 gettimeofday({1325865312, 175350}, NULL) = 0&lt;br /&gt;86       0.000052 poll([{fd=3, events=POLLOUT}], 1, 0) = 1 ([{fd=3, revents=POLLOUT}])&lt;br /&gt;87       0.000069 send(3, "\321\234\1\0\0\1\0\0\0\0\0\0\0013\0011\0011\0011\7in-addr\4arp"..., 38, MSG_NOSIGNAL) = 38&lt;br /&gt;88       0.000085 poll([{fd=3, events=POLLIN}], 1, 2000) = 0 (Timeout)&lt;br /&gt;89       2.002271 close(3)                  = 0&lt;br /&gt;90       0.000081 open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3&lt;br /&gt;91       0.000076 fstat64(3, {st_mode=S_IFREG|0644, st_size=438, ...}) = 0&lt;br /&gt;92       0.000087 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7843000&lt;br /&gt;93       0.000054 read(3, "127.0.0.1\tpacman.onlinedomus.net"..., 4096) = 438&lt;br /&gt;94       0.000091 read(3, "", 4096)         = 0&lt;br /&gt;95       0.000047 close(3)                  = 0&lt;br /&gt;96       0.000048 munmap(0xb7843000, 4096)  = 0&lt;br /&gt;97       0.000062 gettimeofday({1325865314, 178373}, NULL) = 0&lt;br /&gt;98       0.000058 write(1, "Unknown host (1.1.1.3). Took 2.0"..., 46) = 46&lt;br /&gt;99       0.000072 write(1, "Next: ", 6)     = 6&lt;br /&gt;100      0.000053 read(0, 0xb7844000, 1024) = ? ERESTARTSYS (To be restarted)&lt;br /&gt;101      0.918564 --- SIGINT (Interrupt) @ 0 (0) ---&lt;br /&gt;102      0.000931 +++ killed by SIGINT +++&lt;/pre&gt;&lt;br /&gt;E a explicação:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;Linhas 1-5 o programa arranca e pede o endereço IP. Dou-lhe 1.1.1.1&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Linhas 6-18 tenta contactar o serviço nscd (serviço de &lt;i&gt;caching&lt;/i&gt; em Linux) e depois abre e lê o ficheiro /etc/nsswitch.conf&lt;/li&gt;&lt;li&gt;Linhas 19-31 abre os outros dois ficheiros de configuração (/etc/resolv.conf e /etc/host.conf)&lt;/li&gt;&lt;li&gt;Linhas 33-44 contacta o servidor de DNS em 192.168.112.2 (timeout = 2s)&lt;/li&gt;&lt;li&gt;Linhas 45-52 lê /etc/hosts e imprime o resultado (Unknown host)&lt;/li&gt;&lt;li&gt;Linhas 53-68 é o mesmo, mas não lê os ficheiros de configuração pois já não é o primeiro pedido&lt;/li&gt;&lt;li&gt;Linhas 69-79 eu insiro "refresh" e o programa chama a res_init() e re-lê o /etc/resolv.conf. Entretanto, antes eu mudo no /etc/resolv.conf o servidor DNS para 192.168.112.5&lt;/li&gt;&lt;li&gt;Linhas 80-99 I insiro outro endereço IP (1.1.1.3) e vai contactar o novo servidor de DNS (192.168.112.5). Ao não obter uma resposta, re-lê o /etc/hosts.&lt;/li&gt;&lt;li&gt;Linhas 100-102 estava a pedir novamente um endereço IP e pressiono Control+C&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;i&gt;Hacking&lt;/i&gt; só por brincadeira!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Por favor não tente isto em casa! Atenção, o que vem a seguir é arriscado, não suportado e apresentado apenas para provar um ponto de vista. Argumentei acima que chamar a função res_init() permitiria que se mudasse os endereços dos servidores DNS sem parar e arrancar o Informix. Vamos prová-lo!&lt;br /&gt;Fiz novamente &lt;i&gt;trace&lt;/i&gt; a uma conexão, olhando para o processo do processador virtual da classe MSC. Obtive isto:&lt;br /&gt;&lt;pre&gt;socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3&lt;br /&gt;connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.2")}, 16) = 0&lt;br /&gt;gettimeofday({1326038028, 174740}, NULL) = 0&lt;br /&gt;poll([{fd=3, events=POLLOUT}], 1, 0)    = 1 ([{fd=3, revents=POLLOUT}])&lt;br /&gt;send(3, "+\316\1\0\0\1\0\0\0\0\0\0\0011\003112\003168\003192\7in-ad"..., 44, MSG_NOSIGNAL) = 44&lt;br /&gt;poll([{fd=3, events=POLLIN}], 1, 2000)  = 0 (Timeout)&lt;br /&gt;close(3)                                = 0&lt;br /&gt;open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 3&lt;br /&gt;fstat64(3, {st_mode=S_IFREG|0644, st_size=438, ...}) = 0&lt;br /&gt;mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x12f000&lt;br /&gt;read(3, "127.0.0.1\tpacman.onlinedomus.net"..., 4096) = 438&lt;br /&gt;close3)&lt;br /&gt;&lt;/pre&gt;Está a ligar-se ao 192.168.112.2, que é o servidor DNS definido no /etc/resolv.conf. Se eu mudar isso no ficheiro para 192.168.112.5 e tentar novamente, acontece o mesmo (não se apercebe da mudança). Mas agora, sem mais alterações no ficheiro, se correr um &lt;i&gt;debugger&lt;/i&gt; contra o processo do MSC:&lt;br /&gt;&lt;pre&gt;[root@pacman tmp]# gdb -p 4649&lt;br /&gt;GNU gdb (GDB) Fedora (7.1-18.fc13)&lt;br /&gt;Copyright (C) 2010 Free Software Foundation, Inc.&lt;br /&gt;License GPLv3+: GNU GPL version 3 or later &lt;http: gnu.org="" gpl.html="" licenses=""&gt;&lt;br /&gt;This is free software: you are free to change and redistribute it.&lt;br /&gt;There is NO WARRANTY, to the extent permitted by law.  Type "show copying"&lt;br /&gt;and "show warranty" for details.&lt;br /&gt;This GDB was configured as "i686-redhat-linux-gnu".&lt;br /&gt;For bug reporting instructions, please see:&lt;br /&gt;&amp;lt;http: bugs="" gdb="" software="" www.gnu.org=""&amp;gt;.&lt;br /&gt;Attaching to process 4649&lt;br /&gt;Reading symbols from /usr/informix/srvr1170uc4/bin/oninit...(no debugging symbols found)...done.&lt;/http:&gt;&lt;br /&gt;[...]&lt;br /&gt;(gdb) call __res_init()&lt;br /&gt;$1 = 0&lt;br /&gt;(gdb) detach&lt;br /&gt;Detaching from program: /usr/informix/srvr1170uc4/bin/oninit, process 4649&lt;br /&gt;(gdb) quit&lt;br /&gt;[root@pacman tmp]#&lt;br /&gt;&lt;/pre&gt;Se fizer um "call", ou seja chamar a função, a __res_init() que verifiquei ser o nome interno da função definida na libc.so e fizer um novo&amp;nbsp;&lt;i&gt;trace&lt;/i&gt; a uma conexão obtenho:&lt;br /&gt;&lt;pre&gt;socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3&lt;br /&gt;connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.112.5")}, 16) = 0&lt;br /&gt;gettimeofday({1326038409, 784712}, NULL) = 0&lt;br /&gt;poll([{fd=3, events=POLLOUT}], 1, 0)    = 1 ([{fd=3, revents=POLLOUT}])&lt;br /&gt;send(3, "\364K\1\0\0\1\0\0\0\0\0\0\0011\003112\003168\003192\7in-ad"..., 44, MSG_NOSIGNAL) = 44&lt;br /&gt;poll([{fd=3, events=POLLIN}], 1, 2000)  = 0 (Timeout)&lt;br /&gt;close(3)                                = 0&lt;br /&gt;open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 3&lt;br /&gt;fstat64(3, {st_mode=S_IFREG|0644, st_size=438, ...}) = 0&lt;br /&gt;mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x12f000&lt;br /&gt;read(3, "127.0.0.1\tpacman.onlinedomus.net"..., 4096) = 438&lt;br /&gt;close(3)&lt;br /&gt;&lt;/pre&gt;Ups! &lt;i&gt;Hacked!&lt;/i&gt;... Claro que isto não é suportado. Não tente isto numa instância "real". Apenas serve para provar uma teoria.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Conclusões&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O que tentei demonstrar neste artigo é como o Informix interage com os serviços de DNS, se os mesmos estiverem configurados no seu ambiente. Espero ter deixado claro que uma vez activo, o DNS toma um papel muito importante no estabelecimento de ligações. Tanto que um mau funcionamento do DNS terá um impacto muito significativo no sistema de gestão de base de dados. Há alguns pontos em que se pode atribuir responsabilidade ao Informix. Em particular:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;O facto de os pedidos de DNS inverso serem feitos pelo processador virtual da class MSC pode gerar atrasos em pedidos que poderiam correr bem, apenas porque um pedido anterior teve um problema. Ter mais de um processador virtual MSC pode aliviar isto significativamente, mas poderá não resolver por completo&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;O facto de o Informix não estabelecer &lt;i&gt;timeouts&lt;/i&gt; na chamada à gethostbyaddr() - ou equivalente -pode também causar atrasos desnecessários. Mas note-se que a assinatura das funções não tem nada que o permita, e portanto seria necessário criar um alarme que enviasse um sinal ao processo, e que este verificasse se ainda estava à espera da chamada. Isto traria um peso adicional que não faz muito sentido, especialmente quando os &lt;i&gt;timeouts&lt;/i&gt; podem ser configurados na configuração geral dos servidores de DNS&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;O facto de as funções chamadas fazerem &lt;i&gt;cache&lt;/i&gt; das configurações, aliado ao facto de o Informix não proporcionar uma forma de limpar essa &lt;i&gt;cache&lt;/i&gt; (havendo funcionalidades de baixo nível que o permitem), significa que uma mudança nos endereços de DNS requerem uma paragem e arranque do motor Informix. Existe um pedido de funcionalidade registado para isto e muito me agradaria que fosse implementado&lt;/li&gt;&lt;/ol&gt;Por outro lado, o Informix 11.7 introduziu uma excelente funcionalidade que permite aliviar quase todos os problemas.Com o parâmetro NS_CACHE podemos configurar tempos de &lt;i&gt;caching&lt;/i&gt; para vários sistemas (DNS, utilizadores/passwords, serviços...). Isto pode reduzir ao mímino o número de pedidos que são feitos. Naturalmente sempre que lidamos com &lt;i&gt;caches&lt;/i&gt; temos o risco de lidar com informação desactualizada, mas neste caso limpar as &lt;i&gt;caches&lt;/i&gt; é tão simples quanto correr o comando "onmode -wm NS_CACHE=..." e indicar um &lt;i&gt;timeout&lt;/i&gt; de zero segundos. Já agora, este seria um bom sitio/momento para forçar a chamada da função res_init()...&lt;br /&gt;&lt;br /&gt;Para fechar o artigo gostaria de mencionar algumas boas práticas:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Usar o Informix 11.7 se possível, para que possa tirar proveito do sistema de &lt;i&gt;caching&lt;/i&gt;. Os administradores de sistema e/ou de DNS irão apreciar isto se tiver uma taxa de novas ligações muito alta&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Considerar incluir "files" no ficheiro de configuração /etc/nsswitch.conf. Algumas pessoas podem considerar isto uma má ideia, pois pode causar muita actividade sobre o ficheiro /etc/hosts. Mas se as consultas ao ficheiro só forem feitas se os DNS não responderem, e o ficheiro fôr mantido com poucas entradas, e idealmente se usar o sistema de&amp;nbsp;&lt;i&gt;cache&lt;/i&gt; do Informix 11.7 o impacto adicional será negligenciável. E isto pode salvá-lo, caso tenha problemas nos DNS, pois temporariamente poderia adicionar entradas a este ficheiro, permitindo assim que a resolução de nomes fosse feita. Note que pelo menos no meu sistema de testes (Linux), mesmo a chamada à função res_init() não força a leitura novamente do ficheiro /etc/nsswitch.conf&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Faça com que os seus administradores de DNS e os DBAs se entendam... Terão de trabalhar em conjunto e têm de entender que os seus serviços estão intimamente ligados&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Use o Informix 11.7 se puder, para que possa usar o parâmetro REMOTE_SERVER_CFG. Em muitas empresas os DBAs não têm permissões para gerir o /etc/hosts.equiv (ficheiro de sistema). Se tiver um problema de DNS que impossibilite as conversões de endereços IP em nomes, as suas relações de confiança irão ser afetadas se estiverem definidas com nomes.e não endereços (o normal). Numa situação de emergência poderá ser útil que o DBA possa agir imediatamente e temporariamente adicionar os endereços IP ao ficheiro que estabelece as reações de confiança. Com o REMOTE_SERVER_CFG isso será possível sem privilégios de administrador de sistema&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Use &lt;i&gt;timeouts&lt;/i&gt; configurados no /etc/resolv.conf baixos de forma a que o tempo inútil de espera seja menor (uma consulta a um DNS é algo muito rápido)&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-4757346027332052570?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/4757346027332052570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=4757346027332052570' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/4757346027332052570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/4757346027332052570'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2012/01/dns-impact-on-informix-impacto-do-dns.html' title='DNS impact on Informix / Impacto do DNS no Informix'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-5486129368837451146</id><published>2011-12-22T00:15:00.000Z</published><updated>2011-12-22T00:38:37.460Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='query plan'/><category scheme='http://www.blogger.com/atom/ns#' term='plano execução'/><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='optimização'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><title type='text'>Small query performance analysis / Pequena análise de performance de querys</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;English version:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;The need...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The end of the year is typically a critical time for IT people. Following up on last article's I'm still working with performance issues. "Performance issues on Informix?!" I hear you say... Well yes, but to give you an idea of the kind of system I'm talking about I can say that recently we noticed three small tables (between 3 and 60 rows) that between mid-night and 11AM were scanned 33M times. To save you the math, that's around 833 scans/queries for each of these tables per second. And this started to happen recently, on top of the normal load that nearly 3000 sessions can generate...&lt;br /&gt;So, the point is: every bit of performance matters. And in most cases, on this system there are no long running queries. It's mostly very short requests made an incredible number of times. And yes, this makes the DBA life harder... If you have long running queries with bad query plans they're usually easy to spot. But if you have a large number of very quick queries, but with questionable query plans, than it's much more difficult to find.&lt;br /&gt;&lt;br /&gt;Just recently I had one of this situations. I've found a query with a questionable query plan. The query plan varies with the arguments and both possible options have immediate response times (fraction of a second). That's not the first time I've found something similar, and most of the times I face the same situation twice I usually decide I need to have some tool to help me on that.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;The idea!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The purpose was to see the difference in the work the engine does between two query plans. And when I say "tool" I'm thinking about a script. Last time I remember having this situation, I used a trick in dbaccess to obtain the performance counters for both the session, and the tables involved. Some of you probably know, others may not, but when dbaccess parses an SQL script file it can recognize a line starting with "!" as an instruction to execute the rest of the line as a SHELL command. So basically what I did previously was to customize the SQL script containing the query like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;!onstat -z&lt;/pre&gt;&lt;pre&gt;SELECT .... FROM .... WHERE ...&lt;/pre&gt;&lt;pre&gt;!some_shell_scritpt&lt;/pre&gt;&lt;br /&gt;where &lt;i&gt;some_shell_script&lt;/i&gt; had the ability to find the session and run an onstat -g tpf and also an onstat -g ppf. These two onstat commands show us a lot of performance counters respectively from the threads (tpf) and from the partitions (ppf). The output looks like:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;IBM Informix Dynamic Server Version 11.70.UC4 -- On-Line -- Up 7 days 23:42:15 -- 411500 Kbytes&lt;br /&gt;&lt;br /&gt;Thread profiles&lt;br /&gt;tid lkreqs lkw dl to lgrs isrd iswr isrw isdl isct isrb lx bfr bfw lsus lsmx seq&lt;br /&gt;24  0      0   0  0  0    0    0    0    0    0    0    0  0   0   0    0    0  &lt;br /&gt;26  0      0   0  0  0    0    0    0    0    0    0    0  95  95  0    0    0  &lt;br /&gt;51  32917  0   0  0  21101 13060 3512 57   532  3795 0    0  91215 29964 0    125008 4226&lt;br /&gt;52  39036  0   0  0  9099 11356 2648 80   1372 265  0    0  45549 9312 0    244900 21 &lt;br /&gt;49  705    0   0  0  574  8938 0    139  0    139  0    0  22252 148 0    5656 541&lt;br /&gt;2444 706    0   0  0  14   344  0    4    0    0    3    0  819 7   136  224  0  &lt;/pre&gt;&lt;br /&gt;This tells us the thread Id, lock requests, lock waits, deadlocks, timeouts, logical log records, isam calls (read, write, rewrite, delete, commit and rollback), long transactions, buffer reads and writes, logical log space used, logical log space maximum and sequential scans.&lt;br /&gt;And this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;panther@pacman.onlinedomus.com:informix-&amp;gt; onstat -g ppf | grep -v "0     0     0     0     0     0     0     0     0     0     0     0"&lt;br /&gt;&lt;br /&gt;IBM Informix Dynamic Server Version 11.70.UC4 -- On-Line -- Up 7 days 23:43:41 -- 411500 Kbytes&lt;br /&gt;&lt;br /&gt;Partition profiles&lt;br /&gt;partnum    lkrqs lkwts dlks  touts isrd  iswrt isrwt isdel bfrd  bfwrt seqsc rhitratio&lt;br /&gt;0x100001   0     0     0     0     0     0     0     0     13697 0     0     100&lt;br /&gt;0x100002   993   0     0     0     445   0     0     0     1460  0     2     100&lt;br /&gt;0x10002d   6769  0     0     0     2379  34    340   34    9094  581   2     100&lt;br /&gt;0x10002e   164   0     0     0     166   0     0     0     472   0     2     100&lt;br /&gt;0x10002f   2122  0     0     0     2750  0     0     0     5288  0     0     100&lt;br /&gt;0x100030   0     0     0     0     4     0     0     0     700   0     4     100&lt;br /&gt;0x100034   14192 0     0     0     5922  192   80    192   15566 1274  0     100&lt;br /&gt;0x100035   2260  0     0     0     188   80    0     80    2766  655   4     100&lt;br /&gt;0x100036   1350  0     0     0     548   34    0     34    1872  249   0     100&lt;br /&gt;0x100037   80    0     0     0     16    4     0     4     346   28    0     100&lt;br /&gt;0x100038   4720  0     0     0     738   360   0     360   3734  1557  0     100&lt;/pre&gt;&lt;br /&gt;which tells us some of the above, but for each partition.&lt;br /&gt;Note that I reset the counters, run the query and then obtain the profile counters. Ideally, nothing else should be running on the instance (better to do it on a test instance)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Sharing it&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But I decided to make this a bit easier and I created a script for doing it. I'm also using this article to announce that starting today, I'll try to keep my collection of scripts on a publicly available site:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://onlinedomus.com/informix/viewvc.cgi"&gt;http://onlinedomus.com/informix/viewvc.cgi&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This repository contains a reasonable amount of scripts for several purposes. Ideally I should create proper documentation and use cases for each one of them, but I currently don't have that. It's possible I'll cover some of them here in the blog, but probably only integrated in a wider article (like this one).&lt;br /&gt;&lt;br /&gt;These scripts were created by me (with one exception - setinfx was created by &lt;a href="http://levillageinformix.blogspot.com/" target="_blank"&gt;Eric Vercelleto&lt;/a&gt; when we were colleagues in Informix Portugal and we should thank him for allowing the distribution), during my free time and should all contain license info (&lt;a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html" target="_blank"&gt;GPL 2.0&lt;/a&gt;). This means you can use them, copy them, change them etc. Some of them are very old and may not contain this info.&lt;br /&gt;Some fixes and improvements were done during project engagements. Many of them were based on ideas I got from some scripts available in &lt;a href="http://www.iiug.org/software/index.html" target="_blank"&gt;IIUG's software repository&lt;/a&gt; or from colleagues ideas, problems and suggestions (Thanks specially to António Lima and Adelino Silva)&lt;br /&gt;&lt;br /&gt;It's important to notice that the scripts are available "as-is", no guarantees are made and I cannot be held responsible for any problem that it's use may cause.&lt;br /&gt;Having said that, I've been using most of them on several customers for years without problems.&lt;br /&gt;Any comments and/or suggestions are very welcome, and if I find the suggestions interesting and they don't break the script's ideas and usage, I'll be glad to incorporate them on future versions.&lt;br /&gt;&lt;br /&gt;Many of the scripts have two option switches that provide basic help (-h) and version info (-V).&lt;br /&gt;If by any chance you are using any of these scripts I suggest you check the site periodically to find any updates. I try my best to maintain retro-compatibility and old behavior when I make changes on them.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Back to the problem&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So, this article focus on analyzing and comparing the effects of running a query with two (or more) different query plans. The script created for this was ixprofiling. If you run it with -h (help) option it will print:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;panther@pacman.onlinedomus.com:fnunes-&amp;gt; ./ixprofiling -h&lt;br /&gt;ixprofiling [ -h | -V ]&lt;br /&gt;            -s SID database&lt;br /&gt;            [-z|-Z|-n] database sql_script&lt;br /&gt;     -h             : Get this help&lt;br /&gt;     -V             : Get script version&lt;br /&gt;     -s SID database: Get stats for session (SID) and database&lt;br /&gt;     -n             : Do NOT reset engine stats&lt;br /&gt;     -z             : Reset engine stats using onstat (default - needs local database)&lt;br /&gt;     -Z             : Reset engine stats using SQL Admin API (can work remotely )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Let's see what the options do:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;-s SID database&lt;br /&gt;Shows the info similar to onstat -g tpf (for the specified session id) and onstat -g ppf (for the specified database)&lt;br /&gt;It will show information for all the partition objects in the specified database for which any of the profile counters is different from zero. Note that when I write partition, it can be a table, a table's partition or a table's index.&lt;/li&gt;&lt;li&gt;database sql_script&lt;br /&gt;Runs the specified SQL script after making some changes that will (by default) reset the engine profile counters (-z option). See more information about the SQL script below&lt;/li&gt;&lt;li&gt;-n&lt;br /&gt;Prevents the reset of profile counters (if you're not a system database administrator you'll need to specify this to avoid errors)&lt;/li&gt;&lt;li&gt;-z&lt;br /&gt;Resets the profile counters using onstat -z. This is the quickest and most simple way to do it but will need local database access.&lt;/li&gt;&lt;li&gt;-Z&lt;br /&gt;Resets the counters using SQL admin API, so it can be used on remote databases&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;And now let's see an usage example. The script has some particularities that need to be detailed.&lt;br /&gt;First, since the idea is to compare two or more query plans we can put all the variations inside the SQL script, separating them by a line like:&lt;br /&gt;&lt;br /&gt;-- QUERY&lt;br /&gt;&lt;br /&gt;when the script finds these lines, it will automatically get the stats (from the previous query) and reset the counters to prepare for the next query. If you use just one query you don't need this, since by default it will reset the counters at the beginning and show the stats at the end.&lt;br /&gt;&lt;b&gt;If you put two or more queries on the script don't forget to end each query with ";" or it will break the functionality.&lt;/b&gt;&lt;br /&gt;Let's see a practical example. I have a table with the following structure:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;create table ibm_test_case &lt;br /&gt;  (&lt;br /&gt;    col1 integer,&lt;br /&gt;    col2 smallint not null ,&lt;br /&gt;    col3 integer,&lt;br /&gt;    col4 integer,&lt;br /&gt;[... irrelevant bits... ]&lt;br /&gt;    col13 datetime year to second,&lt;br /&gt;[... more irrelevant bits... ]&lt;br /&gt;  );&lt;br /&gt;&lt;br /&gt;create index ix_col3_col13 on ibm_test_case (col3,col13) using btree ;&lt;br /&gt;create index ix_col4 on ibm_test_case (col4) using btree ;&lt;/pre&gt;&lt;br /&gt;and a query like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;select c.col1&lt;br /&gt;from ibm_test_case c&lt;br /&gt;where&lt;br /&gt;        c.col3 = 123456789 and&lt;br /&gt;        c.col4 = 1234567 and&lt;br /&gt;        c.col13 = ( select max ( c2.col13 ) from ibm_test_case c2&lt;br /&gt;                where&lt;br /&gt;                        c2.col3 = c.col3 and&lt;br /&gt;                        c2.col4 = c.col4&lt;br /&gt;                );&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The problem is the query plan for the sub-query. It can choose between an index headed by col3 and another on col4. So I create a test_case.sql with:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;unload to /dev/null select c.col1&lt;br /&gt;from ibm_test_case c&lt;br /&gt;where&lt;br /&gt;        c.col3 = 123456789 and&lt;br /&gt;        c.col4 = 1234567 and&lt;br /&gt;        c.col13 = ( select max ( c2.col13 ) from ibm_test_case c2&lt;br /&gt;                where&lt;br /&gt;                        c2.col3 = c.col3 and&lt;br /&gt;                        c2.col4 = c.col4&lt;br /&gt;                );&lt;br /&gt;&lt;br /&gt;-- QUERY&lt;br /&gt;unload to /dev/null select c.col1&lt;br /&gt;from ibm_test_case c&lt;br /&gt;where&lt;br /&gt;        c.col3 = 123456789 and&lt;br /&gt;        c.col4 = 1234567 and&lt;br /&gt;        c.col13 = ( select --+ INDEX ( c2 ix_col3_col13 )&lt;br /&gt;                max ( c2.col13 ) from ibm_test_case c2&lt;br /&gt;                where&lt;br /&gt;                        c2.col3 = c.col3 and&lt;br /&gt;                        c2.col4 = c.col4&lt;br /&gt;                );&lt;/pre&gt;&lt;br /&gt;Note that on the second query I'm forcing the use of a particular index.&lt;br /&gt;Then we run:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;ixprofiling stores test_case.sql&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and we get the following output:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Database selected.&lt;br /&gt;&lt;br /&gt;Engine statistics RESETed. Query results:&lt;br /&gt;&lt;br /&gt;Explain set.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1 row(s) unloaded.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thread profiles (SID: 2690)&lt;br /&gt;LkReq LkWai DLks  TOuts LgRec IsRd  IsWrt IsRWr IsDel BfRd  BfWrt LgUse LgMax SeqSc Srts  DskSr SrtMx Sched CPU Time    Name        &lt;br /&gt;----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----------- ------------ &lt;br /&gt;5224  0     0     0     0     2611  0     0     0     2646  0     0     0     0     0     0     0     2170  0.051671256 sqlexec     &lt;br /&gt;&lt;br /&gt;Partitions profiles (Database: stores)&lt;br /&gt;LkReq LkWai DLks  TOuts DskRd DskWr IsRd  IsWrt IsRWr IsDel BfRd  BfWrt SeqSc Object name                                           &lt;br /&gt;----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ------------------------------------------------------&lt;br /&gt;6     0     0     0     0     0     2     0     0     0     10    0     0     systables&lt;br /&gt;2609  0     0     0     1933  0     2607  0     0     0     2609  0     0     ibm_test_case&lt;br /&gt;1     0     0     0     2     0     1     0     0     0     6     0     0     ibm_test_case#ix_col3_col13&lt;br /&gt;2608  0     0     0     3     0     1     0     0     0     21    0     0     ibm_test_case#ix_col4&lt;br /&gt;Engine statistics RESETed. Query results:&lt;br /&gt;&lt;br /&gt;1 row(s) unloaded.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thread profiles (SID: 2690)&lt;br /&gt;LkReq LkWai DLks  TOuts LgRec IsRd  IsWrt IsRWr IsDel BfRd  BfWrt LgUse LgMax SeqSc Srts  DskSr SrtMx Sched CPU Time    Name        &lt;br /&gt;----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----------- ------------ &lt;br /&gt;17    0     0     0     0     6     0     0     0     31    0     0     0     0     0     0     0     188   0.003161049 sqlexec     &lt;br /&gt;&lt;br /&gt;Partitions profiles (Database: stores)&lt;br /&gt;LkReq LkWai DLks  TOuts DskRd DskWr IsRd  IsWrt IsRWr IsDel BfRd  BfWrt SeqSc Object name                                           &lt;br /&gt;----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ------------------------------------------------------&lt;br /&gt;6     0     0     0     0     0     2     0     0     0     10    0     0     systables&lt;br /&gt;4     0     0     0     2     0     1     0     0     0     4     0     0     ibm_test_case&lt;br /&gt;7     0     0     0     0     0     6     0     0     0     17    0     0     ibm_test_case#ix_col3_col13&lt;/pre&gt;&lt;br /&gt;So, we can now analyze the differences. As you can see the output is more friendly than the output from onstat. On the session section we can see the usual counters, plus the number of times the engine scheduled the thread(s) to run, the CPU time consumed and the name of the threads.&lt;br /&gt;On the tables/partitions section, we can find the partition, table or index name in a friendly nomenclature (instead of the partnum).&lt;br /&gt;As for the comparison, you can spot a big difference. Much more buffer reads and ISAM reads for the first query plan and also a bigger CPU time. Be aware however that for very fast queries the CPU times may show very big variance so don't assume a lower CPU time is always associated with the better query plan. You should repeat the test many times to see the oscillations.&lt;br /&gt;Also note that the meaning of ISAM calls is many times misunderstood. Some people think it's the number of "SELECTs", others the number of rows returned... In reality it's the number of internal functions calls. Some engine settings like BATCHEDREAD_TABLE and BATCHEDREAD_INDEX may influence the number of calls for the same query and query result.&lt;br /&gt;&lt;br /&gt;That's all for now. I leave you with the repository and hopefully future articles will focus on some of these scripts. Feel free to use them and send me you suggestions.&lt;br /&gt;&lt;br /&gt;&lt;div style="color: blue;"&gt;Versão Portuguesa:&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;A necessidade...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O fina do ano é tipicamente uma altura critica para os informáticos. Continuando no mesmo tema do último artigo, continuo a trabalhar com problemas de &lt;i&gt;performance&lt;/i&gt;. "Problemas de &lt;i&gt;performance&lt;/i&gt; em Informix?!" poderão estar a pensar... Bem, sim, mas para vos dar uma ideia do sistema sobre o qual estou a falar, posso dizer que recentemente notámos três pequenas tabelas (entre 3 e 60 linhas) que entre a meia-noite e as onze da manhã eram varridas (&lt;i&gt;sequential scan&lt;/i&gt;) 33M de vezes. Para poupar nas contas posso já dizer que dá cerca de 833 &lt;i&gt;scans/queries&lt;/i&gt; por segundo para cada uma das tabelas. E isto começou a acontecer recentemente sobre a carga "normal" que perto de 3000 sessões podem criar.&lt;br /&gt;Portanto, a ideia é que cada bocadinho de &lt;i&gt;performance&lt;/i&gt; tem impacto. Na maioria dos casos, este sistema não tem queries longas. Na maior parte das vezes os problemas são pedidos com curta duração mas feitos um imenso número de vezes. E sim, isto torna a vida dos DBAs mais dicfícil... Se tivermos queries longas com maus planos de execução são normalmente fáceis de identificar. Mas se tivermos um grande número de queries muito curtas, com um plano de execução questionável, isso é muito mais difícil de encontrar.&lt;br /&gt;&lt;br /&gt;Ainda recentemente tive uma dessas situações. Detectei uma query com um plano de execução duvidoso. O plano de execução varia com os parâmetros usados e ambas as alternativas têm um tempo de resposta "imediato" (fracção de segundo). Não foi a primeira vez que encontrei algo semelhante, e na maioria dos casos em que enfrento uma situação duas vezes, normalmente decido que preciso de alguma ferramenta que me ajude no futuro. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;A ideia!&lt;/span&gt;&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O objectivo era evidenciar a diferença no trabalho feito pelo motor entre dois planos de execução. E quando refiro "ferramenta" estou a pensar num &lt;i&gt;script&lt;/i&gt;. A última vez que me lembro de ter tido uma situação destas&amp;nbsp; usei um truque no &lt;i&gt;dbaccess&lt;/i&gt; para obter os indicadores de &lt;i&gt;performance&lt;/i&gt; tanto para a sessão como para as tabelas envolvidas.&lt;br /&gt;Alguns de vós saberão, outros não, mas quando o &lt;i&gt;dbaccess&lt;/i&gt; lê um &lt;i&gt;scritpt&lt;/i&gt; SQL pode reconhecer uma linha começada com "!" como uma instrução para executar o resto da linha como um comando SHELL. Assim, o que fiz em situações anteriores foi alterar o &lt;i&gt;script&lt;/i&gt; SQL que continha a query para algo do género:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;!onstat -z&lt;/pre&gt;&lt;pre&gt;SELECT .... FROM .... WHERE ...&lt;/pre&gt;&lt;pre&gt;!um_shell_scritpt&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;onde &lt;i&gt;um_shell_script&lt;/i&gt; tem a capacidade de encontrar a sessão e correr um &lt;i&gt;onstat -g tpf&lt;/i&gt; e também um &lt;i&gt;onstat -g ppf&lt;/i&gt;. Ests dois comandos mostram-nos uma série de contadores de &lt;i&gt;performance&lt;/i&gt; respectivamente da sessão/thread (tpf) e das partições (ppf). O &lt;i&gt;output&lt;/i&gt; é semelhante a isto:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;IBM Informix Dynamic Server Version 11.70.UC4 -- On-Line -- Up 7 days 23:42:15 -- 411500 Kbytes&lt;br /&gt;&lt;br /&gt;Thread profiles&lt;br /&gt;tid lkreqs lkw dl to lgrs isrd iswr isrw isdl isct isrb lx bfr bfw lsus lsmx seq&lt;br /&gt;24  0      0   0  0  0    0    0    0    0    0    0    0  0   0   0    0    0  &lt;br /&gt;26  0      0   0  0  0    0    0    0    0    0    0    0  95  95  0    0    0  &lt;br /&gt;51  32917  0   0  0  21101 13060 3512 57   532  3795 0    0  91215 29964 0    125008 4226&lt;br /&gt;52  39036  0   0  0  9099 11356 2648 80   1372 265  0    0  45549 9312 0    244900 21 &lt;br /&gt;49  705    0   0  0  574  8938 0    139  0    139  0    0  22252 148 0    5656 541&lt;br /&gt;2444 706    0   0  0  14   344  0    4    0    0    3    0  819 7   136  224  0  &lt;/pre&gt;&lt;br /&gt;É-nos mostrado o ID da &lt;i&gt;thread&lt;/i&gt;, número de pedidos de &lt;i&gt;lock&lt;/i&gt;, esperas em &lt;i&gt;locks&lt;/i&gt;, &lt;i&gt;deadlocks&lt;/i&gt;, &lt;i&gt;lock timeouts&lt;/i&gt;, chamadas ISAM (leitura, escrita, re-escrita, apagar, &lt;i&gt;commit&lt;/i&gt; e &lt;i&gt;rollback&lt;/i&gt;), transacções longas, leituras e escritas de &lt;i&gt;buffers&lt;/i&gt;, espaço usado em &lt;i&gt;logical logs&lt;/i&gt; e máximo espaço usado em &lt;i&gt;logical logs&lt;/i&gt; e número de &lt;i&gt;sequential scans&lt;/i&gt;. E isto:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;panther@pacman.onlinedomus.com:informix-&amp;gt; onstat -g ppf | grep -v "0     0     0     0     0     0     0     0     0     0     0     0"&lt;br /&gt;&lt;br /&gt;IBM Informix Dynamic Server Version 11.70.UC4 -- On-Line -- Up 7 days 23:43:41 -- 411500 Kbytes&lt;br /&gt;&lt;br /&gt;Partition profiles&lt;br /&gt;partnum    lkrqs lkwts dlks  touts isrd  iswrt isrwt isdel bfrd  bfwrt seqsc rhitratio&lt;br /&gt;0x100001   0     0     0     0     0     0     0     0     13697 0     0     100&lt;br /&gt;0x100002   993   0     0     0     445   0     0     0     1460  0     2     100&lt;br /&gt;0x10002d   6769  0     0     0     2379  34    340   34    9094  581   2     100&lt;br /&gt;0x10002e   164   0     0     0     166   0     0     0     472   0     2     100&lt;br /&gt;0x10002f   2122  0     0     0     2750  0     0     0     5288  0     0     100&lt;br /&gt;0x100030   0     0     0     0     4     0     0     0     700   0     4     100&lt;br /&gt;0x100034   14192 0     0     0     5922  192   80    192   15566 1274  0     100&lt;br /&gt;0x100035   2260  0     0     0     188   80    0     80    2766  655   4     100&lt;br /&gt;0x100036   1350  0     0     0     548   34    0     34    1872  249   0     100&lt;br /&gt;0x100037   80    0     0     0     16    4     0     4     346   28    0     100&lt;br /&gt;0x100038   4720  0     0     0     738   360   0     360   3734  1557  0     100&lt;/pre&gt;&lt;br /&gt;que nos mostra alguns dos contadores anteriores, mas por partição.&lt;br /&gt;Note-se que re-inicializo os contadores, corro a &lt;i&gt;query&lt;/i&gt; e depois obtenho os outputs. Idealmente não deverá estar mais nada a correr na instância (é preferível usar uma instância de teste).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Partilha&lt;/span&gt;&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Mas decidi tornar isto um pouco mais fácil e criei um &lt;i&gt;script&lt;/i&gt; para o fazer. Estou também a usar este artigo para anunciar que a partir de hoje, tentarei manter a minha colecção de &lt;i&gt;scripts&lt;/i&gt; disponível num &lt;i&gt;site&lt;/i&gt; público:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://onlinedomus.com/informix/viewvc.cgi"&gt;http://onlinedomus.com/informix/viewvc.cgi&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Este repositório contém uma quantidade razoável de &lt;i&gt;scripts&lt;/i&gt; e outras ferramentas úteis para várias tareafas. Idealmente eu deveria criar documentação e casos de uso para cada um deles, mas de momento isso não está feito. É possível que vá descrevendo alguns destes scripts em futuros artigos, mas sempre integrados em assuntos mais vastos (como este)&lt;br /&gt;&lt;br /&gt;Estes &lt;i&gt;scripts&lt;/i&gt; foram criados por mim (com uma excepção - setinfx foi criado por &lt;a href="http://levillageinformix.blogspot.com/" target="_blank"&gt;Eric Vercelletto&lt;/a&gt; quando éramos colegas na Informix Portugal e devemos agradecer-lhe por permitir a distribuição), durante os meus tempos livres e devem conter informação de licenciamento (&lt;a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html" target="_blank"&gt;GPL 2.0&lt;/a&gt;). Isto quer dizer que podem ser usados, distribuidos, alterados etc.). Alguns podem não ter esta informação por serem muito antigos.&lt;br /&gt;Naturalmente algumas correcções e melhorias foram feitas durante projectos em clientes, sempre que detecto algum erro ou hipótese de melhoria no seu uso. Muitos deles foram baseados em ideias que obtive de &lt;i&gt;scripts&lt;/i&gt; existents no &lt;a href="http://www.iiug.org/software/index.html" target="_blank"&gt;repositório do IIUG&lt;/a&gt;, ou de ideias, problemas e sugestões de colegas (agradecimento especial ao António Lima e ao Adelino Silva)&lt;br /&gt;&lt;br /&gt;É importante avisar que os &lt;i&gt;scripts&lt;/i&gt; são disponiblizados "como são", sem qualquer tipo de garantia implicita ou explicita e eu não posso ser responsabilizado por qualquer problema que advenha do seu uso. Posto isto, convém também dizer que a maioria dos scripts têm sido usados por mim em clientes ao longo de anos, sem problemas.&lt;br /&gt;&lt;br /&gt;Quaisquer comentários e/ou sugestões são bem vindas, e se os achar interessantes terei todo o prazer em os incorportar em futuras versões (desde que não fujam à lógica e utilização do &lt;i&gt;script&lt;/i&gt;)&lt;br /&gt;Muitos destes &lt;i&gt;scripts&lt;/i&gt; disponibilizam duas opções que fornecem ajuda básica (-h) e informação sobre a versão (-V).&lt;br /&gt;Se utilizar algum destes &lt;i&gt;scripts&lt;/i&gt; no seu ambiente, sugiro que verifique periodicamente se houve correcções ou melhorias, consultando o &lt;i&gt;site&lt;/i&gt; com alguma regularidade. Sempre que possível evito que novas funcionalidades alterem o comportamento do &lt;i&gt;script&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;De volta ao problema&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Este artigo foca a análise e comparação dos efeitos de executar uma query com dois (ou mais) planos de execução. O &lt;i&gt;script&lt;/i&gt; criado para isso chama-se &lt;i&gt;ixprofiling&lt;/i&gt;. Se corrido com a opção -h (&lt;i&gt;help&lt;/i&gt;) mostra-nos:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;panther@pacman.onlinedomus.com:fnunes-&amp;gt; ./ixprofiling -h&lt;br /&gt;ixprofiling [ -h | -V ]&lt;br /&gt;            -s SID database&lt;br /&gt;            [-z|-Z|-n] database sql_script&lt;br /&gt;     -h             : Get this help&lt;br /&gt;     -V             : Get script version&lt;br /&gt;     -s SID database: Get stats for session (SID) and database&lt;br /&gt;     -n             : Do NOT reset engine stats&lt;br /&gt;     -z             : Reset engine stats using onstat (default - needs local database)&lt;br /&gt;     -Z             : Reset engine stats using SQL Admin API (can work remotely )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Vejamos o que fazem as opções:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;-s SID base_dados&lt;br /&gt;Mostra informação semelhante ao &lt;i&gt;onstat -g tpf&lt;/i&gt; (para a sessão indicada por SID) e &lt;i&gt;onstat -g ppf&lt;/i&gt; (para a base de dados indicada)&lt;br /&gt;Irá mostrar informação para todas as partições na base de dados escolhida, para as quais exista pelo menos um dos contadores com valor diferente de zero. Note-se que quando refiro partição estou a referir-me a uma tabela, a um fragmento de tabela fragmentada (ou se preferir particionada) ou a um indíce.&lt;/li&gt;&lt;li&gt;base_dados script_sql&lt;br /&gt;Corre o &lt;i&gt;script&lt;/i&gt; SQL indicado, fazendo alterações que irão (por omissão), re-inicializar os contadores de &lt;i&gt;performance&lt;/i&gt; do motor (opção -z). Veja mais informação sobre o &lt;i&gt;script&lt;/i&gt; SQL abaixo&lt;/li&gt;&lt;li&gt;-n&lt;br /&gt;Evita a re-inicialização dos contadores de &lt;i&gt;performance&lt;/i&gt; (se não fôr administrador do sistema de base de dados terá de usar esta opção para evitar erros)&lt;/li&gt;&lt;li&gt;-z&lt;br /&gt;Faz a re-inicialização dos contadores do motor usando o comando &lt;i&gt;onstat -z&lt;/i&gt;. Esta é a forma mais simples e rápida de o fazer, mas requer que a base de dados seja local&lt;/li&gt;&lt;li&gt;-Z&lt;br /&gt;Faz a re-inicialização dos contadores utilizando a SQL Admin API, de forma que possa ser feito com bases de dados remotas&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;E agora vejamos um exemplo de uso. O &lt;i&gt;script&lt;/i&gt; tem algumas particularidades que merecem ser datalhadas.&lt;br /&gt;Primeiro e porque a ideia é comparar dois ou mais planos de execução, podemos colocar todas as variantes de plano de execução&amp;nbsp; dentro do mesmo &lt;i&gt;script&lt;/i&gt; SQL usando uma linha como esta para separar as &lt;i&gt;queries&lt;/i&gt;:&lt;br /&gt;&lt;br /&gt;-- QUERY&lt;br /&gt;&lt;br /&gt;Estas linhas são automaticamente substituídas por comandos que obtêm os contadores actuais (da &lt;i&gt;query&lt;/i&gt; anterior) e que re-inicializam os mesmos contadores preparando a execução seguinte. Se usar apenas uma &lt;i&gt;query&lt;/i&gt; não é necessário isto, pois por omissão a re-inicialização dos contadores é feita no início, e após a última &lt;i&gt;query&lt;/i&gt; são automaticamente mostrados os contadores.&lt;br /&gt;&lt;b&gt;Se colocar duas ou mais&amp;nbsp;&lt;i&gt;queries&lt;/i&gt;&lt;/b&gt;&lt;b&gt; no&amp;nbsp;&lt;i&gt;script&lt;/i&gt;&lt;/b&gt;&lt;b&gt; não se esqueça de terminar cada uma com ";" ou o&amp;nbsp;&lt;i&gt;script&lt;/i&gt;&lt;/b&gt;&lt;b&gt; não funcionará como esperado.&lt;/b&gt;&lt;br /&gt;Vamos ver um exemplo prático. Tenho uma tabela com a seguinte estrutura:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;create table ibm_test_case &lt;br /&gt;  (&lt;br /&gt;    col1 integer,&lt;br /&gt;    col2 smallint not null ,&lt;br /&gt;    col3 integer,&lt;br /&gt;    col4 integer,&lt;br /&gt;[... parte irrelevante ... ]&lt;br /&gt;    col13 datetime year to second,&lt;br /&gt;[... mais colunas irrelevantes ... ]&lt;br /&gt;  );&lt;br /&gt;&lt;br /&gt;create index ix_col3_col13 on ibm_test_case (col3,col13) using btree ;&lt;br /&gt;create index ix_col4 on ibm_test_case (col4) using btree ;&lt;/pre&gt;&lt;br /&gt;e uma &lt;i&gt;query&lt;/i&gt; com:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;select c.col1&lt;br /&gt;from ibm_test_case c&lt;br /&gt;where&lt;br /&gt;        c.col3 = 123456789 and&lt;br /&gt;        c.col4 = 1234567 and&lt;br /&gt;        c.col13 = ( select max ( c2.col13 ) from ibm_test_case c2&lt;br /&gt;                where&lt;br /&gt;                        c2.col3 = c.col3 and&lt;br /&gt;                        c2.col4 = c.col4&lt;br /&gt;                );&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;O problem é o plano de execução da &lt;i&gt;sub-query&lt;/i&gt;. Pode&amp;nbsp; escolher entre um índice começado pela coluna col3 e outro pela coluna col4. Por isso crio um ficheiro, caso_teste.sql com:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;unload to /dev/null select c.col1&lt;br /&gt;from ibm_test_case c&lt;br /&gt;where&lt;br /&gt;        c.col3 = 123456789 and&lt;br /&gt;        c.col4 = 1234567 and&lt;br /&gt;        c.col13 = ( select max ( c2.col13 ) from ibm_test_case c2&lt;br /&gt;                where&lt;br /&gt;                        c2.col3 = c.col3 and&lt;br /&gt;                        c2.col4 = c.col4&lt;br /&gt;                );&lt;br /&gt;&lt;br /&gt;-- QUERY&lt;br /&gt;unload to /dev/null select c.col1&lt;br /&gt;from ibm_test_case c&lt;br /&gt;where&lt;br /&gt;        c.col3 = 123456789 and&lt;br /&gt;        c.col4 = 1234567 and&lt;br /&gt;        c.col13 = ( select --+ INDEX ( c2 ix_col3_col13 )&lt;br /&gt;                max ( c2.col13 ) from ibm_test_case c2&lt;br /&gt;                where&lt;br /&gt;                        c2.col3 = c.col3 and&lt;br /&gt;                        c2.col4 = c.col4&lt;br /&gt;                );&lt;/pre&gt;&lt;br /&gt;Repare&amp;nbsp; que na segunda &lt;i&gt;query&lt;/i&gt; estou a forçar o uso de um determinado índice:&lt;br /&gt;Depois corro:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;ixprofiling stores caso_teste.sql&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;e obtemos o seguinte:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Database selected.&lt;br /&gt;&lt;br /&gt;Engine statistics RESETed. Query results:&lt;br /&gt;&lt;br /&gt;Explain set.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1 row(s) unloaded.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thread profiles (SID: 2690)&lt;br /&gt;LkReq LkWai DLks  TOuts LgRec IsRd  IsWrt IsRWr IsDel BfRd  BfWrt LgUse LgMax SeqSc Srts  DskSr SrtMx Sched CPU Time    Name        &lt;br /&gt;----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----------- ------------ &lt;br /&gt;5224  0     0     0     0     2611  0     0     0     2646  0     0     0     0     0     0     0     2170  0.051671256 sqlexec     &lt;br /&gt;&lt;br /&gt;Partitions profiles (Database: stores)&lt;br /&gt;LkReq LkWai DLks  TOuts DskRd DskWr IsRd  IsWrt IsRWr IsDel BfRd  BfWrt SeqSc Object name                                           &lt;br /&gt;----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ------------------------------------------------------&lt;br /&gt;6     0     0     0     0     0     2     0     0     0     10    0     0     systables&lt;br /&gt;2609  0     0     0     1933  0     2607  0     0     0     2609  0     0     ibm_test_case&lt;br /&gt;1     0     0     0     2     0     1     0     0     0     6     0     0     ibm_test_case#ix_col3_col13&lt;br /&gt;2608  0     0     0     3     0     1     0     0     0     21    0     0     ibm_test_case#ix_col4&lt;br /&gt;Engine statistics RESETed. Query results:&lt;br /&gt;&lt;br /&gt;1 row(s) unloaded.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thread profiles (SID: 2690)&lt;br /&gt;LkReq LkWai DLks  TOuts LgRec IsRd  IsWrt IsRWr IsDel BfRd  BfWrt LgUse LgMax SeqSc Srts  DskSr SrtMx Sched CPU Time    Name        &lt;br /&gt;----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----------- ------------ &lt;br /&gt;17    0     0     0     0     6     0     0     0     31    0     0     0     0     0     0     0     188   0.003161049 sqlexec     &lt;br /&gt;&lt;br /&gt;Partitions profiles (Database: stores)&lt;br /&gt;LkReq LkWai DLks  TOuts DskRd DskWr IsRd  IsWrt IsRWr IsDel BfRd  BfWrt SeqSc Object name                                           &lt;br /&gt;----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ------------------------------------------------------&lt;br /&gt;6     0     0     0     0     0     2     0     0     0     10    0     0     systables&lt;br /&gt;4     0     0     0     2     0     1     0     0     0     4     0     0     ibm_test_case&lt;br /&gt;7     0     0     0     0     0     6     0     0     0     17    0     0     ibm_test_case#ix_col3_col13&lt;/pre&gt;&lt;br /&gt;Então, podemos agora analisar as diferenças. Como se pode ver o resultado é mais simpático que o do &lt;i&gt;onstat&lt;/i&gt;. Na secção relativa à sessão, podemos ver os contadores habituais, mais o número de vezes que o motor escalonou a &lt;i&gt;thread&lt;/i&gt; para correr, e o tempo de CPU consumido, bem como o nome das &lt;i&gt;threads&lt;/i&gt;&lt;br /&gt;Na secção destinada às partições podemos encontrar os nomes das tabelas, partições ou indíces numa nomenclatura fácil de entender (em vez do &lt;i&gt;partnum&lt;/i&gt;).&lt;br /&gt;Sobre a comparação, podemos ver uma grande diferença. Muitos mais leituras de &lt;i&gt;buffers&lt;/i&gt; e chamadas ISAM para o primeiro plano de execução e também mais consumo de CPU. Mas atenção que para &lt;i&gt;queries&lt;/i&gt; muito rápidas os tempos de CPU podem apresentar uma variação muito grande. Por isso convém não assumir imediatamente que um plano de execução é melhor porque se vê um tempo de CPU menor na primeira interação. Deve repetir-se o teste muitas vezes para se verificar as oscilações.&lt;br /&gt;Chamo também a atenção para o significado das chamadas ISAM. Muitas vezes vejo confusões sobre este tema. Algumas pessoas pensam que são o número de SELECTs (para os ISAM &lt;i&gt;reads&lt;/i&gt;), ou que serão o número de linhas retornadas... Na realidade é o número de chamadas a funções internas. Algumas configurações do motor como BATCHEDREAD_TABLE e BATCHEDREAD_INDEX podem influenciar o número destas chamadas, para a mesma &lt;i&gt;query&lt;/i&gt; e mesmo conjunto de resultados.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;É tudo por agora. Deixo-lhe o repositório e a esperança que artigos futuros se foquem em alguns destes &lt;i&gt;scripts&lt;/i&gt;. Use-os à vontade e envie quaisquer sugestões.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-5486129368837451146?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/5486129368837451146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=5486129368837451146' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/5486129368837451146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/5486129368837451146'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/12/small-query-performance-analisys.html' title='Small query performance analysis / Pequena análise de performance de querys'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-1254248432278605335</id><published>2011-12-10T15:02:00.001Z</published><updated>2011-12-15T00:53:12.744Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='datatype precedence'/><category scheme='http://www.blogger.com/atom/ns#' term='peformance'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='implicito'/><category scheme='http://www.blogger.com/atom/ns#' term='join'/><category scheme='http://www.blogger.com/atom/ns#' term='implicit'/><category scheme='http://www.blogger.com/atom/ns#' term='cast'/><category scheme='http://www.blogger.com/atom/ns#' term='optimizer'/><category scheme='http://www.blogger.com/atom/ns#' term='optimizador'/><title type='text'>Optimizer secrets / segredos do optimizador</title><content type='html'>&lt;div class="tr_bq"&gt;This article is written in English and Portuguese &lt;/div&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;&lt;div style="color: blue;"&gt;English version:&lt;/div&gt;&lt;br /&gt;Spending a lot of time with customers is great. It gives me time to go beyond the strict task execution that short projects allow. We actually have time to dive deep into what sometimes looks only as a curiosity. I'll describe one of this situations in this post. It started out as a normal performance issue. A query involving a join was causing an hash join and apparently there was an index that could be used. Some quick investigation showed that the datatypes didn't match on the join columns, and as such the index was not being used.&lt;br /&gt;The situation was fixed (using an explicit cast since changing the datatypes would require more deep analysis) and the programmer(s) received an explanation about the issue so that future situations would be avoided. Simple right? Yes... But when you have inquiring minds and programmers with a few minutes to spare you may be surprised. And this was the case. A few weeks later the DBA team received a request to explain why we recommended that the columns used in joins should have the same datatype. A programmer had produced a testcase where the engine was able to convert the parameter sent and use the index. In other words, if the engine is smart enough why should we care?!&lt;br /&gt;&lt;br /&gt;Although this could be considered a waste of time (using the same datatypes or explicit cast is a good practice, right?!) the question was interesting enough to make us spend some time with it. In fact I had seen situations in the past where apparently sometimes the engine was smart, and others not. I never thought too much about it, since I always recommended to follow the best practices (which clearly saves us some troubles). So, personally I also had this doubt, and together with the customer DBAs we started to do some tests. We came up with a very simple test case that we though would show the problem:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;DATABASE stores;&lt;br /&gt;&lt;br /&gt;DROP TABLE IF EXISTS tst_int;&lt;br /&gt;DROP TABLE IF EXISTS tst_char;&lt;br /&gt;&lt;br /&gt;CREATE TABLE tst_int&lt;br /&gt;(&lt;br /&gt;    c1 INTEGER,&lt;br /&gt;    c2 INTEGER&lt;br /&gt;);&lt;br /&gt;CREATE TABLE tst_char&lt;br /&gt;(&lt;br /&gt;    c1 CHAR(15),&lt;br /&gt;    c2 INTEGER&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;INSERT INTO tst_int&lt;br /&gt;SELECT FIRST 2000 pg_pagenum, pg_partnum FROM sysmaster:syspaghdr;&lt;br /&gt;&lt;br /&gt;INSERT INTO tst_char&lt;br /&gt;SELECT FIRST 2000 pg_pagenum, pg_partnum FROM sysmaster:syspaghdr;&lt;br /&gt;&lt;br /&gt;CREATE INDEX i_tst_int ON tst_int(c1);&lt;br /&gt;CREATE INDEX i_tst_char ON tst_char(c1);&lt;br /&gt;&lt;br /&gt;SET EXPLAIN ON;&lt;br /&gt;SELECT "tst_int with char parameter:", * FROM tst_int WHERE c1 = '12345678';&lt;br /&gt;SELECT "tst_char whth int parameter",* FROM tst_char WHERE c1 = 12345678;&lt;br /&gt;&lt;br /&gt;--- demonstrates that each index key is being casted&lt;br /&gt;INSERT INTO tst_char VALUES("a1", 12345678);&lt;br /&gt;SELECT * FROM tst_char WHERE c1 = 12345678;&lt;/pre&gt;&lt;br /&gt;If we take a look at the query plan we see:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;QUERY: (OPTIMIZATION TIMESTAMP: 12-10-2011 23:25:19)&lt;br /&gt;------&lt;br /&gt;SELECT "tst_int with char parameter:", * FROM tst_int WHERE c1 = '12345678'&lt;br /&gt;&lt;br /&gt;Estimated Cost: 1&lt;br /&gt;Estimated # of Rows Returned: 1&lt;br /&gt;&lt;br /&gt;  1) informix.tst_int: INDEX PATH&lt;br /&gt;&lt;br /&gt;    (1) Index Name: informix.i_tst_int&lt;br /&gt;        Index Keys: c1   (Serial, fragments: ALL)&lt;br /&gt;        Lower Index Filter: informix.tst_int.c1 = 12345678&lt;/pre&gt;&lt;br /&gt;So here the engine was "smart". Meaning it converted the CHAR to an INTEGER and that allowed it to use the index. Nice.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;But here:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;QUERY: (OPTIMIZATION TIMESTAMP: 12-10-2011 23:25:19)&lt;br /&gt;------&lt;br /&gt;SELECT "tst_char whth int parameter",* FROM tst_char WHERE c1 = 12345678&lt;br /&gt;&lt;br /&gt;Estimated Cost: 84&lt;br /&gt;Estimated # of Rows Returned: 1&lt;br /&gt;&lt;br /&gt;  1) informix.tst_char: SEQUENTIAL SCAN&lt;br /&gt;&lt;br /&gt;        Filters: informix.tst_char.c1 = 12345678&lt;/pre&gt;&lt;br /&gt;It looks as it's not that smart... Instead of converting the INTEGER parameter to a CHAR and use the index it decides to do the opposite: Converts all the CHARs in that column into INTEGERs and makes a SEQUENTIAL SCAN.&lt;br /&gt;Since I didn't have a good explanation for this we decided to open a PMR to get an official technical support explanation.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Technical support reported that we had something in the documentation that tries to explain this:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.sqls.doc/ids_sqs_1620.htm"&gt;http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.sqls.doc/ids_sqs_1620.htm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This documentation is highly confusing but it tells us something important: If we use a numeric filter against a CHAR column, the database server will convert all the CHAR values to numbers. This is precisely what we saw in the example above. But it still does not explain why. Let me show why with a few examples:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;If we have "00123" in the table and we give 123 as the parameter, if we convert the number to CHAR and try to match it, ir would fail. Bad results...&lt;/li&gt;&lt;li&gt;If we have "234" in the column and we give 9 as the parameter for a "less or equal" (col &amp;lt;= 9), if we convert the number to CHAR, and apply the filter to the CHAR type, it would match ("9" &amp;gt;= "234"). Again it would return an incorrect result because by using an INTEGER as a parameter we're assuming INTEGER comparison&lt;/li&gt;&lt;/ol&gt;So, after this, the rule would seem pretty simple. Something like: "If you use a numeric parameter against a CHAR column, all the values in the column will be converted to numeric.&amp;nbsp; On the other hand, using a CHAR parameter against a numeric column allows the engine to convert the numeric to CHAR and if there is an index on the column it can be used".&lt;br /&gt;&lt;br /&gt;But life's not that simple... If it was so simple why couldn't we find it in the documentation? I tried to search for other RDBMS (Oracle and MS SQL) documentation, and in those cases they're very clear about the issue. Something like "whenever an implicit CAST is needed we follow a precedence table of datatypes. The datatype with lower precedence will be converted into the datatype with higher precedence". Sincerely I thought this was a good way to put it, and if we did the same, why not document it properly? So the PMR already opened started to look like a documentation bug.&lt;br /&gt;But again, life sometimes is not simple... And while this was being analyzed and discussed, the customer team discovered an interesting scenario: If you give an integer value as a filter against a CHAR column, AND the length of the integer value (excluding any leading zeros) is equal to the size of the column, than Informix will convert the number to CHAR and eventually will use an index on the specified column.&lt;br /&gt;This is the optimizer being smart. If you think about it, if the number has the same number of digits as the length of the CHAR column, you can convert the number to CHAR and compare it. The result set will be correct no matter the values in question or the operator.&lt;br /&gt;&lt;br /&gt;To end the story, while browsing the documentation in search for other topics we came across this:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.perf.doc/ids_prf_536.htm"&gt;http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.perf.doc/ids_prf_536.htm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's clear and well explained. Informix makes the necessary casts but that can have a real impact on the performance, specially if exists an index on the column. And the optimizer is smart enough to use a better query plan in the only situation where it can be done. Really nice and at least here (Performance Guide) it's well explained. I really don't mind when a PMR generates a bug because that's a product improvement, but I must admit I prefer to be proven wrong and see that the product really works well!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;Versão Portuguesa:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;É ótimo passar muito tempo com clientes. Dá-me tempo para ir para além da estrita execução de tarefas que os projetos curtos permitem. Temos tempo para aprofundar o que por vezes não parece ser mais que uma curiosidade. Nesta entrada vou descrever uma dessas situações. Começou como um banal problema de &lt;i&gt;performance&lt;/i&gt;. Uma &lt;i&gt;query&lt;/i&gt; que envolvia um &lt;i&gt;join &lt;/i&gt;estava a gerar um &lt;i&gt;hash join&lt;/i&gt; havendo um índice que aparentemente podia ser usado. Após uma rápida investigação percebeu-se que os tipos de dados das colunas envolvidas no &lt;i&gt;join&lt;/i&gt; não eram iguais e por isso o índice não era usado.&lt;br /&gt;A situação foi corrigida (usando um &lt;i&gt;CAST&lt;/i&gt; explícito pois mudar os tipos de dados teria necessitado de uma análise mais profunda e poderia ter outras implicações) e o programador(es) recebeu uma explicação sobre o problema para que situações semelhantes fossem evitadas no futuro. Simples, certo? Sim... Mas quando temos mentes curiosas e programadores com alguns minutos para dispensar podemos ser surpreendidos. E este foi um desses casos. Umas semanas mais tarde a equipa de DBAs do cliente recebeu um pedido para explicar o porquê da recomendação, acompanhado de um caso de teste que demonstrava que o motor conseguia usar um índice mesmo quando os tipos de dados não batiam certo. Por outras palavras, se o motor tem inteligência para o fazer, porque nos devemos nós preocupar?!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Apesar de isto poder ser considerado uma perda de tempo (usar os mesmos tipos de dados ou um &lt;i&gt;CAST&lt;/i&gt; explícito é uma boa prática, não é?!) a questão era suficientemente interessante para nos fazer gastar algum tempo com ela. Na realidade já tinha tido situações no passado onde aparentemente o motor parecia inteligente, e outras onde tal não acontecia. Nunca pensei muito no assunto, dado que recomendo sempre que seja seguida as boas práticas (que claramente nos evitam problemas). Portanto, pessoalmente também tinha esta dúvida e em conjunto com os DBAs do cliente iniciámos alguns testes. Criámos um exemplo muito simples que pensamos que demonstra o problema:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;DATABASE stores;&lt;br /&gt;&lt;br /&gt;DROP TABLE IF EXISTS tst_int;&lt;br /&gt;DROP TABLE IF EXISTS tst_char;&lt;br /&gt;&lt;br /&gt;CREATE TABLE tst_int&lt;br /&gt;(&lt;br /&gt;    c1 INTEGER,&lt;br /&gt;    c2 INTEGER&lt;br /&gt;);&lt;br /&gt;CREATE TABLE tst_char&lt;br /&gt;(&lt;br /&gt;    c1 CHAR(15),&lt;br /&gt;    c2 INTEGER&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;INSERT INTO tst_int&lt;br /&gt;SELECT FIRST 2000 pg_pagenum, pg_partnum FROM sysmaster:syspaghdr;&lt;br /&gt;&lt;br /&gt;INSERT INTO tst_char&lt;br /&gt;SELECT FIRST 2000 pg_pagenum, pg_partnum FROM sysmaster:syspaghdr;&lt;br /&gt;&lt;br /&gt;CREATE INDEX i_tst_int ON tst_int(c1);&lt;br /&gt;CREATE INDEX i_tst_char ON tst_char(c1);&lt;br /&gt;&lt;br /&gt;SET EXPLAIN ON;&lt;br /&gt;SELECT "tst_int with char parameter:", * FROM tst_int WHERE c1 = '12345678';&lt;br /&gt;SELECT "tst_char whth int parameter",* FROM tst_char WHERE c1 = 12345678;&lt;br /&gt;&lt;br /&gt;--- demonstrates that each index key is being casted&lt;br /&gt;INSERT INTO tst_char VALUES("a1", 12345678);&lt;br /&gt;SELECT * FROM tst_char WHERE c1 = 12345678;&lt;/pre&gt;&lt;br /&gt;Se olharmos para o plano de execução vemos:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;QUERY: (OPTIMIZATION TIMESTAMP: 12-10-2011 23:25:19)&lt;br /&gt;------&lt;br /&gt;SELECT "tst_int with char parameter:", * FROM tst_int WHERE c1 = '12345678'&lt;br /&gt;&lt;br /&gt;Estimated Cost: 1&lt;br /&gt;Estimated # of Rows Returned: 1&lt;br /&gt;&lt;br /&gt;  1) informix.tst_int: INDEX PATH&lt;br /&gt;&lt;br /&gt;    (1) Index Name: informix.i_tst_int&lt;br /&gt;        Index Keys: c1   (Serial, fragments: ALL)&lt;br /&gt;        Lower Index Filter: informix.tst_int.c1 = 12345678&lt;/pre&gt;&lt;br /&gt;Ou seja, aqui o motor era "esperto". Convertia o CHAR para INTEGER e isso permitia usar o índice. Boa.&lt;br /&gt;&lt;br /&gt;Mas aqui: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;QUERY: (OPTIMIZATION TIMESTAMP: 12-10-2011 23:25:19)&lt;br /&gt;------&lt;br /&gt;SELECT "tst_char whth int parameter",* FROM tst_char WHERE c1 = 12345678&lt;br /&gt;&lt;br /&gt;Estimated Cost: 84&lt;br /&gt;Estimated # of Rows Returned: 1&lt;br /&gt;&lt;br /&gt;  1) informix.tst_char: SEQUENTIAL SCAN&lt;br /&gt;&lt;br /&gt;        Filters: informix.tst_char.c1 = 12345678&lt;/pre&gt;&lt;br /&gt;Parece que não é assim tão esperto.... Em vez de converter o parâmetro INTEGER para um CHAR e usar o índice, decide fazer o oposto: Converte todos os CHARs daquela coluna para INTEGERs e executa um SEQUENTIAL SCAN.&lt;br /&gt;Como não tinha uma boa explicação para isto decidi abrir um PMR para obter uma explicação oficial do suporte técnico.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;O suporte técnico informou que nós tínhamos algo na documentação que tenta explicar isto:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.sqls.doc/ids_sqs_1620.htm"&gt;http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.sqls.doc/ids_sqs_1620.htm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Esta documentação é altamente confusa, mas diz-nos algo importante: Se usarmos um filtro numérico contra uma coluna do tipo CHAR, o servidor de base de dados irá converter todos os valores CHAR da coluna em números. Isto é exatamente o que encontrámos no exemplo acima. Mas ainda não explica porquê. Deixe-me explicar o porquê com alguns exemplos:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Se tivermos o valor "00123" na tabela e usarmos 123 como parâmetro/filtro, se convertermos o número para CHAR e tentarmos fazer a comparação não vamos retornar nada ('123' != '00123') . Resultados errados...&lt;/li&gt;&lt;li&gt;Se tivermos o valor "234" na coluna e dermos 9 como parâmetro/filtro para uma condição de menor ou igual (col &amp;lt;= 9), se convertermos o número para CHAR isso implicaria que a linha era retornada&amp;nbsp; ("9" &amp;gt;= "234"). Mais uma vez iria retornar um resultado "errado", pois ao usarmos um parâmetro numérico estamos a assumir comparação numérica (onde 9 &amp;lt; 234)&lt;/li&gt;&lt;/ol&gt;Assim, depois disto a regra parecia muito simples. Algo como "Se usarmos um parâmetro numérico contra uma coluna do tipo CHAR, todos os valores da coluna serão convertidos para numérico. Por outro lado, usar um parâmetro CHAR contra uma coluna numérica permite que o motor converta o parâmetro para número e use um índice caso exista".&lt;br /&gt;&lt;br /&gt;Mas a vida não é assim tão simples... Se era assim tão direto porque razão não estava documentado (ou pelo menos nós não tínhamos encontrado)? Tentei procurar na documentação de outros sistemas de gestão de bases de dados (Oracle e MS SQL) , e nestes casos eram bastante claros sobre o assunto. Um resumo livre seria "sempre que um &lt;i&gt;CAST&lt;/i&gt; implícito seja necessário, seguimos uma tabela de precedências de tipos de dados. O tipo de dado com menor precedência será convertido para o que tem mais precedência". Sinceramente isto pareceu-me uma forma correta de colocar a questão, e se fazíamos o mesmo porque não ter isto claro na documentaçã? Assim o PMR já aberto parecia encaminhar-se para um &lt;i&gt;bug&lt;/i&gt; de documentação.&lt;br /&gt;&lt;br /&gt;Mas novamente, a vida por vezes não é simples... E enquanto isto estava a ser analisado e discutido , a equipa do cliente descobriu um cenário interessante: Se usarmos um numero como filtro contra uma coluna do tipo CHAR, e o numero de dígitos desse inteiro (excluindo quaisquer zeros à esquerda) for igual ao número de caracteres definido na coluna, então o número será convertido para CHAR e um eventual índice na coluna será usado.&lt;br /&gt;Isto é o optimizador a ser "esperto". Se pensarmos sobre o assunto, se o número de dígitos do número for igual ao número de caracteres da coluna, podemos convertê-lo para CHAR e compará-lo com a coluna. O resultado será o correto independentemente dos valores em questão e do operador.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Para terminar a história, enquanto consultáva-mos a documentação devido a outro assunto, demos com o seguinte:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.perf.doc/ids_prf_536.htm"&gt;http://publib.boulder.ibm.com/infocenter/idshelp/v117/topic/com.ibm.perf.doc/ids_prf_536.htm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Está claro e bem explicado. O Informix efetua os &lt;i&gt;CASTS&lt;/i&gt; necessários para resolver &lt;i&gt;queries&lt;/i&gt; onde existam inconsistências entre os tipos de dados. Mas isso pode ter um impacto significativo na &lt;i&gt;performance&lt;/i&gt;, especialmente se existir um índice na coluna. E o optimizador é suficientemente inteligente para obter um melhor plano de execução na única situação onde isso pode ser feito. Muito correto e pelo menos aqui (Guia de Performance) está bem explicado.&lt;br /&gt;Sinceramente não me importo muito quando um PMR dá origem a um &lt;i&gt;bug&lt;/i&gt;, pois isso traduz-se numa melhoria do produto, mas tenho de admitir que prefiro que resulte que estava enganado e ser-me mostrado que o produto está a funcionar bem!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-1254248432278605335?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/1254248432278605335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=1254248432278605335' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/1254248432278605335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/1254248432278605335'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/12/optimizer-secrets-segredos-do.html' title='Optimizer secrets / segredos do optimizador'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-2214910939028390589</id><published>2011-12-10T01:24:00.001Z</published><updated>2011-12-12T11:49:25.080Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='gis'/><category scheme='http://www.blogger.com/atom/ns#' term='IIUG'/><category scheme='http://www.blogger.com/atom/ns#' term='tatukgis'/><category scheme='http://www.blogger.com/atom/ns#' term='#informix'/><category scheme='http://www.blogger.com/atom/ns#' term='2012'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='philip howard'/><category scheme='http://www.blogger.com/atom/ns#' term='biztalk'/><category scheme='http://www.blogger.com/atom/ns#' term='john miller'/><category scheme='http://www.blogger.com/atom/ns#' term='bloor'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><title type='text'>Short notes / Notas curtas</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;&lt;div style="color: blue;"&gt;English version:&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This is a very short article that consists of a few short notes.&lt;br /&gt;First, as you can notice from the banner above, IIUG is going to organize the 2012 International User Conference in San Diego on April 22-25 2012. Next year's conference will move from the traditional Kansas City location to San Diego, California. As usual, you can get a lot of value for money. I will probably skip this one, but Ill surely miss it. Please consult the conference URL for all the details.&lt;br /&gt;&lt;br /&gt;Some time ago I added a blog to my list, mas to be honest at the time I didn't review the content that it already had. Recently, during some investigation I ended up there and I had the opportunity to browse over it's content and it's really interesting. I'm talking about &lt;a href="http://www.jfmiii/informix/"&gt;http://www.jfmiii/informix/&lt;/a&gt; . The URL shows that it's author is John Miller, one of the most well known elements of the Informix community. John is the author of a lot of Informix material, specially about update statistics and backup and restore. In the last years is has been involved with Open Admin Tool (OAT). He's also a usual presence in conferences and presentations done or sponsored by IBM. I highly recommend this blog. The blog also includes contributions from other well known members of the community&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Still related to blogs, I just added one more to the list: &lt;a href="http://informixdba.wordpress.com/"&gt;http://informixdba.wordpress.com/&lt;/a&gt; . It's author is Ben Thompson, an UK based Informix and Oralce DBA. Not many articles yet, but it looks promising. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bloorresearch.com/about/people/philip-howard.html" target="_blank"&gt;Philip Howard&lt;/a&gt;, from &lt;a href="http://www.bloorresearch.com/" target="_blank"&gt;Bloor Research&lt;/a&gt; talks about the &lt;a href="http://www.bloorresearch.com/analysis/11736/informix-revived.html" target="_blank"&gt;Informix revive&lt;/a&gt; and also mentions it in the article "&lt;a href="http://www.bloorresearch.com/analysis/11735/breakthrough-instrumented-applications.html" target="_blank"&gt;Breakthrough and instrumented applications&lt;/a&gt;".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tatukgis.com/" target="_blank"&gt;TatukGIS&lt;/a&gt; a Polish based GIS software and solution provider recently &lt;a href="http://www.tatukgis.com/News/TatukGIS-Supporting-IBM-DB2-Spatial-Extender---Inf.aspx" target="_blank"&gt;extended it's products support to Informix and DB2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In a &lt;a href="http://blogs.msdn.com/b/biztalk_server_team_blog/" target="_blank"&gt;blog&lt;/a&gt; hosted by Microsoft, there is a &lt;a href="http://blogs.msdn.com/b/biztalk_server_team_blog/archive/2011/12/08/biztalk-server-2010-r2.aspx" target="_blank"&gt;reference to future support for Informix 11 on their BizTalk ESB software&lt;/a&gt; in the next release of the product&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="color: blue;"&gt;Versão Portuguesa:&lt;/div&gt;&lt;br /&gt;Este é um artigo muito curto e consistirá em algumas notas sobre vários temas.&lt;br /&gt;Primeiro, como pode ver pelo cabeçalho acima, o IIUG vai organizar a conferência internacional de utilizadores de 2012 em San Diego entre 22 e 25 de Abril de 2012. A conferência do ano que vem deixará a localização tradicional em Kansas City e irá para San Diego na California. Como é hábito pode obter bastante valor pelo investimento. Em princípio não irei estar presente, mas irei sem dúvida sentir a falta. Consulte o endereço da conferência para mais detalhes.&lt;br /&gt;&lt;br /&gt;Há uns tempos adicionei um blog à lista, mas sinceramente na altura não revi todo o conteúdo que já existia. Recentemente durante alguma investigação que efectuei acabei por lá ir parar e tive oportunidade de verificar que tem conteúdo bastante interessante. Estou a falar de &lt;a href="http://www.jfmiii/informix/"&gt;http://www.jfmiii/informix/&lt;/a&gt; . Pelo endereço e conteúdo é fácil perceber que se trata do John Miller um dos mais conhecidos elementos da comunidade Informix. O John tem estado ligado a imenso material sobre Informix, em particular artigos sobre update statistics, backup e restore e outros. Nos últimos anos tem estado por detrás do Open Admin Tool. É também presença habitual em conferências e apresentações da IBM. Recomendo vivamente. O blog contém também contribuições de outros elementos bem conhecidos da comunidade&lt;br /&gt;&lt;br /&gt;Ainda relacionado com blogs, acabei de adicionar um à lista: &lt;a href="http://informixdba.wordpress.com/"&gt;http://informixdba.wordpress.com/&lt;/a&gt; . O seu autor é Ben Thompson, um DBA Informix e Oracle baseado no Reino Unido. Ainda não tem muitos artigos, mas parece promissor.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.bloorresearch.com/about/people/philip-howard.html" target="_blank"&gt;Philip Howard&lt;/a&gt;, da &lt;a href="http://www.bloorresearch.com/" target="_blank"&gt;Bloor Research&lt;/a&gt; fala sobre o &lt;a href="http://www.bloorresearch.com/analysis/11736/informix-revived.html" target="_blank"&gt;Informix revive&lt;/a&gt; e também o refere noutro artigo: "&lt;a href="http://www.bloorresearch.com/analysis/11735/breakthrough-instrumented-applications.html" target="_blank"&gt;Breakthrough and instrumented applications&lt;/a&gt;".&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tatukgis.com/" target="_blank"&gt;TatukGIS&lt;/a&gt;, um fornecedre de software e soluções GIS, baseado na Polónia anunciou recentemente &lt;a href="http://www.tatukgis.com/News/TatukGIS-Supporting-IBM-DB2-Spatial-Extender---Inf.aspx" target="_blank"&gt;a extensão do suporte nos seus produtos para Informix e DB2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Num &lt;a href="http://blogs.msdn.com/b/biztalk_server_team_blog/" target="_blank"&gt;blog&lt;/a&gt; hospedado na Microsoft, existe uma &lt;a href="http://blogs.msdn.com/b/biztalk_server_team_blog/archive/2011/12/08/biztalk-server-2010-r2.aspx" target="_blank"&gt;referencia ao futuro suporte ao Informix 11 na próxima release do seu BizTalk ESB.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-2214910939028390589?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/2214910939028390589/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=2214910939028390589' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/2214910939028390589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/2214910939028390589'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/12/short-notes-notas-curtas.html' title='Short notes / Notas curtas'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-2591063462859367521</id><published>2011-11-03T00:05:00.001Z</published><updated>2011-11-03T00:06:05.840Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='11.70.xC4'/><category scheme='http://www.blogger.com/atom/ns#' term='11.70.UC4'/><category scheme='http://www.blogger.com/atom/ns#' term='new'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='11.70.TC4'/><category scheme='http://www.blogger.com/atom/ns#' term='fixpack'/><category scheme='http://www.blogger.com/atom/ns#' term='release'/><category scheme='http://www.blogger.com/atom/ns#' term='TimeSeries'/><category scheme='http://www.blogger.com/atom/ns#' term='11.70.FC4'/><category scheme='http://www.blogger.com/atom/ns#' term='benchmark'/><title type='text'>Informix 11.70.xC4 is available / Informix 11.70.xC4 está disponível</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: blue;"&gt;&lt;span style="background-color: white;"&gt;&lt;span style="color: blue;"&gt;English Version:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: blue;"&gt;&lt;span style="background-color: white;"&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: blue;"&gt;&lt;span style="background-color: white;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="color: black;"&gt;IBM has relesed Informix 11.70.xC4 in October 25. The changes in this release, taken directly from the release notes, are (comments added):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: blue;"&gt;&lt;span style="background-color: white;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="color: black;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: blue;"&gt;&lt;span style="background-color: white;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="color: black;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Administration&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Enhancements to the OpenAdmin Tool (OAT) for Informix&lt;br /&gt;OAT now allows the management of database users (for non-OS users) and OAT is now delivered and installable with Client SDK for Windows (32bits), Linux (32 and 64 bits) and MAC OS (64 bits)&lt;/li&gt;&lt;li&gt;Enhancements to the Informix Replication Plug-in for OAT&lt;br /&gt;The ER plugin now follows ER improvements and can handle multibyte locales.&lt;/li&gt;&lt;li&gt;Informix Health Advisor Plug-in for OAT&lt;br /&gt;A totally new plugin that can examine a great number of metrics and configuration details, warning you (email) of anything not within the recommended settings and/or defined thresholds.&lt;br /&gt;The checks can be scheduled and you can setup several different profiles. Each will run a specific (and configurable) set of metrics.&lt;/li&gt;&lt;li&gt;Dynamically change additional configuration parameters&lt;br /&gt;Several parameters can now be changed with &lt;i&gt;onmode -wm/-wf&lt;/i&gt;. Some of them are really important (WSTATS, AUTO_REPREPARE, CKPTINTVL, DIRECTIVES, OPTCOMPIND, SHMADD) and can save you from planned downtime. Others are more or less irrelevant (some of them could be changed by editing the $ONCONFIG file), but it's important that they can be changed through SQL Admin API for client DBA tools&lt;/li&gt;&lt;li&gt;Compare date and interval values&lt;br /&gt;API extensions to compare datetime and interval values.&lt;/li&gt;&lt;li&gt;Plan responses to high severity event alarms&lt;br /&gt;Could not understand what is new. This could be done before by customizing the ALARMPROGRAM script&lt;/li&gt;&lt;li&gt;Data sampling for update statistics operations&lt;br /&gt;A new parameter (USTLOW_SAMPLE) defines if you want to sample the data for the index information gathering or not (indexes with more than 100.000 leaf pages). 11.70.xC3 did this by default. This can also be set at session level. Note that this can have a dramatic impact on the time it takes to regenerate your statistics. The "LOW" will be the slowest for large tables with indexes...&lt;/li&gt;&lt;li&gt;SQL administration API command arguments for creating sbspaces&lt;br /&gt;New options to create smart blob spaces with logging and access time recording in SQL admin API&lt;/li&gt;&lt;li&gt;Monitor client program database usage&lt;br /&gt;The client program's full path name is now available in &lt;i&gt;onstat -g ses&lt;/i&gt;.&lt;br /&gt;Note that although you can use this to monitor and control access, this information is sent by the client side and potentially can be faked (not the average user, but an attacker could do it)&lt;/li&gt;&lt;li&gt;Progress of compression operations&lt;br /&gt;Two new columns in &lt;i&gt;onstat -g dsk&lt;/i&gt; show the approximate percentage of the tasks already completed and the estimated time to finish&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;High availability and Enterprise Replication&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Easier setup of faster consistency checking&lt;br /&gt;When using ifx_replcheck and an index is created on it, the CRCOLS are not necessary&lt;/li&gt;&lt;li&gt;Handle Connection Manager event alarms&lt;br /&gt;Scripts used for processing connection manager alarms now have access to two variables that identify their name (INFORMIXCMNAME) and unit name (INFORMIXCMCONUNITNAME). This facilitates the script creation&lt;/li&gt;&lt;li&gt;Easier startup of Connection Manager&lt;br /&gt;When the variable CMCONFIG is set and points to the connection manager configuration file, it can be started, stop and restarted without specifying the configuration file. Much like ONCONFIG is used for the engine&lt;/li&gt;&lt;li&gt;Prevent failover if the primary server is active&lt;br /&gt;A new parameter called SDS_LOGCHECK can specify an number of seconds while the SDS secondaries will monitor the logical logs for activity (which would be generated by the primary server). This tries to implement a safety measure to prevent an SDS server to become a primary after a "false" failure of the primary. Note that usually this is prevented by using &lt;a href="http://en.wikipedia.org/wiki/Fencing_%28computing%29" target="_blank"&gt;I/O fencing&lt;/a&gt;, but if that is not available this can be another way to make sure you don't end up with two primaries&lt;/li&gt;&lt;li&gt;Configure secure connections for replication servers&lt;br /&gt;A new parameter called S6_USE_REMOTE_SERVER_CFG defines if the file specified by REMOTE_SERVER_CFG will also be used for client connections using the s=6 SQLHOSTS options (for replication). If this parameter is set to 1 the file will be used, otherwise it will default to the old behavior and use $INFORMIXDIR/etc/hosts.equiv&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Security&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Global Security Kit (GSKit) support&lt;br /&gt;A new parameter (GSKIT_VERSION) can be used to specify the Global Security Kit version you intend to use. Informix 11.70.xC4 ships with version 8, but can use version 7&lt;/li&gt;&lt;li&gt;Use a file to authenticate server connections in a secured network environment&lt;br /&gt;Already mentioned above (S6_USE_REMOTE_SERVER_CFG)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Time Series data&lt;/li&gt;&lt;ul&gt;&lt;li&gt;IBM Informix TimeSeries Plug-in for Data Studio&lt;br /&gt;This new plugin allows the interaction with TimeSeries data from Optim Data Studio and Optim Developer Studio&lt;/li&gt;&lt;li&gt;Delete a range of elements and free empty pages from a time series&lt;br /&gt;Delete improvements in TimeSeries data that should free some pages&lt;/li&gt;&lt;li&gt;Aggregate time series data across multiple rows&lt;br /&gt;Improvement in how we can aggregate TimeSeries data.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;Besides bringing some new features, this release also fixes some important bugs that appeared in xC3 around the new automatic read ahead configuration. Apart from this I think it's important to notice the following points:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;TimeSeries continues to have a great focus on the current enhancements off Informix. This is expectable and desired considering the great news around customer success stories and the recent benchmark.&lt;/li&gt;&lt;li&gt;The new OAT health plugin. I didn't have time yet to really explore it, but for sure I would have done a few things differently like re-using the alarmprogram configuration to send alarms. But this is great and being a plugin it can easily be changed if it doesn't fit your needs.&lt;/li&gt;&lt;li&gt;The inclusion of OAT inside CSDK is a good step (from my point of view). It makes it easier to get and install. I've installed it very quickly in Windows&lt;/li&gt;&lt;li&gt;The new dynamically changeable parameters are a very good step. Of course I would love to be able to change all the parameters without stopping the instance. But we're getting closer. My next favorites would be (and why):&lt;/li&gt;&lt;ul&gt;&lt;li&gt;LOGBUFF, PHYSBUFF&lt;br /&gt;After instance healthchecks, may times these should be changed&lt;br /&gt;I suppose this should not be to hard, since there are a set of each and they're used in a circular fashion. So on change, they could be resized.&lt;br /&gt;LOGBUFF would probably be harder due to it's role in replication (HDR)&lt;/li&gt;&lt;li&gt;TBLSPACE_STATS&lt;br /&gt;Again, it's a good practice to have this active. But having to stop the instance to fix this is not nice&lt;/li&gt;&lt;li&gt;SYSSBSPACENAME, SBSPACENAME&lt;br /&gt;Sometimes these are not set, but the usage of some new features required them. A restart is not nice...&lt;/li&gt;&lt;li&gt;CLEANERS&lt;br /&gt;Again, many times needed after a configuration check&lt;/li&gt;&lt;li&gt;SHMTOTAL&lt;br /&gt;Many customers don't set it. And sometimes you may need to reduce it or increase it (new OS are able to add/remove memory online). Of course we would not be able to lower it below current usage.&lt;/li&gt;&lt;li&gt;DD_*, DS_*, PC_*, PLCY_*, USRC_&lt;br /&gt;Again, usual candidates to change after a health check. These would be trickier to change, but if we did it for statement cache we should be able to do it for all the other caches. Also a functionality to "flush" these caches or at least remove some entries would be nice.&lt;/li&gt;&lt;li&gt;EXT_DIRECTIVES&lt;br /&gt;Some times customers find out they need it, but it's off by default... Again the restart&lt;/li&gt;&lt;li&gt;DBCREATE_PERMISSION&lt;br /&gt;This is in my view dynamic by nature&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: blue;"&gt;&lt;span style="background-color: white;"&gt;&lt;span style="color: blue;"&gt;Versão Portuguesa:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: blue;"&gt;&lt;span style="background-color: white;"&gt;&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: blue;"&gt;&lt;span style="background-color: white;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="color: black;"&gt;A IBM lançou o Informix 11.70.xC4 no dia 25 de Outubro. Estas são as mudanças nesta versão (retiradas directamente das &lt;i&gt;release notes&lt;/i&gt; (comentários adicionados):&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: blue;"&gt;&lt;span style="background-color: white;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-color: blue;"&gt;&lt;span style="background-color: white;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Administração&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Melhorias no OpenAdmin Tool (OAT)&lt;br /&gt;O OAT permite agora a gestão dos utilizadores de base de dados (para utilizadores não autenticados no sistema operativo) e é agora distribuido com o Client SDK para Windows (32bits), Linux (32 and 64 bits) e MAC OS (64 bits)&lt;/li&gt;&lt;li&gt;Melhorias no plugin de replicação do OAT&lt;br /&gt;O plugin de ER segue as emlhorias do próprio ER e pode lidar com &lt;i&gt;locales multibyte&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Informix &lt;i&gt;Health Advisor Plug-in&lt;/i&gt; para o OAT&lt;br /&gt;Um plugin totalmente novo que pode examinar um grande número de métricas e detalhes de configuração, avisando (por email) de algo que fuja às recomendações e/ou a parâmetros pré-definidos. Podemos calendarizar verificações periódicas de acordo com vários perfis. Cada perfil irá validar um conjunto de métricas especificas (e configurável)&lt;/li&gt;&lt;li&gt;Alteração dinâmica de mais parâmetros&lt;br /&gt;Vários parâmetros podem agora ser mudados com o &lt;i&gt;onmode -wm/-wf&lt;/i&gt;. Alguns são realmente importantes (WSTATS, AUTO_REPREPARE, CKPTINTVL, DIRECTIVES, OPTCOMPIND, SHMADD) e podem evitar paragens planeadas. Outros são relativamente irrelevantes (alguns já podiam ser alterados editando o $ONCONFIG), mas é importante que possam ser alterados através da SQL Admin API, para que possam ser mudados em ferramentas cliente&lt;/li&gt;&lt;li&gt;Comparação de datas e &lt;i&gt;intervals&lt;/i&gt;&lt;br /&gt;Extensão da API extensions para comparar valores dos tipos datetime e interval&lt;/li&gt;&lt;li&gt;Planear resposta a eventos de alta severidade&lt;br /&gt;Não consegui perceber o que foi feito de novo. Isto já podia ser feito através da configuração/adaptação do &lt;i&gt;script&lt;/i&gt; configurado no parâmetros ALARMPROGRAM&lt;/li&gt;&lt;li&gt;&lt;i&gt;Data sampling&lt;/i&gt; para operações de UPDATE STATISTICS&lt;br /&gt;Um novo parâmetro (USTLOW_SAMPLE) define se queremos efectuar &lt;i&gt;sampling&lt;/i&gt; na recolha de dados sobre os índices ou não (índices com mais de 100.000 "folhas" - &lt;i&gt;leaf pages&lt;/i&gt;). 11.70.xC3 fazía-o por omissão. Isto pode ser activado ao nível da sessão. Note-se que isto pode ter um impacto dramático no tempo que leva a refazer as estatísticas. A opção "LOW" é a mais lenta para tabelas grandes em muitos casos.., &lt;/li&gt;&lt;li&gt;Novos argumentos para criar &lt;i&gt;smart blob spaces&lt;/i&gt; com a SQL administration API &lt;br /&gt;As novas opções permitem criar os &lt;i&gt;smart blob spaces&lt;/i&gt; com ou sem &lt;i&gt;logging&lt;/i&gt; e mantendo ou não o tempo de acesso aos objectos&lt;/li&gt;&lt;li&gt;Monitorização do uso das bases de dados por programa cliente&lt;br /&gt;O nome (caminho) completo do programa cliente está disponível no &lt;i&gt;output&lt;/i&gt; do &lt;i&gt;onstat -g ses&lt;/i&gt;&lt;br /&gt;Note-se que apesar de isto poder ser usado para monitorizar ou até condicionar o acesso a uma base de dados, esta informação é enviada pelo cliente e pode potentcialmente ser alterada (não pelo utilizador comum, mas certamente por um atacante)&lt;/li&gt;&lt;li&gt;Consulta do progresso das operações de compressão&lt;br /&gt;Duas novas colunas no &lt;i&gt;output&lt;/i&gt; do &lt;i&gt;onstat -g dsk&lt;/i&gt; mostras a percentagem aproximada de trabalho já efectuado e o tempo estimado para a sua conclusão&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Alta disponibilidade e &lt;i&gt;Enterprise Replication&lt;/i&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Configuração mais fácil de verificação de consistência&lt;br /&gt;Quando se usa o ifx_replcheck, e se cria um índice por ele, os CRCOLS não são necessários&lt;/li&gt;&lt;li&gt;Lidar com alarmística do Connection Manager&lt;br /&gt;&lt;i&gt;Scripts&lt;/i&gt; usados para processar os alarmes do(s) connection managers têm agora acesso a duas variáveis que identificam o seu nome&amp;nbsp; (INFORMIXCMNAME) e nome de unidade (INFORMIXCMCONUNITNAME). Isto facilita a criação dos &lt;i&gt;scripts&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Arranque facilitado do Connection Manager&lt;br /&gt;Quando a variável CMCONFIG está definida e aponta para o ficheiro de configuração do Connection Manager, este pode ser iniciado, parado e re-iniciado sem especificar o ficheiros de configuração. Muito semelhante à utilização da variável ONCONFIG para o motor&lt;/li&gt;&lt;li&gt;Prevenção de &lt;i&gt;failover&lt;/i&gt; se o servidor primário ainda estiver activo&lt;br /&gt;Um novo parâmetro, chamado SDS_LOGCHECK pode indicar o número de segundos que os SDS secundários irão monitorizar os &lt;i&gt;logical logs&lt;/i&gt; para detectar actividade (que a existir seria gerada pelo primário). Isto tenta implementar uma medida de segurança para prevenir que um servidor SDS se torne primário em caso de falsa falha do primário. Note-se que habitualmente isto é prevenido com recurso ao &lt;a href="http://en.wikipedia.org/wiki/Fencing_%28computing%29" target="_blank"&gt;I/O fencing&lt;/a&gt;, mas se essa funcionalidade não estiver disponível, esta pode ser outra forma de evitar ficar com dois servidores primários&lt;/li&gt;&lt;li&gt;Configuração de segurança para servidores em replicação&lt;br /&gt;Um novo parâmetro, S6_USE_REMOTE_SERVER_CFG define se o ficheiro indicado pelo parâmetro REMOTE_SERVER_CFG será também usado para conexões que utilizem a opção s=6 do SQLHOSTS (para replicação). Se o parâmetros estiver a 1 o referido ficheiro será utilizado, caso contrário o comportamento antigo será o escolhido e o ficheiro a usar será $INFORMIXDIR/etc/hosts.equiv&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Segurança&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Suporte ao Global Security Kit (GSKit)&lt;br /&gt;Um novo parâmetros, GSKIT_VERSION, pode ser usado para definir a versão do Global Security Kit que se pretende usar. O Informix 11.70.xC4 incluí a versão 8, mas pode trabalhar com a versão 7&lt;/li&gt;&lt;li&gt;Utilizacão de um ficheiro para autenticar conexões de servidores numa rede segura&lt;br /&gt;Já mencionado atrás (S6_USE_REMOTE_SERVER_CFG)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Dados Time Series &lt;/li&gt;&lt;ul&gt;&lt;li&gt;IBM Informix TimeSeries Plug-in para Data Studio&lt;br /&gt;Este novo plugin permite interagir com dados TimeSeries a partir do Optim Data Studio e do Optim Developer Studio&lt;/li&gt;&lt;li&gt;Apagar um intervalo de elementos e libertar páginas vazias de um &lt;i&gt;time series&lt;/i&gt;&lt;br /&gt;Melhorias nos DELETEs em dados TimeSeries que permitem libertar espaço&lt;/li&gt;&lt;li&gt;Agregar dados &lt;i&gt;time series&lt;/i&gt; cruzando várias linhas&lt;br /&gt;Melhorias na forma como podemos agregar informação guardada em TimeSeries&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;Para além de trazer algumas novas funcionalidades, esta versão também corrige alguns &lt;i&gt;bugs&lt;/i&gt; importantes em torno da funcionalidade de &lt;i&gt;read ahead&lt;/i&gt; automático introduzido na versão 11.70.xC3. Fora isto, julgo que é importante salientar os seguintes pontos: &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;O TimeSeries continua a receber muito do foco das últimas melhorias no Informix. Isto é expectável e desejável considerando as boas notícias sobre histórias de sucesso e o recente &lt;i&gt;benchmark&lt;/i&gt;&lt;/li&gt;&lt;li&gt;O novo &lt;i&gt;health&lt;/i&gt; plugin do OAT. Não tive muito tempo ainda para o explorar, mas certamente faria algumas coisas de forma diferente, como por exemplo re-utilizar a configuração do ALARMPROGRAM para o envio de alarmes. Mas a criação deste plugin é uma óptima ideia e sendo um plugin pode ser alterado facilmente para se ajustar às nossas necessidades&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A inclusão do OAT dentro do Client SDK é um bom passo (do meu ponto de vista). Torna ainda mais fácil obter e instalar o OAT. Já o instalei em Windows aproveitando o upgrade de versão que fiz ao Client SDK&lt;/li&gt;&lt;li&gt;A possibilidade de mudar dinamicamente mais parâmetros é excelente. Naturalmente que gostaria que todos os parâmetros da instância tivessem esta capacidade. Mas estamos cada vez mais perto. Os meus próximos favoritos seriam (e porquê):&lt;/li&gt;&lt;ul&gt;&lt;li&gt;LOGBUFF, PHYSBUFF&lt;br /&gt;Depois de uma análise a uma instância, muitas vezes estes devem ser mudados.&lt;br /&gt;Imagino que torná-los dinâmicos não fosse muito difícil, pois existem vários &lt;i&gt;buffers&lt;/i&gt; que são usados de forma circular. Assim, após um pedido de mudança, quando passa de um para outro podia aproveitar-se para fazer a alteração. O LOGBUFF seria mais difícil pela importância que tem na replicação (HDR)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;TBLSPACE_STATS&lt;br /&gt;Também aqui é uma boa práctica ter este parâmetro activo. Mas se for detectado que não está, ter de parar a instância para o mudar não é simpático&lt;/li&gt;&lt;li&gt;SYSSBSPACENAME, SBSPACENAME&lt;br /&gt;Muitas vezes estes não são definidos, mas a decisão de usar novas funcionalidades torna-os necessários. Mais uma vez, obrigar a paragem não é simpático...&lt;br /&gt;&lt;/li&gt;&lt;li&gt;CLEANERS&lt;br /&gt;Muitas vezes necessita ser alterado após uma análise à configuração e comportamento da instância&lt;br /&gt;&lt;/li&gt;&lt;li&gt;SHMTOTAL&lt;br /&gt;Muitos clientes não o definem. E por vezes podemos ter de reduzir ou aumentar o valor (os novos sistemas operativos já permitem adicionar/remover memória dinamicamente). Naturalmente não seria possível baixar o valor abaixo da quantidade já em uso&lt;br /&gt;&lt;/li&gt;&lt;li&gt;DD_*, DS_*, PC_*, PLCY_*, USRC_&lt;br /&gt;Mais candidatos habituais a mudança após uma análise de configuração. Estes seriam possivelmente dos mais complexos de tornar dinâmicos, mas se já se faz para a &lt;i&gt;statement cache&lt;/i&gt; deveria ser possível fazer para estes também. Para além disso, uma funcionalidade para limpar uma das caches (ou pelo menos remover alguma entrada) seria útil em determinadas situações&lt;/li&gt;&lt;li&gt;EXT_DIRECTIVES&lt;br /&gt;Alguns clientes descobrem que precisam de o usar, mas está desligado por default. E uma paragem nunca é desejável&lt;br /&gt;&lt;/li&gt;&lt;li&gt;DBCREATE_PERMISSION&lt;br /&gt;Este é a meu ver dinâmico por natureza&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-2591063462859367521?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/2591063462859367521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=2591063462859367521' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/2591063462859367521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/2591063462859367521'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/11/informix-1170xc4-is-available-informix.html' title='Informix 11.70.xC4 is available / Informix 11.70.xC4 está disponível'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-7039130621262805400</id><published>2011-09-13T22:50:00.003+01:00</published><updated>2011-09-13T22:50:44.219+01:00</updated><title type='text'>Spanish Informix user group / Grupo Espanhol de utilizadores Informix</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;English version:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I suppose this article should be written in Spanish but unfortunately I'm too limited for that. I recently noticed the appearance of the &lt;a href="http://www.iug.org.es/"&gt;Spanish Informix User Group site&lt;/a&gt;. Accordingly to the information online it's recent and it will be launched in this Autumn with the presence of several Informix specialists.&lt;br /&gt; &lt;br /&gt;If your country is Spain, or your native language is Spanish, and you use Informix (or just want to learn more about it) I think and hope that this will be a new reference. I've seen some signs of interest in Informix in my neighbor country and this is another one.&lt;br /&gt; &lt;br /&gt;I wish all the best to the founders and I hope they'll be able to attract the users and serve the community. And for the Portuguese community, this can also be interesting. There's a large number of people here to whom the language will not be a big issue, so maybe we can also enjoy and take advantage of this initiative (even due to the geographic proximity)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;Versão Portuguesa:&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;Suponho que este artigo deveria ser também escrito em Espanhol/Castelhano, mas infelizmente sou demasiado limitado para isso. Notei recentemente o aparecimento do &lt;a href="http://www.iug.org.es/"&gt;&lt;i&gt;site&lt;/i&gt; do Grupo Espanhol de Utilizadores Informix&lt;/a&gt;. Segundo a informação lá colocada é recente e será lançado neste Outono com a presença de vários especialistas Informix.&lt;br /&gt;&lt;br /&gt;Se o seu país é a Espanha ou se o Espanhol é uma língua que domina, e usa Informix (ou apenas deseje aprender mais sobre ele) penso e espero que isto venha a ser uma nova referência. Tenho visto alguns sinais de interesse no Informix no meu país vizinho e este é mais um.&lt;br /&gt;&lt;br /&gt;Desejo as maiores felicidades aos fundadores e espero que consigam atrair os utilizadores e servir a comunidade. Também para a comunidade Portuguesa isto pode ser interessante. Existe por cá muita gente para quem a língua não será um obstáculo e portanto poderão disfrutar e tirar partido desta iniciativa (até pela proximidade geográfica)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-7039130621262805400?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/7039130621262805400/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=7039130621262805400' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/7039130621262805400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/7039130621262805400'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/09/spanish-informix-user-group-grupo.html' title='Spanish Informix user group / Grupo Espanhol de utilizadores Informix'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-5579898134638612104</id><published>2011-09-09T22:44:00.001+01:00</published><updated>2011-09-09T23:21:43.138+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='conversion'/><category scheme='http://www.blogger.com/atom/ns#' term='pending'/><category scheme='http://www.blogger.com/atom/ns#' term='#informix'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='upgrade'/><category scheme='http://www.blogger.com/atom/ns#' term='IPA'/><category scheme='http://www.blogger.com/atom/ns#' term='inplace alter'/><title type='text'>Get pending In Place ALTERs / Obter as tabelas com InPlace ALTERs pendentes</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color: white; color: blue;"&gt;English version:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The topic of in place ALTERed tables has always been present in Informix. We say a table was ALTERed in place when an ALTER TABLE instruction resulted in a new table schema, but the table was not physically changed. This is very helpful on large and busy tables. It means you can do the ALTER TABLE quickly (instantaneously) and with minimum immediate impact on system resources. Internally Informix does a very simple thing from the user point of view, but that can be complex from the engine point of view: A new version of the table definition is created, and from there on, any instruction (DML) affecting the data will use the new version. The table's existing pages are left on the older version but each time we SELECT them, the engine converts the row(s) to the new format. Additionally if we update a row, the page where it is stored will be written in the new format.&lt;br /&gt;&lt;br /&gt;For example, if we have a table with lots of data  pages, and we add a column, this will do an in place ALTER. Certain types of ALTERs don't allow in place ALTERs. For example, if we change a CHAR(5) column to a SMALLINT, this will be a slow ALTER. This usually happens when the system cannot immediately guarantee that the existing data can be stored in the new representation.&lt;br /&gt;&lt;br /&gt;When the engine decides that it can do an in place ALTER, we don't have the option to inhibit it. Meaning the ALTER table will be done as an in place ALTER, and if we want to force the physical changes, we must do what we usually call a dummy UPDATE: UPDATE tabname SET column = column;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Impacts of in place ALTERs&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are several impacts on having tables with in place ALTERs. The immediate one is that your updates will be slightly slower, since the whole page will be converted and written. Note that this does not necessarily means higher I/O load, since the page is the smallest unit written by the engine. In other words, even if your table does not have more than one version of it's definition, when we change a single row of data, a whole page (at least) will be written. But the other rows of the page don't need to be changed. And changing an older version can mean your data will not fit on one page after conversion. So there can be more I/O.&lt;br /&gt;Another potential issue is that like with any other part of the engine, the mechanism of in place ALTER can have issues. This is an overrated aspect, but it's true we've seen problems that only affect tables with in place ALTERs.&lt;br /&gt;&lt;br /&gt;But the real issue with in place ALTERs refers to upgrades and downgrades. Through versions there have been great controversy regarding the real impact of doing in-place upgrades (conversions) with tables with pending in-place ALTERs. I've searched through the migration guides for several versions (7.3, 9.2, 9.4, 10, 11.1, 11.5 and 11.7) and they're almost completely consistent: You can upgrade with pending in-place ALTERed tables, but you cannot revert. The only exception I've found was the manual for 9.4 which states that you must remove the pending in-place ALTERs to run the conversion (upgrade) successfully.&lt;br /&gt;&lt;br /&gt;The reason for allowing upgrades but not downgrades is pretty simple and acceptable: Informix guarantees that version N+1 can handle all previous situations of in-place ALTERs done in version N or older. But, since each version may have added new situations where in-place ALTERs can be done, we can't risk porting a pending ALTER to an older version that may not be able to handle it. Let me remind you that an in-place ALTER requires the ability to convert from one row version to a newer one (which can have more columns, or different data types etc.)&lt;br /&gt;&lt;br /&gt;At the time of this writing I could not verify if the exception in the migration guide of version 9.4 was justified or simply a documentation problem. But the fact is that most people assume they must complete the ALTER tables that were done in-place before converting. By this I mean that they must eliminate all the pages in older versions. A valid reason to do that is that in case you need to revert you don't have to waste time running the dummy updates. Typically, if you have any issue in the new version and need to revert, you'll want to do it as soon as possible. As such, eliminating the pending inplace ALTERs before you upgrade can save you precious time if you really need to revert. In any case, the migration guide for version 11.7 clearly states that you only need to remove the pending inplace ALTERs, if they were caused after the conversion to 11.7. Any previous one (which already exists in the old version) would not need to be eliminated.&lt;br /&gt;As a side note, let me state that the only time I've done reversions was during a customer and partner workshop where we were demoing this functionality... I never had to do it on a real customer situation. In any case the other limitations for reversion can be real challenges, so the pending in-place ALTERs wouldn't be your biggest concern.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Finding in-place alters&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now that we've seen in which situations we should remove pending inplace ALTERs (tables with pages in older versions), we come to another issue that is frequently asked, and to which there are several answers. Most of them are controversial or badly explained which again raises a lot of confusion. The issue is: How do we find tables with pending inplace ALTERs?&lt;br /&gt;There was a discussion in the IIUG forum near the end of 2010 that focused on this issue. As usual, there were three answers to this: &lt;br /&gt;&lt;ol&gt;&lt;li&gt;A quick way (based on SQL and SMI that tells us which tables suffered an inplace ALTER, but doesn't show which tables have pending inplace ALTERs. This means that unless you completely rebuild the table, just running dummy UPDATEs will not prevent the table from always appearing in the list generated by this method &lt;/li&gt;&lt;li&gt;A slow way that's based in the oncheck -pT output (this effectively tells you the number of pages in each existing version This method will give you just the tables with pending inplace ALTERs &lt;/li&gt;&lt;li&gt;A technical support tool that searches the tables metadata and can provide the answer pretty quickly. Only problem is that it's not generally available &lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;And this was my motivation to do some research on this issue. After some information exchange with Andreas Legner from IBM technical support in Germany, I was able to create an SQL script that can find the tables with pending inplace alters. The script can give us the details about the number of pages in each version, it returns the database and table name, the version and number of pages it contains.&lt;br /&gt;&lt;br /&gt;The great thing about this script is that it's fast (from a few seconds to a few minutes for very large databases) and it really shows you the current status. Contrary to what the option 1) above does, if you do the dummy updates on one table, that table will not show up if you run it again. One warning: If you test this, after the dummy update you need to force a checkpoint. The script goes through the partition headers (because the required info is stored there), and after the dummy updates the partition headers are written to disk only at checkpoint time.&lt;br /&gt;&lt;br /&gt;The script comes in the form of a stored procedure and is based only on the sysmaster views. The script was tested with all the versions I could find (7.31, 9.3, 9.4, 10, 11.1, 11.5 and 11.70) and it worked without issues in all of them. So if you're upgrading an old system and want to make sure you clear any pending inplace altered tables this can be a great help.&lt;br /&gt;&lt;br /&gt;The SQL containing the script is at the bottom of this article and I will not dig into it with great detail. The challenges I got in developing it were mainly to understand how the needed data was already present in sysmaster views and also on interpreting this data (the representation is different depending on the "&lt;a href="http://en.wikipedia.org/wiki/Endianness"&gt;endianess&lt;/a&gt;" of your platform. Again, for the first one the help from Andreas Legner was precious and for the second one a special thank you goes to Art Kagel. Both of them helped me to review the script and to fix some nasty bugs I had in my first attempts.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Usage&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In order to use this procedure, you'll need to copy the script code below, paste it into dbaccess and run it against any of your instance databases. It will create a function called get_pending_ipa() that will return the following fields:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Database&lt;/li&gt;&lt;li&gt;Table name&lt;/li&gt;&lt;li&gt;Partition name&lt;/li&gt;&lt;li&gt;Object type (can be table, partition or partition main)&lt;/li&gt;&lt;li&gt;Partition number&lt;/li&gt;&lt;li&gt;Partition lockid (the partnum of the main partition for fragmented tables)&lt;/li&gt;&lt;li&gt;Table structure version&lt;/li&gt;&lt;li&gt;Number of pages remaining in this version&lt;/li&gt;&lt;/ul&gt;If you need to create this against a version 7 (pre-V9) you should change the header and footer as commented in the script.&lt;br /&gt;To execute just run&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;execute function get_pending_ipa();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;or&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;execute procedure get_pending_ipa();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Disclaimer&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Although the script was tested as much as I could, please understand that is comes with no guarantee. Use at your one risk. Neither me nor my employer can be considered liable for any harm done by it (difficult to happen since it only SELECTs), or more important for bad decisions taken based on it's output. This is just the usual disclaimer. Naturally I've done my best to make sure it works. If you find any error in the script or if you have any suggestion, feel free to contact me.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;Versão Portuguesa:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Introdução &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O assunto das tabelas com inplace ALTERs (optei por não traduzir o termo) tem estado sempre presente no Informix. Dizemos que uma tabela tem um inplace ALTER quando uma instrução ALTER TABLE deu origem a uma nova definição (schema) de tabela, mas a mesma não foi fisicamente alterada. Isto é muito útil em tabelas grandes e/ou com muitos acessos. Permite que se faça um ALTER TABLE muito rápido (instantâneo) e com um impacto reduzido no consumo de recursos do sistema. Internamente o Informix faz algo muito simples do ponto de vista do utilizador mas que pode ser bastante complexo se visto pelo ângulo do motor: É criada uma nova definição da estrutura da tabela, e a partir desse momento qualquer instrução (DML) que afecte os dados usará essa nova versão. As páginas já existentes da tabela mantêm-se na versão antiga, mas sempre que façamos um SELECT o motor converte a linha(s) para o novo formato. Adicionalmente, se fizermos um UPDATE a página onde estiver guardado o registo(s) será convertida pelo motor para o novo formato.&lt;br /&gt;&lt;br /&gt;Por exemplo, se tivermos uma tabela com muitas páginas de dados, e adicionar-mos uma coluna, isto será feito com um inplace ALTER. Mas alguns tipos de ALTER TABLE não permitem um inplace ALTER. Caso mudemos uma coluna de CHAR(5) para SMALLINT, isto será um slow ALTER. Habitualmente isto acontece se o sistema não puder garantir imediatamente que os dados existentes têm representação ou podem ser guardados no novo tipo de dados (no caso anterior o CHAR(5) pode ter caracteres não numéricos). Se o motor decide que pode fazer um inplace ALTER não temos forma de o inibir. Ou seja, a alteração será forçosamente feita com inplace ALTER e se desejarmos forçar a mudança física temos de fazer o que normalmente se designa de dummy UPDATE: UPDATE tabela SET coluna = coluna;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Impactos dos in place ALTERs&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Existem vários impactos em ter tabelas com inplace ALTERs. O mais imediato é que os UPDATEs serão ligeiramente mais lentos, pois toda a página tem de ser convertida e escrita. Note-se que isto não implica maior carga de I/O, pois a página é a unidade de escrita mais pequena do motor. Por outras palavras, mesmo que a sua tabela não tenha mais que uma versão da sua definição, quando mudamos uma linha contida numa página, toda a página (pelo menos) será escrita. Mas as outras linhas da mesma página não são alteradas. E mudar de uma versão anterior da definição para a atual pode implicar que nem todas as linhas caibam na página depois de convertidas. Isso sim, pode implicar mais I/O.&lt;br /&gt;Outro potencial problema é que como em qualquer outra área de código do motor, o mecanismo de inplace ALTER pode ter problemas ou erros. Este aspeto é muitas vezes sobrevalorizado, mas é um facto que já tivemos problemas que só aconteciam em tabelas com inplace ALTERs.&lt;br /&gt;&lt;br /&gt;Mas o verdadeiro problema habitualmente associado com os inplace ALTERs diz respeito aos upgrades e downgrades. Através das versões tem existido grande controvérsia relativamente às verdadeiras implicações de se efetuarem conversões (ou upgrades inplace) de versão existindo tabelas com inplace ALTERs pendentes (por pendentes quer-se dizer que têm efetivamente páginas com mais que uma versão de definição ou schema da tabela). Procurei pelos guias de migração de várias versões (7.3, 9.2, 9.4, 10, 11.1, 11.5 e 11.7) e são quase absolutamente consistentes: Pode fazer-se o upgrade com inplace ALTERs pendentes mas não se pode fazer o inverso (regressão). A única exceção a esta regra está no manual da versão 9.4 que refere que os mesmos têm de ser removidos antes de se efectuar a conversão.&lt;br /&gt;&lt;br /&gt;A razão para permitir conversões, mas não regredir é bastante simples e compreensível: O Informix garante que a versão N+1 consegue lidar com toas as possibilidades de inplace ALTERs da versão N ou anteriores. Mas dado que em cada versão podem ser adicionadas novas situações onde o motor consegue fazer um inplace ALTER, não podemos correr o risco de portar um inplace ALTER pendente para uma versão anterior que não sabe como lidar com ele. Deixe-me lembrar que um inplace ALTER obriga a que o motor consiga mapear os dados de um formato para outro (com mais colunas, ou tipos de dados diferentes etc.)&lt;br /&gt;&lt;br /&gt;No momento da escrita deste artigo não consegui verificar se a exceção no guia de migração da versão 9.4 se pode justificar com um erro de documentação ou se tem outro fundamento. Mas o facto é que a maioria dos utilizadores assumem que têm de completar (ou eliminar) os inplace ALTERs pendentes antes das conversões (upgrades). Uma razão válida para este raciocínio é que caso seja necessário regredir para a versão original não se quererá perder tempo a executar os dummy updates. Ou seja, eliminar os inplace ALTERs pendentes, antes da conversão, pode poupar tempo precioso caso se verifique a necessidade de regredir. O manual da versão 11.7 vai um pouco mais longe e refere que só é necessário remover os inplace ALTERs pendentes, se os mesmos foram gerados já na versão 11.7&lt;br /&gt;&lt;br /&gt;Qualquer um anterior (que já existisse na versão original) não necessitará de ser eliminado.&lt;br /&gt;Como um aparte, permita-me que diga que a única vez que fiz regressões foi num workshop para parceiros e clientes com o objetivo de demonstrar a funcionalidade. Nunca tive a necessidade de efectuar isto numa situação real em clientes. Em qualquer caso existem várias limitações às regressões que podem constituir verdadeiros desafios, pelo que os inplace ALTERs não deveriam ser a maior preocupação.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Identificar inplace ALTERs pendentes&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Agora que vimos em que situações devemos remover os inplace ALTERs pendentes, chegamos a outro tópico que é alvo frequente de perguntas e discussões. A questão é: Como identificamos as tabelas que possuem páginas de dados com várias versões da sua definição? Há várias respostas e regra geral são controvérsias ou mal explicadas o que levanta enormes confusões. Decorreu uma discussão sobre este tema mais uma vez em finais de 2010. Como é hábito foram dadas três respostas para o problema: &lt;br /&gt;&lt;ol&gt;&lt;li&gt;Uma forma rápida (baseada em SQL e tabelas SMI) que nos diz as tabelas que sofreram inplace ALTERs mas não permite saber se ainda estão pendentes (existem ainda páginas de dados com formato antigo). Isto significa que a menos que se refaça completamente a tabela, a mera execução dos dummy UPDATEs não impedirá a tabela de voltar a aparecer na lista gerada por este método.&lt;/li&gt;&lt;li&gt;Uma forma lenta, baseada no resultado do oncheck -pT. Isto efetivamente diz-nos quantas páginas de dados existem para cada formato da tabela. Este método permite realmente identificar os inplace ALTERs pendentes. &lt;/li&gt;&lt;li&gt;Uma ferramenta do suporte técnico que procura na metadata das tabelas e pode fornecer a resposta de forma rápida. O único problema é que não está disponível para os utilizadores em geral &lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;E isto foi a minha motivação para efetuar alguma pesquisa sobre este tema. Após alguma troca de informação com o Andreas Legner do suporte técnico da IBM na Alemanha, consegui criar um script SQL que pode reportar as tabelas com inplace ALTERs pendentes. Este script consegue fornecer o número de páginas existentes em cada versão da definição da tabela. Retorna a base de dados, a tabela, a versão(ões) e quantas páginas contém.&lt;br /&gt;&lt;br /&gt;O bom deste script é que é rápido (de uns segundos a poucos minutos para bases de dados muito grandes), e mostra a situação actual. Contrariamente à opção 1) acima, depois de fazermos os dummy UPDATEs numa tabela, essa mesma tabela não volta a aparecer no output do script. Apenas um aviso relativamente a isto: O script percorre o que chamamos de partition headers e estes só são escritos em disco durante um checkpoint. Assim, depois de correr os dummy UPDATEs devem forçar-se um checkpoint (ou esperar que ocorra um) antes de correr novamente o script.&lt;br /&gt;&lt;br /&gt;O script traduz-se num procedimento SPL e baseia-se em informação disponível nas views da base de dados sysmaster. O script foi testeado em todas as versões que consegui encontrar (7.31, 9.3, 9.4, 10, 11.1, 11.5 e 11.7) e correru em todas sem problemas. Assim, se estiver a fazer uma conversão de um sistema antigo e quiser limpar todos os inplace ALTERs pendentes nessa instância, isto pode ser uma grande ajuda.&lt;br /&gt;&lt;br /&gt;O script SQL contendo o procedimento está disponível no final deste artigo e não vou fazer uma explicação exaustiva do mesmo. Os desafios que enfrentei durante o desenvolvimento do procedimento foram principalmente entender se os os dados necessários estavam representados na base de dados sysmaster e também na interpretação desses dados (a representação dos dados é diferente conforme o "&lt;a href="http://pt.wikipedia.org/wiki/Extremidade_%28ordena%C3%A7%C3%A3o%29"&gt;endianess&lt;/a&gt;" da plataforma). Mais uma vez, na primeira questão a ajuda do Andreas Legner foi preciosa e para a segunda questão tive a ajuda do Art Kagel a quem enviou um sincero agradecimento. Ambos me ajudaram a rever o procedimento e identificaram alguns bugs feios que tinha nas primeiras tentativas.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Utilização&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Para usar esta função terá de copiar o código do &lt;i&gt;script&lt;/i&gt; que se encontra no final do artigo, colá-lo num dbaccess (ou outra ferramenta) e executá-lo numa das bases de dados da sua instância. O &lt;i&gt;script&lt;/i&gt; irá criar uma função chamada get_pending_ipa() que irá retornar os seguintes valores:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Nome da base de dados&lt;/li&gt;&lt;li&gt;Nome da tabela&lt;/li&gt;&lt;li&gt;Nome da partição&lt;/li&gt;&lt;li&gt;Tipo de objecto (pode ser &lt;i&gt;table&lt;/i&gt;, &lt;i&gt;partition&lt;/i&gt; ou &lt;i&gt;partition main&lt;/i&gt;)&lt;/li&gt;&lt;li&gt;Número da partição&lt;/li&gt;&lt;li&gt;&lt;i&gt;lockid&lt;/i&gt; da partição (o número da partição principal para tabelas fragmentadas)&lt;/li&gt;&lt;li&gt;Versão da estrutura da tabela&lt;/li&gt;&lt;li&gt;Número de páginas ainda existentes nesta versão&lt;/li&gt;&lt;/ul&gt;Se necessitar de criar a função numa versão 7 (pre-V9) deve alterar o cabeçalho e o final da função de acordo com o recomendado/comentado no código&lt;br /&gt;Para executar basta dar a instrução:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;execute function get_pending_ipa();&lt;br /&gt;ou&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;execute procedure get_pending_ipa();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Exclusão de garantia&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Apesar de o script ter sido testado tanto quanto pude, por favor assuma que o mesmo não é fornecido com qualquer tipo de garantia. Utilize-o por sua conta e risco. Nem eu nem o meu empregador poderão ser considerados responsáveis por qualquer mal ou prejuízo derivado do seu uso (difícil dado que apenas faz SELECTs), ou mais importante, por más decisões baseadas no seu output. Isto é apenas o normal termo de des-responsabilização. Naturalmente fiz o meu melhor para assegurar que o procedimento funciona bem e retorna resultados corretos. Qualquer problema que identifique no script ou sugestão de melhoria por favor contacte-me.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;SQL script:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #804040;"&gt;&lt;b&gt;CREATE&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;FUNCTION&lt;/span&gt;&amp;nbsp;get_pending_ipa() RETURNING&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: seagreen;"&gt;&lt;b&gt;VARCHAR&lt;/b&gt;&lt;/span&gt;(&lt;span style="color: magenta;"&gt;128&lt;/span&gt;) &lt;span style="color: slateblue;"&gt;as&lt;/span&gt;&amp;nbsp;database, &lt;span style="color: seagreen;"&gt;&lt;b&gt;VARCHAR&lt;/b&gt;&lt;/span&gt;(&lt;span style="color: magenta;"&gt;128&lt;/span&gt;) &lt;span style="color: slateblue;"&gt;as&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;table&lt;/span&gt;, &lt;span style="color: seagreen;"&gt;&lt;b&gt;VARCHAR&lt;/b&gt;&lt;/span&gt;(&lt;span style="color: magenta;"&gt;128&lt;/span&gt;) &lt;span style="color: slateblue;"&gt;as&lt;/span&gt;&amp;nbsp;partition, &lt;span style="color: seagreen;"&gt;&lt;b&gt;VARCHAR&lt;/b&gt;&lt;/span&gt;(&lt;span style="color: magenta;"&gt;9&lt;/span&gt;) &lt;span style="color: slateblue;"&gt;as&lt;/span&gt;&amp;nbsp;obj_type,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: seagreen;"&gt;&lt;b&gt;INTEGER&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;as&lt;/span&gt;&amp;nbsp;partnum, &lt;span style="color: seagreen;"&gt;&lt;b&gt;INTEGER&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;as&lt;/span&gt;&amp;nbsp;lockid, &lt;span style="color: slateblue;"&gt;SMALLINT&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;as&lt;/span&gt;&amp;nbsp;version, &lt;span style="color: seagreen;"&gt;&lt;b&gt;INTEGER&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;as&lt;/span&gt;&amp;nbsp;npages&lt;br /&gt;&lt;span style="color: blue;"&gt;-- For version 7.x use this header instead:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;--CREATE PROCEDURE get_pending_ipa() RETURNING VARCHAR(128), VARCHAR(128), VARCHAR(128), VARCHAR(9), INTEGER, INTEGER, SMALLINT, INTEGER;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- Name: $RCSfile: get_pending_ipa.sql,v $&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- CVS file: $Source: /usr/local/cvs/stable/informix/queries/get_pending_ipa.sql,v $&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- CVS id: $Header: /usr/local/cvs/stable/informix/queries/get_pending_ipa.sql,v 1.5 2011/09/09 20:57:31 fnunes Exp $&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- Revision: $Revision: 1.5 $&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- Revised on: $Date: 2011/09/09 20:57:31 $&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- Revised by: $Author: fnunes $&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- Support: Fernando Nunes - domusonline@gmail.com&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- Licence: This script is licensed as GPL ( &lt;a href="http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html"&gt;http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html&lt;/a&gt; )&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- Variables holding the database,tabnames and partnum&lt;/span&gt;&lt;br /&gt;DEFINE v_dbsname, v_old_dbsname &lt;span style="color: #804040;"&gt;&lt;b&gt;LIKE&lt;/b&gt;&lt;/span&gt;&amp;nbsp;sysmaster:systabnames.dbsname;&lt;br /&gt;DEFINE v_tabname, v_partname, v_old_tabname &lt;span style="color: #804040;"&gt;&lt;b&gt;LIKE&lt;/b&gt;&lt;/span&gt;&amp;nbsp;sysmaster:systabnames.tabname;&lt;br /&gt;DEFINE v_partnum, v_old_partnum &lt;span style="color: #804040;"&gt;&lt;b&gt;LIKE&lt;/b&gt;&lt;/span&gt;&amp;nbsp;sysmaster:syspaghdr.pg_partnum;&lt;br /&gt;DEFINE v_lockid, v_old_lockid &lt;span style="color: #804040;"&gt;&lt;b&gt;LIKE&lt;/b&gt;&lt;/span&gt;&amp;nbsp;sysmaster:sysptnhdr.lockid;&lt;br /&gt;DEFINE v_pg_next &lt;span style="color: seagreen;"&gt;&lt;b&gt;INTEGER&lt;/b&gt;&lt;/span&gt;;&lt;br /&gt;DEFINE v_pg_partnum &lt;span style="color: seagreen;"&gt;&lt;b&gt;INTEGER&lt;/b&gt;&lt;/span&gt;;&lt;br /&gt;DEFINE v_obj_type &lt;span style="color: seagreen;"&gt;&lt;b&gt;VARCHAR&lt;/b&gt;&lt;/span&gt;(&lt;span style="color: magenta;"&gt;9&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: blue;"&gt;-- Variables holding the various table versions and respective number of pages pending to migrate&lt;/span&gt;&lt;br /&gt;DEFINE v_version &lt;span style="color: slateblue;"&gt;SMALLINT&lt;/span&gt;;&lt;br /&gt;DEFINE v_pages &lt;span style="color: seagreen;"&gt;&lt;b&gt;INTEGER&lt;/b&gt;&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- Hexadecimal representation of version and pending number of pages&lt;/span&gt;&lt;br /&gt;DEFINE v_char_version &lt;span style="color: seagreen;"&gt;&lt;b&gt;CHAR&lt;/b&gt;&lt;/span&gt;(&lt;span style="color: magenta;"&gt;6&lt;/span&gt;);&lt;br /&gt;DEFINE v_char_pages &lt;span style="color: seagreen;"&gt;&lt;b&gt;CHAR&lt;/b&gt;&lt;/span&gt;(&lt;span style="color: magenta;"&gt;10&lt;/span&gt;);&lt;br /&gt;DEFINE v_aux_char &lt;span style="color: seagreen;"&gt;&lt;b&gt;CHAR&lt;/b&gt;&lt;/span&gt;(&lt;span style="color: magenta;"&gt;8&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: blue;"&gt;-- Hexadecimal representation of the slot 6 data. Each 16 bytes will appear as a record that needs to be concatenated&lt;/span&gt;&lt;br /&gt;DEFINE v_hexdata &lt;span style="color: seagreen;"&gt;&lt;b&gt;VARCHAR&lt;/b&gt;&lt;/span&gt;(&lt;span style="color: magenta;"&gt;128&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: blue;"&gt;-- Variable to hold the sysmaster:syssltdat hexadecimal representation of each 16 bytes of the slot data&lt;/span&gt;&lt;br /&gt;DEFINE v_slot_hexdata &lt;span style="color: seagreen;"&gt;&lt;b&gt;CHAR&lt;/b&gt;&lt;/span&gt;(&lt;span style="color: magenta;"&gt;40&lt;/span&gt;);&lt;br /&gt;DEFINE v_aux &lt;span style="color: seagreen;"&gt;&lt;b&gt;VARCHAR&lt;/b&gt;&lt;/span&gt;(&lt;span style="color: magenta;"&gt;128&lt;/span&gt;);&lt;br /&gt;DEFINE v_endian &lt;span style="color: seagreen;"&gt;&lt;b&gt;CHAR&lt;/b&gt;&lt;/span&gt;(&lt;span style="color: magenta;"&gt;6&lt;/span&gt;);&lt;br /&gt;DEFINE v_offset &lt;span style="color: slateblue;"&gt;SMALLINT&lt;/span&gt;;&lt;br /&gt;DEFINE v_slotoff &lt;span style="color: slateblue;"&gt;SMALLINT&lt;/span&gt;;&lt;br /&gt;DEFINE v_dummy &lt;span style="color: seagreen;"&gt;&lt;b&gt;INTEGER&lt;/b&gt;&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- In case we need to trace the function... Uncomment the following two lines&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;--SET &lt;/span&gt;&lt;span style="background-color: yellow;"&gt;&lt;span style="color: blue;"&gt;DEBUG&lt;/span&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;FILE TO "/tmp/get_pending_ipa.dbg";&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;--TRACE ON;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- Now lets find out the Endianess ( &lt;a href="http://en.wikipedia.org/wiki/Endianness"&gt;http://en.wikipedia.org/wiki/Endianness&lt;/a&gt; ) of this platform&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- The data in sysmaster:syssltdat will be different because of possible byte swap&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- Read the first slot of the rootdbs TBLSpace tblspace (0x00100001)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- The first 4 bytes hold the partition number (0x00100001)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #804040;"&gt;&lt;b&gt;SELECT&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s.hexdata[&lt;span style="color: magenta;"&gt;1&lt;/span&gt;,&lt;span style="color: magenta;"&gt;8&lt;/span&gt;]&lt;br /&gt;&lt;span style="color: slateblue;"&gt;INTO&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;v_hexdata&lt;br /&gt;&lt;span style="color: slateblue;"&gt;FROM&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sysmaster:syssltdat s&lt;br /&gt;&lt;span style="color: slateblue;"&gt;WHERE&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s.partnum = &lt;span style="color: magenta;"&gt;'0x100001'&lt;/span&gt;&amp;nbsp;&lt;span style="color: #804040;"&gt;&lt;b&gt;AND&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s.pagenum = &lt;span style="color: magenta;"&gt;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #804040;"&gt;&lt;b&gt;AND&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s.slotnum = &lt;span style="color: magenta;"&gt;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #804040;"&gt;&lt;b&gt;AND&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s.slotoff = &lt;span style="color: magenta;"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&amp;nbsp;v_hexdata = &lt;span style="color: magenta;"&gt;'01001000'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: slateblue;"&gt;THEN&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- Byte swap order, so we're little Endian (Intel, Tru64....)&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_endian = &lt;span style="color: magenta;"&gt;'LITTLE'&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: slateblue;"&gt;ELSE&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&amp;nbsp;v_hexdata = &lt;span style="color: magenta;"&gt;'00100001'&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;THEN&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- Just as we write it (no byte swap), so we're big Endian (Sparc, Power, Itanium...)&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_endian = &lt;span style="color: magenta;"&gt;'BIG'&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;ELSE&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- Just in case something weird (like a bug(!) or physical modification) happened&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RAISE &lt;span style="color: slateblue;"&gt;EXCEPTION&lt;/span&gt;&amp;nbsp;&lt;span style="color: magenta;"&gt;-746&lt;/span&gt;, &lt;span style="color: magenta;"&gt;0&lt;/span&gt;, &lt;span style="color: magenta;"&gt;'Invalid Endianess calculation... Check procedure code!!!'&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&lt;br /&gt;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- Flags to mark the beginning&lt;/span&gt;&lt;br /&gt;LET v_hexdata = &lt;span style="color: magenta;"&gt;"-"&lt;/span&gt;;&lt;br /&gt;LET v_old_dbsname = &lt;span style="color: magenta;"&gt;"-"&lt;/span&gt;;&lt;br /&gt;LET v_old_tabname = &lt;span style="color: magenta;"&gt;"-"&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- The information we want for each version description will occupy this number of characters&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- in the sysmaster:syssltdat.hexdata notation (after removing spaces). The size depends on the engine version.&lt;/span&gt;&lt;br /&gt;LET v_offset=DBINFO(&lt;span style="color: magenta;"&gt;'version'&lt;/span&gt;,&lt;span style="color: magenta;"&gt;'major'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&amp;nbsp;v_offset &amp;gt;= &lt;span style="color: magenta;"&gt;10&lt;/span&gt;&lt;br /&gt;&lt;span style="color: slateblue;"&gt;THEN&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_offset = &lt;span style="color: magenta;"&gt;48&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: slateblue;"&gt;ELSE&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_offset = &lt;span style="color: magenta;"&gt;40&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&lt;br /&gt;LET v_old_lockid = &lt;span style="color: magenta;"&gt;-1&lt;/span&gt;;&lt;br /&gt;FOREACH&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- This query will browse through all the instance partitions, excluding sysmaster database, and will look for&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- any extended partition header (where partition header "next" field is not 0)&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- the ABS(...) is just a trick to make partnums that are equal to lock id appear at the end&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #804040;"&gt;&lt;b&gt;SELECT&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;t.dbsname, t.tabname, t1.tabname, t.partnum, p.pg_partnum, p.pg_next, h.lockid, ABS(h.lockid - h.partnum)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;INTO&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;v_dbsname, v_partname ,v_tabname, v_partnum, v_pg_partnum, v_pg_next, v_lockid, v_dummy&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;FROM&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sysmaster:systabnames t,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sysmaster:syspaghdr p,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sysmaster:sysptnhdr h,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sysmaster:systabnames t1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;WHERE&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p.pg_partnum = sysmaster:partaddr(sysmaster:partdbsnum(t.partnum),&lt;span style="color: magenta;"&gt;1&lt;/span&gt;) &lt;span style="color: #804040;"&gt;&lt;b&gt;AND&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p.pg_pagenum = sysmaster:partpagenum(t.partnum) &lt;span style="color: #804040;"&gt;&lt;b&gt;AND&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;t.dbsname &lt;span style="color: #804040;"&gt;&lt;b&gt;NOT&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #804040;"&gt;&lt;b&gt;IN&lt;/b&gt;&lt;/span&gt;&amp;nbsp;(&lt;span style="color: magenta;"&gt;'sysmaster'&lt;/span&gt;) &lt;span style="color: #804040;"&gt;&lt;b&gt;AND&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;h.partnum = t.partnum &lt;span style="color: #804040;"&gt;&lt;b&gt;AND&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;t1.partnum = h.lockid &lt;span style="color: #804040;"&gt;&lt;b&gt;AND&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p.pg_next != &lt;span style="color: magenta;"&gt;0&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;ORDER&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;BY&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;t.dbsname, t.tabname, &lt;span style="color: magenta;"&gt;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;DESC&lt;/span&gt;, t.partnum&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&amp;nbsp;v_lockid = v_partnum&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;THEN&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&amp;nbsp;v_lockid = v_old_lockid&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;THEN&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_obj_type = &lt;span style="color: magenta;"&gt;"Part Main"&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;ELSE&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_obj_type = &lt;span style="color: magenta;"&gt;"Table"&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;ELSE&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_obj_type = &lt;span style="color: magenta;"&gt;"Part"&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_old_lockid = v_lockid;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WHILE v_pg_next != &lt;span style="color: magenta;"&gt;0&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- Find if we're dealing with a fragmented table or not...&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- While this extended partition page points to another one...&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- Get all the slot 6 data (where the version metadata is stored - version, number of pages, descriptor page etc.&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FOREACH&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #804040;"&gt;&lt;b&gt;SELECT&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;REPLACE(s.hexdata, &lt;span style="color: magenta;"&gt;' '&lt;/span&gt;), s.slotoff, p.pg_next&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;INTO&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;v_slot_hexdata, v_slotoff, v_pg_next&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;FROM&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sysmaster:syspaghdr p,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sysmaster:syssltdat s&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;WHERE&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s.partnum = p.pg_partnum &lt;span style="color: #804040;"&gt;&lt;b&gt;AND&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s.pagenum = p.pg_pagenum &lt;span style="color: #804040;"&gt;&lt;b&gt;AND&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s.slotnum = &lt;span style="color: magenta;"&gt;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #804040;"&gt;&lt;b&gt;AND&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p.pg_partnum = v_pg_partnum &lt;span style="color: #804040;"&gt;&lt;b&gt;AND&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p.pg_pagenum = v_pg_next&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&amp;nbsp;( v_dbsname != v_old_dbsname &lt;span style="color: #804040;"&gt;&lt;b&gt;OR&lt;/b&gt;&lt;/span&gt;&amp;nbsp;v_tabname != v_old_tabname &lt;span style="color: #804040;"&gt;&lt;b&gt;OR&lt;/b&gt;&lt;/span&gt;&amp;nbsp;v_partnum != v_old_partnum)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;THEN&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_old_dbsname = v_dbsname;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_old_tabname = v_tabname;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_old_partnum = v_partnum;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- First iteraction for each table&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_hexdata = v_slot_hexdata;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;ELSE&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- Next iteractions for each table&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_hexdata = TRIM(v_hexdata) || v_slot_hexdata;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&amp;nbsp;LENGTH(v_hexdata) &amp;gt;= v_offset&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;THEN&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- We already have enough data for a version within a table&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- &lt;/span&gt;&lt;span style="background-color: yellow;"&gt;&lt;span style="color: blue;"&gt;Note&lt;/span&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;that we probably have part of the next version description in v_hexdata&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- So we need to copy part of it, and keep the rest for next iteractions&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_aux=v_hexdata;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_hexdata=SUBSTR(v_aux,v_offset+&lt;span style="color: magenta;"&gt;1&lt;/span&gt;,LENGTH(v_aux)-v_offset);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- Split the version and number of pending pages part...&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version = v_aux[&lt;span style="color: magenta;"&gt;1&lt;/span&gt;,&lt;span style="color: magenta;"&gt;4&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages = v_aux[&lt;span style="color: magenta;"&gt;9&lt;/span&gt;,&lt;span style="color: magenta;"&gt;16&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- Create a usable hex number. Prefix it with '0x' and convert due to little endian if that's the case&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&amp;nbsp;v_endian = &lt;span style="color: magenta;"&gt;"BIG"&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;THEN&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version = &lt;span style="color: magenta;"&gt;'0x'&lt;/span&gt;||v_char_version;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages = &lt;span style="color: magenta;"&gt;'0x'&lt;/span&gt;||v_char_pages;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;ELSE&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_aux_char = v_char_version;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version[&lt;span style="color: magenta;"&gt;5&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;1&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version[&lt;span style="color: magenta;"&gt;6&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;2&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version[&lt;span style="color: magenta;"&gt;4&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;4&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version[&lt;span style="color: magenta;"&gt;3&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;3&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version[&lt;span style="color: magenta;"&gt;2&lt;/span&gt;]=&lt;span style="color: magenta;"&gt;'x'&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version[&lt;span style="color: magenta;"&gt;1&lt;/span&gt;]=&lt;span style="color: magenta;"&gt;'0'&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_aux_char = v_char_pages;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;9&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;1&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;10&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;2&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;7&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;3&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;8&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;4&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;6&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;6&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;5&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;5&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;3&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;7&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;4&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;8&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;2&lt;/span&gt;]=&lt;span style="color: magenta;"&gt;'x'&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;1&lt;/span&gt;]=&lt;span style="color: magenta;"&gt;'0'&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- HEX into DEC (integer)&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_version = TRUNC(v_char_version + &lt;span style="color: magenta;"&gt;0&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_pages = TRUNC(v_char_pages + &lt;span style="color: magenta;"&gt;0&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&amp;nbsp;v_pages &amp;gt; &lt;span style="color: magenta;"&gt;0&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;THEN&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- This version has pending pages so show it...&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;RETURN&lt;/span&gt;&amp;nbsp;TRIM(v_dbsname), TRIM(v_tabname), TRIM(v_partname), TRIM(v_obj_type), v_partnum, v_lockid, v_version, v_pages &lt;span style="color: slateblue;"&gt;WITH&lt;/span&gt;&amp;nbsp;RESUME;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;FOREACH&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&amp;nbsp;LENGTH(v_hexdata) &amp;gt;= v_offset&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;THEN&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- If we still have data to process...&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_aux=v_hexdata;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version = v_aux[&lt;span style="color: magenta;"&gt;1&lt;/span&gt;,&lt;span style="color: magenta;"&gt;4&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages = v_aux[&lt;span style="color: magenta;"&gt;9&lt;/span&gt;,&lt;span style="color: magenta;"&gt;16&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&amp;nbsp;v_endian = &lt;span style="color: magenta;"&gt;"BIG"&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;THEN&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version = &lt;span style="color: magenta;"&gt;'0x'&lt;/span&gt;||v_char_version;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages = &lt;span style="color: magenta;"&gt;'0x'&lt;/span&gt;||v_char_pages;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;ELSE&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_aux_char = v_char_version;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version[&lt;span style="color: magenta;"&gt;5&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;1&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version[&lt;span style="color: magenta;"&gt;6&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;2&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version[&lt;span style="color: magenta;"&gt;4&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;4&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version[&lt;span style="color: magenta;"&gt;3&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;3&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version[&lt;span style="color: magenta;"&gt;2&lt;/span&gt;]=&lt;span style="color: magenta;"&gt;'x'&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_version[&lt;span style="color: magenta;"&gt;1&lt;/span&gt;]=&lt;span style="color: magenta;"&gt;'0'&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_aux_char = v_char_pages;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;9&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;1&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;10&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;2&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;7&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;3&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;8&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;4&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;6&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;6&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;5&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;5&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;3&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;7&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;4&lt;/span&gt;]=v_aux_char[&lt;span style="color: magenta;"&gt;8&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;2&lt;/span&gt;]=&lt;span style="color: magenta;"&gt;'x'&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_char_pages[&lt;span style="color: magenta;"&gt;1&lt;/span&gt;]=&lt;span style="color: magenta;"&gt;'0'&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- HEX into DEC (integer)&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_version = TRUNC(v_char_version + &lt;span style="color: magenta;"&gt;0&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LET v_pages = TRUNC(v_char_pages + &lt;span style="color: magenta;"&gt;0&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&amp;nbsp;v_pages &amp;gt; &lt;span style="color: magenta;"&gt;0&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;THEN&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;-- This version has pending pages so show it...&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;RETURN&lt;/span&gt;&amp;nbsp;TRIM(v_dbsname), TRIM(v_tabname), TRIM(v_partname), TRIM(v_obj_type), v_partnum, v_lockid, v_version, v_pages &lt;span style="color: slateblue;"&gt;WITH&lt;/span&gt;&amp;nbsp;RESUME;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;IF&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;WHILE&lt;br /&gt;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;FOREACH;&lt;br /&gt;&lt;span style="color: slateblue;"&gt;END&lt;/span&gt;&amp;nbsp;&lt;span style="color: slateblue;"&gt;FUNCTION&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: blue;"&gt;-- For version 7.x use this close statement instead:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;--END PROCEDURE;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-5579898134638612104?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/5579898134638612104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=5579898134638612104' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/5579898134638612104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/5579898134638612104'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/09/get-pending-in-place-alters-obter-as.html' title='Get pending In Place ALTERs / Obter as tabelas com InPlace ALTERs pendentes'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-4094195399584037925</id><published>2011-08-21T00:25:00.001+01:00</published><updated>2011-08-21T00:33:46.668+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IBM'/><category scheme='http://www.blogger.com/atom/ns#' term='acquisition'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='futuro'/><category scheme='http://www.blogger.com/atom/ns#' term='aquisição'/><category scheme='http://www.blogger.com/atom/ns#' term='história'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><category scheme='http://www.blogger.com/atom/ns#' term='future'/><title type='text'>10 years of IBM / 10 anos de IBM</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;English version&lt;br /&gt;&lt;br /&gt;On July 2, 2001, &lt;a href="http://www-03.ibm.com/press/us/en/pressrelease/1174.wss"&gt;IBM announced the completion of Informix acquisition&lt;/a&gt;. So, 10 years have passed since the deal that changed many people lives. A lot was written at the time and since then about the deal, about Informix future, about competitors reactions etc. This historical milestone made me take a look back and think about what's been going on. There are several perspectives about this: The professional, personal, the technical and the marketing ones (and probably more that don't come to mind at this moment). Personally, the acquisition happened three years after I joined Informix Portugal. At the time I was already deeply involved with a Portuguese customer (large Telco) and I believe I gained precious experience since then. Being at IBM I had the opportunity to have some experience with other products (from areas that touch the database area), although the focus was and still is Informix. Informix allowed me to interact with many large (from a small country perspective) companies. So, it was a very positive transition. Of course not everything is perfect. Needless to say that the environment in a small company branch (around 20 people at the time) is by no means similar to the environment of a larger corporation like IBM. The processes inside big corporations are more complex. This is a fact and there's nothing we can do against it.&lt;br /&gt;&lt;br /&gt;From a technical perspective, the Informix evolution was incredible. For those of you who know Informix, just think about the releases that came out inside IBM: 9.3 (little to no influence from IBM because it was launched in 2001), 9.4 (2003), 10 (2005), 11.10 (2007), 11.50 (2008) and 11.7 (2010). By the way, from these, only 9.3 has no support at all and 9.4 and 10 are on limited support. There's value for money here, and investment protection. You can compare this to our main competitor for example. They launched 9i R1, 9i R2, 10g R1,  10 R2, 11g R1 and 11g R2. To the best of my knowledge only latest two are fully supported, so more or less the same number of releases and more supported versions for us. Not bad for a database which had no future ten years ago, I'd say.&lt;br /&gt;If I try to recall all the new features I'll end up with another very large article. But some of them must be mentioned:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;9.3&lt;br /&gt;ER in the ORDBMS product line (9.x)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;9.4&lt;br /&gt;Larger chunks&lt;br /&gt;ER and HDR at the same time&lt;br /&gt;PAM authentication&lt;br /&gt;B-Tree scanners (as opposed to older B-Tree cleaner)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;10&lt;br /&gt;Multiple page sizes&lt;br /&gt;Online index build&lt;br /&gt;Column encryption&lt;br /&gt;External directives&lt;br /&gt;Table level restore&lt;br /&gt;&lt;/li&gt;&lt;li&gt;11.10&lt;br /&gt;MACH 11 (multiple secondary nodes)&lt;br /&gt;Non blocking checkpoints&lt;br /&gt;Open Admin Tool&lt;br /&gt;SQL admin API&lt;br /&gt;Database scheduler&lt;br /&gt;Last Committed Read&lt;br /&gt;&lt;/li&gt;&lt;li&gt;11.50&lt;br /&gt;Updatable secondaries&lt;br /&gt;Compression&lt;br /&gt;Connection Manager&lt;br /&gt;Start of XPS to IDS feature porting&lt;br /&gt;&lt;/li&gt;&lt;li&gt;11.70&lt;br /&gt;Storage provisioning&lt;br /&gt;Non OS users (mapped users)&lt;br /&gt;No limit for the number of extents&lt;br /&gt;On line table reorg&lt;br /&gt;Several XPS features (multi-index path, star join...)&lt;br /&gt;Informix warehous accelerator&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;And then we get to the marketing perspective... This is the fun part. It's a never ending discussion, and I thought it would be interesting to make some comparisons, like for example quotes versus reality. Announcements versus reality. Declarations of intentions versus reality. I browsed the Internet trying to find what people said and thought at the time and since then.&lt;br /&gt;&lt;br /&gt;Let's start a few years before:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"I think Informix is doing a great job of marketing.  They now get the  Sybase marketing award. It's something we have  never done a very good  job of. Talk to somebody at Sybase or Microsoft  and ask them what they  think of DataBlades. Everyone thinks it's  crazy. It's not that it's a  bad idea -- it's madness. And  they did not -- they did not -- integrate  those two products. They did  not, they cannot, they will not, it's  impossible.", Larry Ellison, at &lt;/span&gt;&lt;a style="font-style: italic;" href="http://books.google.pt/books?id=YzoEAAAAMBAJ&amp;amp;printsec=frontcover&amp;amp;lr=&amp;amp;hl=en#v=onepage&amp;amp;q&amp;amp;f=false"&gt;InfoWorld interview&lt;/a&gt;&lt;span style="font-style: italic;"&gt;, February 1997&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Actually, we now "activate" ("register" in Informix jargon) datablades automatically if the user calls a function that belong to one of them. And we ship several of them for free. One of them (TimeSeries) is used to beat competition on "smart metering". Other (BTS) is used to incorporate open source text indexing technology into Informix.&lt;br /&gt;On the same article, Larry Ellison mentions that Informix had 4 products. Although he apparently only names 3 (and 2 seem to be the same), this was in part true. There was the "OLTP" engine, the "DW" (XPS) and the Universal Server (IUS). These days are gone. XPS does still exists, although some of it's functionality is in IDS. There is no distinction between OLTP and "object" or universal servers.&lt;br /&gt;&lt;br /&gt;By the time of the acquisition:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"We've found in the past is that when you're acquiring other products, the integration problem is greater than the value you gain from acquiring the product. This will be an integration nightmare.", Paul Marriott, business development manager for 9I at Oracle, in &lt;/span&gt;&lt;a style="font-style: italic;" href="http://www.arnnet.com.au/article/24983/ibm_informix_swoop_puzzles_database_resellers/"&gt;ARNnet site&lt;/a&gt;&lt;span style="font-style: italic;"&gt;, on April 2001&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Was this opinion taken into account when Oracle bought JD Edwards, Peoplesoft, Siebel, Hyperion, Innobase,  BEA, Sun....? I believe not. Maybe they just don't learn from their "mistakes", or this quote was just another FUD statement...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"&lt;/span&gt;&lt;strong style="font-weight: normal; font-style: italic;"&gt;Surely Oracle is going to pick up a few customers from you though -especially the Informix customers?&lt;/strong&gt; &lt;p style="font-style: italic;"&gt;JK; I don't think you can make that general a statement. Oracle is  trying to give the impression that we are going to tell the Informix  customers that they've now got to move to DB2. But obviously we aren't  doing that. We acquired the Informix assets because we value them. We  aren't going to force a migration on customers and partners that isn't  right for them - that makes no business sense at all. We've spoken to  the Informix customers and partners and have told them that Informix  will be supported and developed for the foreseeable future - and the  Informix customers are very happy with this. They appear to like the  whole proposition so we certainly don't anticipate losing them to  Oracle." , Jim Kelly, IBM's Vice President, Marketing Data Management Solutions Division, &lt;a href="http://www.it-director.com/technology/content.php?cid=1978"&gt;in an interview&lt;/a&gt; to an analyst from Bloor Research, on July 2001&lt;br /&gt;&lt;/p&gt;AFAIK, no customer was forced to move to DB2. Some customers were forced to move, because their application suppliers (SAP for example) discontinued Informix in their latest  versions. These customers had the chance to choose the new database platform. Some choose DB2, others Oracle, others SQL Server (or other databases like SAPdb)... Similar statements were produced by different IBM executives at the time of the acquisition and later.&lt;br /&gt;&lt;br /&gt;And just for fun:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"But quite frankly if Informix is still being marketed as an&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;independent product five years from now I'll be shocked.", Daniel Morgan, an Oracle ACE in &lt;/span&gt;&lt;a style="font-style: italic;" href="http://groups.google.com/group/comp.databases.oracle.server/browse_thread/thread/79aa1432fa790506/0eeb035339cc15ca?hl=pt&amp;amp;lnk=gst&amp;amp;q=if+informix+is+marketed#0eeb035339cc15ca"&gt;comp.databases.oracle.server&lt;/a&gt;&lt;span style="font-style: italic;"&gt; on June 2001&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hopefully,  five or six years after the predicted date, he has already recovered from the shock.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let's leave the quotes... I'd also like to give you an example of "declarations of intentions vs reality". While working on a project with another IBM product, I felt the need to test something with a competitor (Oracle) database which is used at the customer site. For my purposes the "free edition" was perfectly enough and it allowed me to work on my own environment. I did the download, but after some days I stopped to think about one detail: The current available version of the "free edition" was 10g (launched 4 or 5 years ago). Now... this version is not fully supported anymore (at least without further costs). So I decided to look for a more recent version. Guess what? It' not available. Some more investigation showed me that a new version &lt;a href="http://forums.oracle.com/forums/ann.jspa?annID=1564"&gt;was made available in April this year, but only for "beta"&lt;/a&gt;. Now... What on earth is a "beta" version of a free edition?! After all the product should be the same. Only with certain restrictions.&lt;br /&gt;If you want to compare this with the IBM policy for Informix, you'll noticed that the "free edition" is up to date with the latest available fixpack. Do you notice a different behavior here? I do. And I don't think that's because I work for IBM...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;On a more personal perspective, from local market, we see that we haven't been loosing customers. More important our customer are very happy with Informix for the well known reasons (reliability, simplicity, robustness, ease of management). This is not marketing. It's a bit hard to point out a true "pure" Informix DBA and I know the biggest installations in my country. We have Informix in some of the biggest retail chains, in the Telcos, in logistics/transportation, in Finance, in central and local administration and in industrial environments. And all of these barely notice that they run Informix. This is a great achievement, but at the same time I feel it's also a downside. Although this is a paradox, I truly believe that a software that has problems may have better chances of success. Why? Because it makes the people who work with it more "visible" when they solve problems.&lt;br /&gt;As an example, in 2010 I was extensively congatulated when I got involved in a critical situation (caused by a sequence of human errors). The issue was escalated to an high level, and after it was solved the appreciation messages and the echos spread across the hierarchical chain. Now... In a normal situation, no problem should have ocurred, and I would still be completely anonymous from a hierachical point of view.&lt;br /&gt;People who manage Informix tend to do other stuff as well and many times they're a bit "invisible". This is not fair since it also means they're doing their job right, but I've seen this happen several times. You probably know the saying... It's better to have "bad publicitly" than no publicity at all...&lt;br /&gt;&lt;br /&gt;Now, let's take a look at what changed in Informix (not the new features) since the acquisition:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It gained presence in the IBM events like Information on Demand&lt;/li&gt;&lt;li&gt;We have monthly webcasts (chat with the labs)&lt;/li&gt;&lt;li&gt;We have PIDs (Post Interim Drops) which are cumulative patch updates This means that I rarely ask for a specific patch since most of the time there's a PID with the fix already available&lt;/li&gt;&lt;li&gt;We've been seeing major version releases each 1-2 years (2001,2003,2005,2007,2008,2010). And we've been having new fixpacks each 3 or 4 months which include new features&lt;/li&gt;&lt;li&gt;We have InfoCenter with the most up to date documentation in an easily searchable interface&lt;/li&gt;&lt;li&gt;We still have the PDF documentation for the people who know their ways around the manuals&lt;/li&gt;&lt;li&gt;We have better integration with the IBM product porfolio&lt;/li&gt;&lt;li&gt;Informix is used as a repository for some of these products (Cognos express, Optim as an option...)&lt;/li&gt;&lt;li&gt;Some new features came directly from other products (DB2 for example). Meaning we get improvements with little engineering effort&lt;/li&gt;&lt;li&gt;We have a wider range of editions, including a free one&lt;/li&gt;&lt;li&gt;We are still innovators, as the recent TimeSeries success stories show. There are new requirements and we're able to fulfill them&lt;/li&gt;&lt;li&gt;Informix is a brand inside the IBM Information Management pillar. Remember that at first we were integrated in the "DB2" pillar. Informix is currently on par with DB2, Cognos, Guardium etc.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;... And what didn't change:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Informix is still light, easy to install and manage&lt;/li&gt;&lt;li&gt;Informix is still robust&lt;/li&gt;&lt;li&gt;Informix still scales pretty well&lt;/li&gt;&lt;li&gt;Informix support is still good (I'm biased, but I talk a lot with customers that have to deal with other vendors support)&lt;/li&gt;&lt;li&gt;Customers still like Informix&lt;/li&gt;&lt;li&gt;People still complain about the marketing of the product&lt;/li&gt;&lt;li&gt;We don't see Informix in the news&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iiug.org/"&gt;IIUG&lt;/a&gt; is still a great asset for the Informix community&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I believe most people reading this who are aware of Informix history may consider I looked only at the bright side, and there is a dark side. Things that were not accomplished or things that become worst since the acquisition. But keep in mind that it's not totally fair to compare what happened inside IBM with what happened before IBM (specially during the "golden years"). A fair comparison would have to be done between what would have happened if IBM had not buy Informix, and that's impossible to tell. Naturally every Informix supporter can think that it should have more visibility inside IBM (this is a general idea we pick from the forums and independent blogs and sites), or that we're lacking better marketing etc.&lt;br /&gt;From my point of view the balance is positive. And I'm looking forward to the 20th anniversary after IBM acquisition. Let's see what happens in the next ten years. Ten years ago I think many people would not expect the evolution we had.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Versão Portuguesa&lt;br /&gt;&lt;br /&gt;No dia 2 de Julho de 2001 &lt;a href="http://www-03.ibm.com/press/us/en/pressrelease/1174.wss"&gt;a IBM anunciou a conclusão da aquisição da Informix&lt;/a&gt;. Portanto, passaram 10 anos desde o negócio que mudou a vida de muitas pessoas. Muito foi escrito na altura e desde então sobre o negócio, sobre o futuro do Informix, sobre as reacções da concorrência etc. Este marco histórico fez-me olhar para trás e pensar sobre o que se tem passado.  Há várias perspectivas sobre isto: A pessoal, a profissional, a técnica e a de &lt;span style="font-style: italic;"&gt;marketing&lt;/span&gt; (bem como outras que não me ocorrem de momento).&lt;br /&gt;Pessoalmente, a aquisição aconteceu três anos depois de ter ingressado na Informix Portugal. Na altura já estava bastante envolvido com um cliente Português (grande empresa de telecomunicações) e penso que ganhei uma experiência preciosa desde então. Pertencer à IBM deu-me oportunidade de me envolver com outros produtos (de outras áreas, mas que tocam o mundo das bases de dados), embora o foco fosse e ainda o seja, o Informix. O Informix permitiu-me interagir com várias grandes (da perpectiva de um país pequeno) empresas. Portanto foi uma transição muito positiva. Naturalmente nem tudo é perfeito. Escusado será dizer que o ambiente de uma filial (cerca de 20 pessoas na altura) de uma pequena companhia mundial, não é de todo semelhante ao ambiente de uma grande companhia como é o caso da IBM. Os processos dentro de grandes empresas têm necessariamente de ser mais complexos. Isto é um facto e ninguém poderá fazer nada contra isso.&lt;br /&gt;&lt;br /&gt;Do ponto de vista técnico, a evolução do Informix foi incrível. Para os que conhecem Informix, basta que recordem as versões que sairam já dentro da IBM: 9.3 (pequena ou nenhum influência da IBM dado que foi lançada em 2001), 9.4  (2003), 10 (2005), 11.10 (2007), 11.50 (2008) e 11.7 (2010). Já agora, destas apenas a 9.3 não tem qualquer tipo de suporte e a 9.4 e 10 estão num esquema de suporte limitado (mas sem custos adicionais). Há aqui valor e protecção de investimento. Pode comparar isto com o nosso maior concorrente:  Lançaram o 9i R1, 9i R2, 10g R1,  10 R2, 11g R1 and 11g R2. Tanto quanto julgo saber,  só os últimos dois são suportados sem mais custos adicionais, por isso, mais ou menos o mesmo número de &lt;span style="font-style: italic;"&gt;releases&lt;/span&gt; e maior número delas suportadas por nós. Nada mal para uma base de dados que como muitos diziam não tinha futuro há dez anos atrás.&lt;br /&gt;&lt;br /&gt;Se enumerasse as novas funcionalidades acabaria com mais um artigo muito grande. Mas pelo menos algumas devem ser referidas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;9.3&lt;br /&gt;ER na linha de produto ORDBMS (9.x)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;9.4&lt;br /&gt;Chunks maiores que 2GB&lt;br /&gt;ER e HDR ao mesmo tempo&lt;br /&gt;Autenticação PAM&lt;br /&gt;B-Tree &lt;span style="font-style: italic;"&gt;scanners&lt;/span&gt; (em oposição à anterior B-Tree &lt;span style="font-style: italic;"&gt;cleaner&lt;/span&gt;)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;10&lt;br /&gt;Diferentes tamanhos de página&lt;br /&gt;Criação de indíces &lt;span style="font-style: italic;"&gt;Online&lt;/span&gt;&lt;br /&gt;Encriptação de colunas&lt;br /&gt;Directivas externas&lt;br /&gt;Restore de uma tabela a partir de um arquivo&lt;br /&gt;&lt;/li&gt;&lt;li&gt;11.10&lt;br /&gt;MACH 11 (multiplos nós secundários)&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Checkpoints&lt;/span&gt; sem bloqueio&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Open Admin Tool&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;SQL admin API&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Database scheduler&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt; Last Committed Read&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;11.50&lt;br /&gt;Secundários com possibilidade de alterações (DML)&lt;br /&gt;Compressão&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Connection Manager&lt;/span&gt;&lt;br /&gt;Início da transposição de funcionalidades do XPS para o IDS&lt;br /&gt;&lt;/li&gt;&lt;li&gt;11.70&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Storage provisioning&lt;/span&gt;&lt;br /&gt;Utilizadores não reconhecidos pelo SO (&lt;span style="font-style: italic;"&gt;mapped users&lt;/span&gt;)&lt;br /&gt;Eliminação do limite de extents para uma partição&lt;br /&gt;Reorganização de tabelas &lt;span style="font-style: italic;"&gt;Online&lt;/span&gt;&lt;br /&gt;Várias funcionalidades do XPS (&lt;span style="font-style: italic;"&gt;multi-index path, star join...&lt;/span&gt;)&lt;br /&gt;Informix Warehouse Accelerator&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;E agora temos a perspective de &lt;span style="font-style: italic;"&gt;marketing&lt;/span&gt;.... Este é o aspecto mais divertido. Trata-se de uma discussão sem fim e lembrei-me que seria interessante fazer algumas comparações, como por exemplo citações &lt;span style="font-style: italic;"&gt;versus&lt;/span&gt; realidade, anúncios &lt;span style="font-style: italic;"&gt;versus&lt;/span&gt; realidade e declarações de intenções &lt;span style="font-style: italic;"&gt;versus&lt;/span&gt; realidade. Efectuei umas pesquisas sobre o que as pessoas disseram na altura e desde então.&lt;br /&gt;&lt;br /&gt;Comecemos uns anos antes (tradução pessoal. Pode consultar o original nos &lt;span style="font-style: italic;"&gt;links&lt;/span&gt;):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"Eu penso que a Informix está a fazer grande trabalho de marketing.  Eles agora obtêm o prémio de &lt;/span&gt;&lt;span style="font-style: italic;"&gt;marketing &lt;/span&gt;&lt;span style="font-style: italic;"&gt;Sybase. É algo em que nós nunca fizemos um bom trabalho. Fale com alguém na Sybase ou Microsoft e pergunte-lhes o que pensam dos Datablades. Toda a gente lhe dirá que é uma loucura. Não é que seja uma má ideia -- é loucura. E eles não -- eles não -- integraram esses dois produtos. Eles não o fizeram, não o podem fazer, não o irão fazer, é impossível.", Larry Ellison, numa &lt;/span&gt;&lt;a style="font-style: italic;" href="http://books.google.pt/books?id=YzoEAAAAMBAJ&amp;amp;printsec=frontcover&amp;amp;lr=&amp;amp;hl=en#v=onepage&amp;amp;q&amp;amp;f=false"&gt;entrevista à InfoWorld&lt;/a&gt;&lt;span style="text-decoration: underline; font-style: italic;"&gt;,&lt;/span&gt;&lt;span style="font-style: italic;"&gt; em Fevereiro de 1997&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Na verdade, nós actualmente "activamos" ("registamos" em linguagem Informix) datablades automaticamente sempre que um utilizador chama uma função que pertence a um deles. E fornecemos vários gratuitamente. Um deles (TimeSeries) é usado para bater a concorrência em "&lt;span style="font-style: italic;"&gt;smart metering&lt;/span&gt;". Outro (BTS) é usado para incorporar tecnologia de código fonte aberto de indexação de texto, no Informix.&lt;br /&gt;No mesmo artigo, Larry Ellison menciona que o Informix tinha 4 produtos diferentes. Embora aparentemente só refira 3 (e dois parecem ser o mesmo), isto era em parte verdade. Existia o motor "OLTP", o de "DW" (XPS) e o servidor universal (IUS). Esses dias já terminaram. O XPS ainda existe, embora muitas das funcionalidades já estejam no IDS. Não há distinção entre o produto para OLTP e o que na altura era chamado de servidor universal.&lt;br /&gt;&lt;br /&gt;Na altura da aquisição:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"Descobrimos no passado que quando adquirimos outros produtos, o problema da integração é maior que o valor ganho pela aquisição do produto. Isto será um pesadelo de integração", Paul Marriott,  gestor de desenvolvimento de negócio para o 9I na Oracle, no &lt;/span&gt;&lt;a style="font-style: italic;" href="http://www.arnnet.com.au/article/24983/ibm_informix_swoop_puzzles_database_resellers/"&gt;site ARNnet&lt;/a&gt;&lt;span style="font-style: italic;"&gt;, em Abril de 2001&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Esta opinião foi tida em conta quando a Oracle comprou a JDEdwards,  Peoplesoft, Siebel, Hyperion, Innobase, BEA, Sun....? Calculo que não. Talvez não aprendam com os erros ou esta citação tenha sido apenas mais uma a contribuir para o FUD (&lt;span style="font-style: italic;"&gt;fear, uncertainty and doubt&lt;/span&gt;)...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"&lt;/span&gt;&lt;strong style="font-weight: normal; font-style: italic;"&gt;Certamente a Oracle irá conseguir obter algums clientes vossos - especialmente clientes Informix?&lt;/strong&gt; &lt;p style="font-style: italic;"&gt;JK; Não me parece que se possa generalizar essa afirmação. A Oracle está a tentar dar a impressão que nós iremos dizer aos clientes Informix que agora têm de migrar para DB2. Mas obviamente não faremos isso. Adquirimos os bens da Informix porque os valorizamos. Não iremos forçar uma migração em clientes e parceiros que não seja indicada para eles - Isso não faz qualquer sentido em termos de negócio. Temos falado com clientes e parceiros Informix e temos dito que o Informix será suportado e desenvolvido no futuro previsível - e os clientes Informix estão muito contentes com isto. Parecem gostar de toda a proposição de valor e portanto não antecipamos perdê-los para a Oracle", Jim Kelly, IBM's Vice President, Marketing Data Management  Solutions Division, &lt;a href="http://www.it-director.com/technology/content.php?cid=1978"&gt;numa entrevista&lt;/a&gt; a um analista da Bloor Research, em Julho de 2001&lt;br /&gt;&lt;/p&gt;Tanto quanto sei, nenhum cliente foi forçado a migrar para DB2. Alguns clientes foram forçados a migrar porque os seus fornecedores aplicacionais (SAP por exemplo) descontinuaram o suporte para Informix nas suas versões mais recentes. Estes clientes tiveram a possibilidade de escolher a nova plataforma para base de dados. Alguns escolheram DB2, outros Oracle e outros SQL Server (ou outras BDs como SAPdb)...&lt;br /&gt;Afirmações semelhantes foram proferidas por outros executivos da IBM na altura da aquisição e após a mesma.&lt;br /&gt;&lt;br /&gt;E apenas por brincadeira:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"Mas muito sinceramente, se o Informix ainda for comercializado como um produto independente, daqui a cinco anos ficarei chocado.", Daniel Morgan, um Oracle ACE no &lt;/span&gt;&lt;a style="font-style: italic;" href="http://groups.google.com/group/comp.databases.oracle.server/browse_thread/thread/79aa1432fa790506/0eeb035339cc15ca?hl=pt&amp;amp;lnk=gst&amp;amp;q=if+informix+is+marketed#0eeb035339cc15ca"&gt;comp.databases.oracle.server&lt;/a&gt;&lt;span style="font-style: italic;"&gt; em Junho de 2001&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Com um pouco de sorte, após cinco ou seis anos depois da data prevista, ele já terá recuperado do choque.&lt;br /&gt;&lt;br /&gt;Deixemos as citações... Também gostaria de deixar um exemplo de "declarações de intensões &lt;span style="font-style: italic;"&gt;versus&lt;/span&gt; realidade". Durante um projecto com outro produto IBM, senti a necessidade de testar algo com uma base de dados da concorrência (Oracle), que é usada no cliente onde decorre o projecto. Para as minhas necessidades, a edição gratuita era perfeitamente suficiente e permitia-me trabalhar mais confortavelmente no meu próprio ambiente. Efectuei o &lt;span style="font-style: italic;"&gt;download&lt;/span&gt;, mas após alguns dias parei para pensar sobre um detalhe: A versão actualmente disponível da edição gratuita era a 10g (lançada há 4 ou 5 anos). Repare-se... esta versão já nem é totalmente suportada (sem custos adicionais). Por isso decidi procurar a versão mais recente. Adivinhe...? Não está disponível. Alguma investigação mostrou-me que a nova versão  &lt;a href="http://forums.oracle.com/forums/ann.jspa?annID=1564"&gt;foi disponibilizada em Abril deste ano, mas apenas em "beta"&lt;/a&gt;.  Agora... O que diabo é uma versão "beta" de uma edição livre?! Ao fim ao cabo o produto deverá ser o mesmo. Apenas com algumas restrições.&lt;br /&gt;Se compararmos isto com a politica da IBM para o Informix, reparamos que a edição gratuita, está a par com os último fixpack disponibilizado. Nota aqui uma diferença de comportamento? Eu noto e julgo que não é por trabalhar na IBM...&lt;br /&gt;&lt;br /&gt;Numa perspectiva mais subjectiva, sobre o mercado local, vemos que não temos perdido clientes. Mais importante, os clientes continuam contentes com o Informix pelas razões bem conhecidas (fiabilidade, simplicidade, robustez e facilidade de gestão). Isto não é &lt;span style="font-style: italic;"&gt;marketing&lt;/span&gt;. É-me um pouco difícil indicar um verdadeiro e "puro" DBA Informix, e conheço as maiores e mais criticas instalações de Informix no meu País. Temos Informix em grandes cadeias de lojas, nas telecomunicações, em logística e transportes, na área financeira, na administração central e local e na área industrial. E em todos estes sitios mal se apercebem que correm Informix. Isto é um grande feito, mas ao mesmo tempo é um grande problema. Apesar de isto ser um paradoxo, acredito verdadeiramente que um software que cause ou esteja envolvido em problemas tem mais facilidade em ter sucesso. Porquê? Porque faz com que as pessoas que trabalhem com ele se tornem mais "visíveis" quando resolvem problemas. A título de exemplo, em 2010 fui extraordinariamente elogiado pelo envolvimento numa situação complicada (originada por uma sequência de erros humanos). O assunto foi escalado ao mais alto nível e após resolvido surgiram os elogios e os ecos percorreram a cadeia hierarquica. Ora numa situação normal, nada de errado teria acontecido e eu continuaria anónimo para a hierarquia.&lt;br /&gt;Quem gere Informix tende a efectuar uma série de outras tarefas. E tendem a ser "invisíveis". Isto não é justo, pois naturalmente significa que estão a fazer o seu trabalho correctamente, mas já o tenho presenciado inúmeras vezes. Como diz o ditado: "que falem mal, mas que falem"...&lt;br /&gt;&lt;br /&gt;Vejamos agora o que mudou (não as novas funcionalidades) desde a aquisição:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;O Informix ganhou presença nos eventos globais da IBM (como o Information on Demand)&lt;/li&gt;&lt;li&gt;Temos &lt;span style="font-style: italic;"&gt;webcasts&lt;/span&gt; mensais (&lt;span style="font-style: italic;"&gt;chat with the labs&lt;/span&gt;)&lt;/li&gt;&lt;li&gt;Temos PIDs (&lt;span style="font-style: italic;"&gt;Post Interim Drops&lt;/span&gt;) que são &lt;span style="font-style: italic;"&gt;patches&lt;/span&gt; cumulativos. Isto significa que raramente peço um &lt;span style="font-style: italic;"&gt;patch&lt;/span&gt; específico pois na maioria dos casos já existe um PID com a correcção necessária já disponível&lt;/li&gt;&lt;li&gt;Temos tido novas versões (&lt;span style="font-style: italic;"&gt;major releases&lt;/span&gt;) cada 1-2 anos (2001,2003,2005,2007,2008,2010). E temos tido &lt;span style="font-style: italic;"&gt;fixpacks&lt;/span&gt; cada 3-4 meses, que inclúem novas funcionalidades e não apenas correcções&lt;/li&gt;&lt;li&gt;Temos o &lt;span style="font-style: italic;"&gt;InfoCenter&lt;/span&gt; com a documentação mais actualizada e uma interface que permite a procura fácil de termos&lt;/li&gt;&lt;li&gt;Continuamos a ter a documentação em PDF para quem já conhece a sua estrutura e prefere tê-la disponível no computador (ou dispositivo móvel)&lt;/li&gt;&lt;li&gt;Temos melhor integração com o &lt;span style="font-style: italic;"&gt;portfolio&lt;/span&gt; de produtos IBM&lt;/li&gt;&lt;li&gt;O Informix é usado como repositório em alguns dos outros produtos IBM (Cognos Express e Optim como opção, ...)&lt;/li&gt;&lt;li&gt;Algumas novas funcionalidades vieram directamente de outros produtos (DB2 por exemplo). Isto traduz-se em novas melhorias com pouco esforço de engenharia&lt;/li&gt;&lt;li&gt;Temos um leque maior de edições, incluindo uma gratuita&lt;/li&gt;&lt;li&gt;Continuamos inovadores, como as recentes histórias de sucesso com o TimeSeries mostram. Existem novos requisitos e somos capazes de os preencher&lt;/li&gt;&lt;li&gt;Informix é uma marca dentro do pilar de &lt;span style="font-style: italic;"&gt;Information Management&lt;/span&gt; da IBM. Recorde-se que de início foi incluído no pilar chamado "DB2". O Informix está actualmente a par do DB2, Cognos, Guardium etc.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;... E o que não mudou:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Informix ainda é leve, fácil de instalar e gerir&lt;/li&gt;&lt;li&gt;Informix ainda é robusto&lt;/li&gt;&lt;li&gt;Informix ainda é escalável&lt;/li&gt;&lt;li&gt;O suporte Informix ainda é bom (sou suspeito, mas falo muito com clientes que têm de lidar com o suporte de outros vendedores...)&lt;/li&gt;&lt;li&gt;Os clientes ainda gostam do Informix&lt;/li&gt;&lt;li&gt;As pessoas ainda se queixam do &lt;span style="font-style: italic;"&gt;marketing&lt;/span&gt; em torno do Informix&lt;/li&gt;&lt;li&gt;Continuamos sem ver o Informix nas notícias com frequência&lt;/li&gt;&lt;li&gt;O &lt;a href="http://www.iiug.org/"&gt;IIUG&lt;/a&gt; continua a sem um bem precioso para a comunidade Informix&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Acredito que muitas pessoas ao lerem isto, e conhecendo a história do Informix possam considerar que apenas foquei o lado positivo e que existe um lado negro. Pontos que não foram alcançados ou coisas que correm pior desde a aquisição. Mas convém não esquecer que não é totalmente justo comparar o pós aquisição com o pré-aquisição (especialmente durante os "anos dourados"). Uma comparação para ser justa teria de ser feita entre o que se tem passado dentro da IBM com o que se passaria fora da IBM se não tivesse havido a aquisição. Mas isto é pura especulação. Naturalmente todos os apoiantes do Informix pensam que deveria ter mais visibilidade dentro da IBM (ideia recorrente que se percebe nos forums e em &lt;span style="font-style: italic;"&gt;blogs&lt;/span&gt; e &lt;span style="font-style: italic;"&gt;sites&lt;/span&gt; externos à IBM), ou que precisamos de mais/melhor &lt;span style="font-style: italic;"&gt;marketing&lt;/span&gt;. Mas na minha perspectiva o balanço tem sido positivo. E fico expectante pelo 20º aniversário da aquisição. Vamos ver o que acontece nos próximos 10 anos. Há 10 anos atrás penso que muita gente não acreditaria na evolução que o Informix sofreu.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-4094195399584037925?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/4094195399584037925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=4094195399584037925' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/4094195399584037925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/4094195399584037925'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/08/10-years-of-ibm-10-anos-de-ibm.html' title='10 years of IBM / 10 anos de IBM'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-4355794163714272467</id><published>2011-06-30T22:53:00.003+01:00</published><updated>2011-06-30T23:26:29.593+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='11.70.TC3'/><category scheme='http://www.blogger.com/atom/ns#' term='dbaccess'/><category scheme='http://www.blogger.com/atom/ns#' term='11.70.fc3'/><category scheme='http://www.blogger.com/atom/ns#' term='#informix'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='fixpack'/><category scheme='http://www.blogger.com/atom/ns#' term='11.70.xc3'/><category scheme='http://www.blogger.com/atom/ns#' term='11.70.uc3'/><category scheme='http://www.blogger.com/atom/ns#' term='client sdk'/><title type='text'>11.70.xC3 is available / 11.70.xC3 está disponível</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;English version:&lt;br /&gt;&lt;br /&gt;My articles backlog keeps increasing, but there are things I can't miss. One of them is the availability of another fixpack of Informix.&lt;br /&gt;The latest one is 11.70.xC3. I spot it on &lt;a href="http://www.ibm.com/support/fixcentral"&gt;FixCentral&lt;/a&gt; a couple of days ago and &lt;a href="https://www.ibm.com/support/docview.wss?uid=swg27019520&amp;amp;wv=1"&gt;PDF documentation&lt;/a&gt; is already available. &lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/index.jsp"&gt;InfoCenter&lt;/a&gt; is also updated.&lt;br /&gt;&lt;br /&gt;As usual there are big news and smaller ones. It really depends on your needs and cares. The follwoing is a straight copy/paste from its release notes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Administration&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Automatic read-ahead operations&lt;/li&gt;    &lt;li&gt;Configuring the server response to low memory&lt;/li&gt;    &lt;li&gt;Reserving memory for critical activities&lt;/li&gt;    &lt;li&gt;Connection Manager enhancements&lt;/li&gt;    &lt;li&gt;Enhancements to the OpenAdmin Tool&lt;/li&gt;  &lt;/ul&gt;&lt;li&gt; Embeddability&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Managing message logs in embedded and enterprise environments&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Developing&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Built-in SQL compatibility functions for string manipulation and trigonometric support&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;High availability clusters and Enterprise Replication&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Automatically connecting to a grid&lt;/li&gt;&lt;li&gt;Code set conversion for Enterprise Replication&lt;/li&gt;&lt;li&gt;Enhancements to the Informix Replication plug-in for OAT&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Security&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Non-root installations support shared-memory and stream-pipe connections&lt;/li&gt;&lt;li&gt;Retaining numbers for audit log files&lt;/li&gt;&lt;li&gt;Restrict operating system properties for mapped users&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Time Series data&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Simplified handling of time series data&lt;/li&gt;&lt;li&gt;Informix TimeSeries plug-in for OAT&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;A few remarks:&lt;br /&gt;&lt;br /&gt;The possibility of configuring read ahead automatically is great. Let's be honest: How many of us ever really mastered the traditional configuration? Personally I can tell you that a few years ago I tried it in a very controlled environment and I gave up. I could not spot any difference in my tests and over the years I've seen contradictory statements on how it should be setup. So it's a great pleasure to see it can be automatic now.&lt;br /&gt;&lt;br /&gt;Server response in a low memory situation is also a great new feature. In cases where I have more than one instance on the same server I insist on setting up SHMTOTAL so that I can isolate any issue caused by excessive memory consumption. This prevents the situation from affecting other instances.&lt;br /&gt;But even so it was usual to see undesirable behaviors on the instance consuming too much memory. And this is easy to understand, because to fix something (rollback, monitor etc.) you still need memory. If you've run out of it, your ability to solve it is constrained.&lt;br /&gt;What IBM did now is give you the ability to reserve some memory, to deal with lack of memory. Seems pretty obvious right? But IBM did more. When you hit the pre-configured thresholds the engine can automatically run some tasks that will allow it to free some memory. So, again, more automation, easier to use in embedded scenarios and more robustness&lt;br /&gt;&lt;br /&gt;Connection manager suffered some big changes. Sincerely I need more time to figure them out, but the idea is that a unique connection manager can be used to deal with different needs (high availability, grid, server sets and ER. The configuration file has changed.&lt;br /&gt;As usual, OAT has been changed to accommodate the server side improvements. Several new options are available to deal with log file rotation, low memory conditions setup, lock monitoring (inspired on a plugin initially created by me which is available on the &lt;a href="http://www.iiug.org/"&gt;IIUG&lt;/a&gt; software repository) and a new plugin to handle TimeSeries.&lt;br /&gt;&lt;br /&gt;Several new SQL functions were introduced. This is something that could be solved (most of them could be easily created), but that hurt the new users experience and portability efforts. I would like to see much more in this area...&lt;br /&gt;One interesting new feature is the possibility to configure ER between servers with different codesets. This opens some interesting possibilities for example if you need to convert the codeset of a large database.&lt;br /&gt;&lt;br /&gt;Timeseries was also improved, revealing it's one very important aspect of the latests releases.&lt;br /&gt;Finally several security related changes, like improvements for servers in "non-root" installations and for instances configured with mapped users.&lt;br /&gt;&lt;br /&gt;I usually concentrate only on the server side improvements, but this time I want to mention a trivial, but long desired change in Client SDK: It now includes dbaccess, the simple but very handy tool. Of course people would like to see a fancy GUI tool on Windows (or even other environments using Java), but that would be much harder, and would certainly increase the footprint.&lt;br /&gt;This is a quick solution for a long lasting problem: the client did not include any query tool. I would vote for the inclusion of other traditional "server side" tools like dbschema and dbload.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Versão Portuguesa&lt;br /&gt;&lt;br /&gt;O meu atraso na escrita de artigos continua a aumentar, mas há algumas coisas que não posso deixar passar. Uma delas é a disponibilidade de outro fixpack Informix.&lt;br /&gt;O último é o 11.70.xC3. Encontrei-o há dois dias no site &lt;a href="http://www.ibm.com/support/fixcentral"&gt;FixCentral&lt;/a&gt; e a &lt;a href="https://www-304.ibm.com/support/docview.wss?uid=swg27019520&amp;amp;wv=1"&gt;documentação em PDF&lt;/a&gt; já está disponível. O &lt;a href="http://publib.boulder.ibm.com/infocenter/idshelp/v117/index.jsp"&gt;InfoCenter&lt;/a&gt; também já está actualizado&lt;br /&gt;&lt;br /&gt;Como de costume há grandes novidades e pequenas novidades. Tudo depende das necessidades e preocupações de cada um. O seguinte é a tradução tão fiel quanto possível das novidades especificadas nas notas deste fixpack:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Administração&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Operações automáticas de read-ahead&lt;/li&gt;&lt;li&gt;Configuração da reacção do servidor a situações de escassez de memória&lt;/li&gt;&lt;li&gt;Reservar memória para actividades criticas&lt;/li&gt;&lt;li&gt;Melhorias no Connection Manager&lt;/li&gt;&lt;li&gt;Melhorias no OpenAdmin Tool&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Funcionalidades de inclusão da base de dados em ambientes fechados&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Gestão de logs de mensagens em ambientes embebidos e empresariais&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Desenvolvimento&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Funções SQL de compatibilidade e manipulação de strings e suporte trigonométrico&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Clusters de alta disponibilidade e Enterprise Replication&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Conexão automática a uma grid&lt;/li&gt;&lt;li&gt;Conversão de mapas de caracteres para Enterprise Replication&lt;/li&gt;&lt;li&gt;Melhorias no plugin de replicação Informix para o OAT&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Segurança&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Instalações Non-root suportam conexões shared-memory e stream-pipe&lt;/li&gt;&lt;li&gt;Retenção de números para os logs de audit&lt;/li&gt;&lt;li&gt;Restrição de propriedades de sistema operativo para utilzadores mapeados&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Dados Time Series&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Gestão simplificada de dados Time Series&lt;/li&gt;&lt;li&gt;Plugin do OAT para Informix TimeSeries&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/ul&gt;Alguns comentários:&lt;br /&gt;&lt;br /&gt;A possibilidade de configurar o &lt;span style="font-style: italic;"&gt;read ahead&lt;/span&gt; automaticamente parece-me óptima! Sejamos honestos: Quantos de nós conseguiram realmente dominar a configuração tradicional? Pessoalmente posso dizer que há alguns anos atrás tentei num ambiente bastante controlado e desisti. Não consegui identificar diferenças sensíveis nos meus testes, e ao longo dos anos vi indicações contraditórias sobre como isto deveria ser configurado. Por isso é com muita satisfação que vejo que agora pode ser automatizado.&lt;br /&gt;&lt;br /&gt;Poder configurar a reacção do servidor em situações de escassez de memória é outra excelente melhoria. Em ambientes onde tenha mais que uma instância por servidor, eu insisto em definir o SHMTOTAL, para que possa isolar qualquer problema causado por excesso de consumo de memória. Isto previne que a situação afecte as outras instâncias (ou no limite a própria máquina). Mas mesmo assim era habitual vermos comportamentos não desejados numa instância que consumisse muita memória. E isto é fácil de entender, porque para corrigir alguma coisa (efectuar um rollback, monitorizar etc.) é necessária memória. Se já a esgotámos, a capacidade de resolver o problema é afectada.&lt;br /&gt;O que a IBM fez agora foi dar-nos a capacidade de reservar alguma memória para lidar com a falta de memória. Parece bastante óbvio, certo? Mas a IBM fez mais. Quando atingimos os limites pré-configurados, o motor pode automaticamente executar algumas tarefas que lhe permitirão libertar memória. Portanto, mais uma vez, mais automatização o que torna mais fácil usar o Informix em ambientes embebidos e aumenta a robustez.&lt;br /&gt;&lt;br /&gt;O Connection Manager sofreu grandes alterações. Sinceramente necessito de mais tempo para as analisar, mas a ideia é que um único &lt;span style="font-style: italic;"&gt;connection manager&lt;/span&gt; pode ser usado para lidar com diferentes necessidades (alta disponibilidade, grid, server sets, e Enterprise Replication). O formato do ficheiro de configuração foi alterado.&lt;br /&gt;&lt;br /&gt;Como vem sendo habitual, o Open Admin Tool (OAT) foi alterado para acomodar as melhorias introduzidas no servidor. Novas opções estão disponíveis para lidar com rotação de ficheiros de log, configuração de condições de escassez de memória, monitorização de locks (inspirado num plugin inicialmente criado por mim e disponível no repositório do &lt;a href="http://www.iiug.org"&gt;IIUG&lt;/a&gt;) e um novo plugin para lidar com TimeSeries.&lt;br /&gt;&lt;br /&gt;Várias novas funções SQL foram introduzidas. Isto é algo que poderia ser resolvido pelo utilizador (a maioria destas podia ser facilmente criada), mas isso dificultava a vida a novos utilizadores e tinha impacto na portabilidade de aplicações. Gostaria de ver muito mais evolução neste aspecto...&lt;br /&gt;&lt;br /&gt;Uma funcionalidade interessante é a possibilidade de configurar Enterprise Replication (ER) entre bases de dados que utilizem diferentes mapas de caracteres.&lt;br /&gt;Isto abre possibilidades interessanes se por exemplo necessitar-mos de converter um mapa de caracteres de uma base de dados grande.&lt;br /&gt;&lt;br /&gt;O TimeSeries também foi melhorado, revelando que é um dos aspectos mais importantes das últimas versões.&lt;br /&gt;Finalmente, algumas mudanças na área de segurança, como melhorias em servidores instalados como "non-root" e para instâncias configuradas com utilizadores mapeados.&lt;br /&gt;&lt;br /&gt;Habitualmente concentro-me apenas nas melhorias do lado do servidor, mas desta vez tenho de mencionar um mudança trivial, mas há muito desejada no Client SDK: Passou a incluir o dbaccess, a ferramenta simples, mas muito útil de interrogação da base de dados. Claro que todos gostaríamos de ver uma ferramenta gráfica nos ambientes Windows (ou mesmo em todos os ambientes, baseado em Java por exemplo), mas a verdade é que isso necessitaria de um esforço muito maior e iria aumentar significativamente a dimensão do cliente.&lt;br /&gt;Isto é uma solução rápida para um problema que existia há muito tempo: o cliente não incluía nenhuma ferramenta de interrogação da base de dados. Eu votaria a favor da inclusão de outras ferramentas "tradicionais" do servidor como o dbschema e dbload.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-4355794163714272467?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/4355794163714272467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=4355794163714272467' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/4355794163714272467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/4355794163714272467'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/06/1170xc3-is-available-1170xc3-esta.html' title='11.70.xC3 is available / 11.70.xC3 está disponível'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-79082948762842685</id><published>2011-06-04T13:39:00.000+01:00</published><updated>2011-06-04T15:57:19.242+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='hp'/><category scheme='http://www.blogger.com/atom/ns#' term='itanium'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>HP-UX: What now? / E agora?</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;English version:&lt;br /&gt;&lt;br /&gt;You know I usually stick to  Informix related topics, but a few weeks ago something was announced that has to make us think... As we all know by now, Oracle &lt;a href="http://www.oracle.com/us/corporate/press/346696"&gt;announced&lt;/a&gt; that future versions of their software products will not support HP-UX running on Intel Itanium chips.&lt;br /&gt;Why do we have to think about it? Well, from my personal perspective because it raises a lot of serious doubts/questions. Let's see:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;First you read in the announcement that Intel is not truly committed to Itanium. The exact words are "Intel management made it clear that their strategic focus is on their  x86 microprocessor and that Itanium was nearing the end of its life". Intel denied this in the following days. Who do we believe? The company that owns the chip in question or another (now also) hardware supplier? Is it normal that a company discontinues it's products on a platform that has not announced it's end of life plans?&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The announcement was made just before an important HP shareholders meeting... We could of course believe this was just a coincidence&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;In the last months a lot of news came up referring to personal wars between Oracle's and HP's executives (ex HP CEO is now a very important Oracle executive). Meanwhile ex SAP CEO has been appointed as HP CEO, and Oracle and SAP had an ongoing court trial started at the time he was SAP's CEO. All these an point 2) may lead us to the feeling that while personalities clash, customers suffer. There's nothing wrong with having strong personalities as leaders of large companies, on the contrary. But we would expect their egos not to cause harm to their customers (of course "harm" translates into costs, uncertainty,  fear and doubts - typically FUD that competitors like to spread, but in this case competitors don't have to bother...)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Oracle mentions that others (Microsoft and Red Hat) have previously discontinued support for Itanium. This is true, but there is a big difference: The market share that these two companies had in the Itanium market was considered irrelevant. Now, for Oracle, the situation is completely different. They have a large share of Itanium customers (accordingly to &lt;a href="http://h30507.www3.hp.com/t5/Mission-Critical-Computing-Blog/FAQs-from-HP-on-the-Oracle-Itanium-Announcement/ba-p/89977"&gt;this blog&lt;/a&gt;, there are around 140.000 Oracle/Itanium customers)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Some &lt;a href="http://www.channelregister.co.uk/2011/03/28/oracle_itanium_gambit/page2.html"&gt;people argue&lt;/a&gt; that supporting a platform has it's costs. Of course this is true, but the costs are certainly well covered if the above number holds true. That's part of the business. In order to provide a product, you incur in certain costs. And also note that Oracle always said, wrote an publicized that their code base was the same independently of the platform. So using this as an argument is hardly acceptable...&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Many people think this is just a commercial move from Oracle. They're trying to weak a competitor position while at the same time they hope to raise their own hardware sales. We can accept that this is normal, but we should keep in mind a few things. First, just a while ago Oracle choose HP as an hardware partner (remember Exadata?). Secondly Oracle CEO has said that it would like to see &lt;a href="http://www.theregister.co.uk/2010/01/29/oracle_sun_exadata_ibm/"&gt;Oracle becoming the IBM of the sixties (integrated stack where the margins would be bigger), but that it would keep its software running on competitor platforms&lt;/a&gt;. Well something has changed :)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Will this be the only case, or will Oracle do the same in the future with other OS? The fact is that the number of OS and Hardware vendors for enterprise computing is shrinking. You currently have Microsof Windows on Intel x86, IBM AIX on System p, HP-UX on Itanium, Solaris Sparc, Linux on Intel x86, and Solaris on Intel (I'm explicitley forgeting other platforms like IBM System Z and  HP NonStop). Oracle is doing it's best to eliminate HP-UX/Itanium. Will it stop there? Or will it proceed it's path to become "the IBM of the 1960s" (meaning the closed system that locked customers in)? Note that IBM still suffers with the image it created at the time.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;The above are just a list of some important points. I may be missing a few. The announcement must had a significant impact on HP Itanium customers running Oracle software. Imagine that you wake up one morning and find out that the software vendor you choose gave up supporting your platform. Of course you'll have support for your existing products, but you'd really appreciate a roadmap... By the way, wasn't that the same company that 10 years ago accused IBM of not having a roadmap for Informix? It's funny when we put things into perspective...&lt;br /&gt;So, assuming you're one of those customers what will you do? You have a few options:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You jump on the Oracle train and buy a one way ticket... I mean you choose Sparc for your upcoming hardware renovation... You don't know where the train will take you... You don't even know how much it will cost you... Specially because you just bought a one way ticket... Once you're "there" you'll figure what what price the next ride will cost... One thing you know: You'll be traveling with the same company since no other operates in the same region...&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You choose another hardware platform, and you really hope the same trick will not be played again&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You change your software supplier&lt;/li&gt;&lt;/ol&gt;I'd say none of the options above looks particularly attractive. But in case you need another database (and you're able to get your application running against it), you should really consider Informix. Here's why:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;It's robust, easy to use, reliable, works well in virtualized environments etc., but you should already know that&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It has a roadmap and has just completed a decade of improvements after the IBM acquisition&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It belongs to a company that will try to sell you it's hardware, because it believes it's good, and not because it tends to be the only option to run it's software&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It's already very well integrated with many of the other IBM software portfolio, and this is assumed to be a continuous effort&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It has a long history of working well with HP-UX (traditionally on PA-RISC and now with Itanium). A search for "informix" in the HP site will show you several HP documents about integration between Informix and HP-UX&lt;/li&gt;&lt;/ol&gt;To wrap up this article, I'd like to put here a few links that relate to this topic. I hope they'll allow you to see what's being written about this Oracle announcement, and to form your own opinion about it.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The original Oracle announcement&lt;br /&gt;&lt;a href="http://www.oracle.com/us/corporate/press/346696"&gt;http://www.oracle.com/us/corporate/press/346696&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The Register article about the announcement&lt;br /&gt;&lt;a href="http://www.theregister.co.uk/2011/03/23/oracle_stops_itanium_development/"&gt;http://www.theregister.co.uk/2011/03/23/oracle_stops_itanium_development/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;The Register article covering HP and Intel answer to the announcement&lt;br /&gt;&lt;a href="http://www.theregister.co.uk/2011/03/24/intel_hp_itanium_defense/"&gt;http://www.theregister.co.uk/2011/03/24/intel_hp_itanium_defense/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;The Register article overview of the users thoughts about the announcement&lt;br /&gt;&lt;a href="http://www.theregister.co.uk/2011/04/26/gabriel_oracle_itanium_survey/"&gt;http://www.theregister.co.uk/2011/04/26/gabriel_oracle_itanium_survey/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Gabriel Consulting survey referenced in the previous link&lt;br /&gt;&lt;a href="http://www.gabrielconsultinggroup.com/recent-research/doc_download/42-oracle-survey-whats-the-real-reason-oracle-dropped-itanium.html"&gt;http://www.gabrielconsultinggroup.com/recent-research/doc_download/42-oracle-survey-whats-the-real-reason-oracle-dropped-itanium.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;HP echoes some users comments&lt;a href="http://www.hp.com/hpinfo/newsroom/press/2011/110414xa.html?jumpid=reg_R1002_USEN"&gt;&lt;br /&gt;http://www.hp.com/hpinfo/newsroom/press/2011/110414xa.html?jumpid=reg_R1002_USEN&lt;/a&gt;&lt;/li&gt;&lt;li&gt;HP site dedicated to this issue&lt;br /&gt;&lt;a href="http://h18004.www1.hp.com/products/solutions/customers_first.html"&gt;http://h18004.www1.hp.com/products/solutions/customers_first.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;HP blog from an executive containing a FAQ&lt;br /&gt;&lt;a href="http://h30507.www3.hp.com/t5/Mission-Critical-Computing-Blog/FAQs-from-HP-on-the-Oracle-Itanium-Announcement/ba-p/89977"&gt;http://h30507.www3.hp.com/t5/Mission-Critical-Computing-Blog/FAQs-from-HP-on-the-Oracle-Itanium-Announcement/ba-p/89977&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Versão Portuguesa:&lt;br /&gt;&lt;br /&gt;Normalmente restrinjo-me a assuntos exclusivamente relacionados com Informix, mas há algumas semanas atrás foi anunciado algo que nos tem de fazer pensar.... Como já todos deveremos saber nesta altura, a Oracle&lt;a href="http://www.oracle.com/us/corporate/press/346696"&gt; anunciou&lt;/a&gt; que futuras versões do seu software não irão suportar HP-UX a correr em chips Itanium.&lt;br /&gt;Porque é que devemos reflectir sobre isto? Bom, na minha opinião pessoal porque isto levanta uma série de dúvidas e questões importantes. Vejamos:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Começamos por ler no anúncio que a Intel não está verdadeiramente empenhada no Itanium. As palavras exactas (tradução pessoal) foram: "... a gestão da Intel deixou claro que o foco da sua estratégia é a linha de processadores x86 e que o Itanium se está a aproximar do fim de vida..." . A Intel negou isto nos dias seguintes. Em quem acreditamos? Na empresa que detém o processador em questão ou noutra empresa (agora também) fornecedora de &lt;span style="font-style: italic;"&gt;hardware&lt;/span&gt;? Será normal que uma empresa anuncie o fim de desenvolvimento dos seus produtos numa plataforma cujo fim de vida não foi sequer anunciado?&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;O anúncio foi feito imediatamente antes de um encontro de accionistas da HP.... Podemos claro acreditar que isto foi apenas uma coincidência&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Nos últimos meses vieram a público uma série de notícias referentes a guerras pessoais entre executivos da HP e Oracle (o ex CEO da HP é agora um quadro importante na Oracle - o número dois na verdade, logo abaixo do Larry Ellison). Entretanto o ex CEO da SAP foi nomeado CEO da HP, e a Oracle e HP tinham um processo em tribunal que remonta ao tempo em que o mesmo era CEO da SAP. Tudo isto e o ponto 2) podem levar-nos a pensar que enquanto as personalidades se chocam os clientes sofrem. Não há nada de errado em que grandes empresas tenham personalidades fortes na sua liderança, bem pelo contrário. Mas seria de esperar que os egos não prejudiquem os respectivos clientes. O "prejuízo" traduz-se em custos, incerteza, medos e dúvidas - o que em Inglês se chama "FUD - fear, uncertainty and doubt -", que normalmente é espalhado pela concorrência, mas que neste caso nem requer esforço da concorrência pois é feiro pelos próprios.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A Oracle referiu que outros (Microsoft e Red Hat) já tinham previamente descontinuado o suporte para Itanium. Isto é verdade, mas há uma enorme diferença: A quota de mercado que estas duas empresas tinham em Itanium não é comparável à da Oracle. Esta tem uma grande percentagem dos clientes Itanium a usarem os seus produtos (de acordo com &lt;a href="http://h30507.www3.hp.com/t5/Mission-Critical-Computing-Blog/FAQs-from-HP-on-the-Oracle-Itanium-Announcement/ba-p/89977"&gt;este blog&lt;/a&gt;, existem cerca de 140.000 clientes Oracle/Itanium)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.channelregister.co.uk/2011/03/28/oracle_itanium_gambit/page2.html"&gt;Algumas pessoas defendem&lt;/a&gt; que suportar uma plataforma tem os seus custos. Isto é uma verdade óbvia., mas esses custos são largamente cobertos  se os números acima forem correctos. Isso faz parte do negócio. Para fornecer um produto as empresas (de qualquer tipo) incorrem em custos. Note-se ainda que a Oracle sempre disse, escreveu e publicitou que o seu código era o mesmo independente da plataforma. Por tudo isto, o argumento do custo de suportar uma plataforma não me parece aceiável...&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Muitas pessoas acreditam que isto é apenas uma manobra comercial da Oracle. Estão a tentar enfraquecer um concorrente ao mesmo tempo que tentam aumentar as suas p´roprias vendas de &lt;span style="font-style: italic;"&gt;hardware&lt;/span&gt;. Podemos encarar isto como algo relativamente normal, mas devemos manter em mente uma série de factos. Primeiro, apenas há algum tempo atrás, a Oracle escolheu a HP como o seu parceiro de &lt;span style="font-style: italic;"&gt;hardware&lt;/span&gt; (lembram-se do Exadata?). Segundo, o CEO da oracle disse que gostava de ver (tradução pessoal) &lt;a href="http://www.theregister.co.uk/2010/01/29/oracle_sun_exadata_ibm/"&gt;A Oracle tornar-se a IBM dos anos sessenta (soluções integradas onde as margens são maiores), mas que manteria o seu software a correr nas plataformas da  concorrência&lt;/a&gt;. Parece que algo mudou entretanto... :)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Será este um caso único, ou irá a Oracle fazer os mesmo com outras plataformas? A verdade é que as plataformas (SO e &lt;span style="font-style: italic;"&gt;hardware&lt;/span&gt;) para computação empresarial estão a diminuir. Actualmente temos Microsof Windows em Intel x86, IBM AIX em System p, HP-UX em Itanium, Solaris Sparc, Linux em Intel x86, e Solaris em Intel (estou a omitir outras plataformas como IBM System Z e HP NonStop) . A Oracle está a fazer o seu melhor para eliminar HP-UX em Itanium. Irá parar por aí? Ou irá prosseguir os seu caminho para se tornar a "IBM dos anos sessenta" (neste caso um sistema fechado que prende os clientes)? Note-se que a IBM ainda sofre com a imagem criada nessa altura.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Acima está uma lista de alguns pontos importantes. Posso ter esquecido alguns. O anúncio deve ter tido um impacto significativo nos clientes HP Itanium que utilizam &lt;span style="font-style: italic;"&gt;software&lt;/span&gt; Oracle. Imagine que acorda uma manhã e descobre que o fornecedor de &lt;span style="font-style: italic;"&gt;software&lt;/span&gt; que seleccionou, deixou de suportar a sua plataforma. Claro que terá suporte para os produtos que já existem, mas certamente apreciaria a existência de um &lt;span style="font-style: italic;"&gt;roadmap&lt;/span&gt;... Aliás, não foi esta a mesma empresa que há 10 anos atrás acusou a IBM de não ter um &lt;span style="font-style: italic;"&gt;roadmap&lt;/span&gt; para Informix? É engraçado quando se colocam as coisas em perspectiva...&lt;br /&gt;Assim, assumindo que é um desses clientes, o que irá fazer? A meu ver tem algumas opções:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Apanha o compboio da Oracle e compra um bilhete de ida... Ou seja, escolhe SPARC para a sua próxima renovação de &lt;span style="font-style: italic;"&gt;hardware&lt;/span&gt;... Não  sabe para onde o comboio o leva... Nem sequer sabe quanto lhe vai custar... Especialmente porque comprará apenas um bilhete de ida... Depois de "lá" chegar logo verá qual o preço da próxima "viagem"... Uma coisa será certa: Irá viajar com a mesma empresa, pois mais ninguém opera na mesma "região"...&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Escolhe outra plataforma de &lt;span style="font-style: italic;"&gt;hardware&lt;/span&gt; e espera ardentemente que o mesmo truque não seja empregue novamente&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Muda de fornecedore de &lt;span style="font-style: italic;"&gt;softtware&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;Diria que nenhuma das opções acima parece particularmente atractiva. Mas caso necessite de uma nova base de dados (e possa colocar a sua aplicação a correr nela), deveria considerar o Informix. Eis porquê:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;É robusto, confiável, corre bem em ambientes virtualizadoes etc.., mas isto já deverá saber&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Tem um &lt;span style="font-style: italic;"&gt;roadmap&lt;/span&gt; e acabou de completar 10 anos de inovação após a aquisição pela IBMI&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Pertence a uma empresa que tentará vender-lhe o seu &lt;span style="font-style: italic;"&gt;hardware&lt;/span&gt; porque acredita que é bom, e não apenas porque tende a ser a única plataforma onde pode correr o seu &lt;span style="font-style: italic;"&gt;hardware&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Já está bastante bem integrado com muito do &lt;span style="font-style: italic;"&gt;software&lt;/span&gt; IBM, e isto é assumidamente um esforço contínuo&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Tem uma longa história de bom desempenho em HP-UX (tradicionalmente em PA-RISC e actualmente em Itanium). Uma pesquisa por "informix" no &lt;span style="font-style: italic;"&gt;site&lt;/span&gt; da HP irá mostrar-lhe vários documentos da HP sobre a integração entre Informix e HP-UX&lt;/li&gt;&lt;/ol&gt;Para fechar este artigo, gostaria de deixar alguns &lt;span style="font-style: italic;"&gt;links&lt;/span&gt; relacionados com este assunto.  Espero que lhe permitam ver o que tem sido escrito sobre este anúncio da Oracle, e que possa formar a sua p´ropria opinião sobre o tema.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;O anúncio original&lt;br /&gt;&lt;a href="http://www.oracle.com/us/corporate/press/346696"&gt;http://www.oracle.com/us/corporate/press/346696&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Um artigo no "The Register" sobre o anúncio&lt;br /&gt;&lt;a href="http://www.theregister.co.uk/2011/03/23/oracle_stops_itanium_development/"&gt;http://www.theregister.co.uk/2011/03/23/oracle_stops_itanium_development/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Um artigo no "The Register" cobrindo as respostas da HP e Intel&lt;br /&gt;&lt;a href="http://www.theregister.co.uk/2011/03/24/intel_hp_itanium_defense/"&gt;http://www.theregister.co.uk/2011/03/24/intel_hp_itanium_defense/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Um artigo no "The Register" sobre as opiniões dos utilizadores sobre o anúncio&lt;br /&gt;&lt;a href="http://www.theregister.co.uk/2011/04/26/gabriel_oracle_itanium_survey/"&gt;http://www.theregister.co.uk/2011/04/26/gabriel_oracle_itanium_survey/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Inquérito do "Gabriel Consulting" referenciado no artigo anterior&lt;br /&gt;&lt;a href="http://www.gabrielconsultinggroup.com/recent-research/doc_download/42-oracle-survey-whats-the-real-reason-oracle-dropped-itanium.html"&gt;http://www.gabrielconsultinggroup.com/recent-research/doc_download/42-oracle-survey-whats-the-real-reason-oracle-dropped-itanium.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Alguns ecos sobre o assunto publicados pela HP&lt;a href="http://www.hp.com/hpinfo/newsroom/press/2011/110414xa.html?jumpid=reg_R1002_USEN"&gt;&lt;br /&gt;http://www.hp.com/hpinfo/newsroom/press/2011/110414xa.html?jumpid=reg_R1002_USEN&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Um &lt;span style="font-style: italic;"&gt;site&lt;/span&gt; da HP dedicado ao assunto&lt;br /&gt;&lt;a href="http://h18004.www1.hp.com/products/solutions/customers_first.html"&gt;http://h18004.www1.hp.com/products/solutions/customers_first.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Um blog de um executivo da HP que contém um FAQ sobre o tema&lt;br /&gt;&lt;a href="http://h30507.www3.hp.com/t5/Mission-Critical-Computing-Blog/FAQs-from-HP-on-the-Oracle-Itanium-Announcement/ba-p/89977"&gt;http://h30507.www3.hp.com/t5/Mission-Critical-Computing-Blog/FAQs-from-HP-on-the-Oracle-Itanium-Announcement/ba-p/89977&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-79082948762842685?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/79082948762842685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=79082948762842685' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/79082948762842685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/79082948762842685'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/06/hp-ux-what-now-e-agora.html' title='HP-UX: What now? / E agora?'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-2768541534865365868</id><published>2011-05-17T23:40:00.003+01:00</published><updated>2011-05-17T23:53:32.825+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iwa'/><category scheme='http://www.blogger.com/atom/ns#' term='roadshow'/><category scheme='http://www.blogger.com/atom/ns#' term='Informix Warehouse Accelerator'/><category scheme='http://www.blogger.com/atom/ns#' term='2011'/><category scheme='http://www.blogger.com/atom/ns#' term='lisbon'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='lisboa'/><title type='text'>Informix Roadshow 2011 Lisboa (report)</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-Owd5JQ7uJFY/Tcv7Bf91c0I/AAAAAAAAACw/abfL3Yb7NR0/s1600/InformixRoadshow2011Lisbon.JPG"&gt;&lt;img style="float: left; margin: 0pt 10px 10px 0pt; cursor: pointer; width: 320px; height: 180px;" src="http://4.bp.blogspot.com/-Owd5JQ7uJFY/Tcv7Bf91c0I/AAAAAAAAACw/abfL3Yb7NR0/s320/InformixRoadshow2011Lisbon.JPG" alt="" id="BLOGGER_PHOTO_ID_5605850164372009794" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;English version:&lt;br /&gt;&lt;br /&gt;The Lisbon Informix Roadshow 2011 was a success. We got a full room of customers and partners to learn about the latest news in the Informix world.&lt;br /&gt;We had international speakers (Juan Brogeras - SWG Information Management Sales Director SPGI, Steve Shoaf - WW sales Executive - Informix and solidDB, Jose Manuel Ruiz Gallud - Informix Technical Sales - Southwest IOT and Manuel Jorge Sousa - Vice President 4JS for Iberia)&lt;br /&gt;&lt;br /&gt;Juan started the sessions with an overview of the Informix business, followed by Steve which explained what Informix Warehouse is and what you can do with it. This was one of the hottest topics.&lt;br /&gt;Manuel proceeded with an excellent overview of 4JS and what the new partnership can bring to customers.&lt;br /&gt;After the break Jose gave us the news on 11.7. By obvious reasons this was another session that raised the assistance interest.&lt;br /&gt;We ended up with a client presentation from PTSI. Eduardo Santana explained us how they migrate all their Informix environments to 11.50. We found out how they did it, what they achieved and what they plan to do next to take advantage of the new features.&lt;br /&gt;I wrapped the session with an overview of the information available on the IBM site about Informix, more specifically the ROI tools, the analyst studies, the documentation, the several editions and the redbooks.&lt;br /&gt;After that we had lunch "outside" which given the weather was a very nice idea. Of course during the break and lunch we had plenty of opportunities to interact with customers and partners and it really made my day receiving the positive feedback about the sessions.&lt;br /&gt;&lt;br /&gt;Above you can see Jose Ruiz in action, updating us with all the new benefits of Informix 11.7&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Versão Portuguesa:&lt;br /&gt;&lt;br /&gt;O Informix Roadshow 2011 de Lisboa foi um sucesso. Tivemos uma sala cheia de clientes e parceiros que desejavam obter as últimas novidades sobre o mundo Informix.&lt;br /&gt;&lt;br /&gt;Estre os oradores tivemos alguns com responsabilidades internacionais (Juan Brogeras - SWG Information  Management Sales Director SPGI, Steve Shoaf - WW sales Executive -  Informix and solidDB, Jose Manuel Ruiz Gallud - Informix Technical Sales  - Southwest IOT and Manuel Jorge Sousa - Vice Presidente 4JS para a Iberia)&lt;br /&gt;&lt;br /&gt;Juan iniciou as sessões com um apanhado do negócio Informix, seguido pelo Steve que explicou o que é o Informix Warehous Accelerator e o que podemos fazer com ele. Esta foi uma das sessões que mais atenção suscitou.&lt;br /&gt;O Manuel prosseguiu com uma excelente visão da 4JS e o que esta parceria pode trazer aos clientes.&lt;br /&gt;Depois do intervalo o Jose mostrou-nos as novidades da 11.7. Por razões óbvias esta foi outra sessão que despertou mais interesse na assistência.&lt;br /&gt;Terminámos com uma apresentação de um cliente, a PTSI. O Eduardo Santana explicou-nos como é que migraram todos os seus ambientes para a versão 11.50. Descobrimos como o fizeram, o que alcançaram e o que pensam fazer para tirar proveito das novas funcionalidades.&lt;br /&gt;Eu encerrei a sessão com uma descrição da informação disponível no site da IBM sobre Informix, mais especificamente as ferramentas de cálculo de ROI (&lt;span style="font-style: italic;"&gt;return on investment&lt;/span&gt;), os estudos de analistas, a documentação, as várias edições disponíveis e os redbooks.&lt;br /&gt;Após isso tivemos oportunidade de almoçar "fora", o que dado o bom tempo que se fazia sentir tornou a refeição mais agradável. Naturalmente que durante o intervalo e o almoço tivemos oportunidade de interagir com clientes e parceiros e foi com prazer que recebemos &lt;span style="font-style: italic;"&gt;feedback&lt;/span&gt; positivo sobre as várias sessões.&lt;br /&gt;&lt;br /&gt;Em cima  podem ver o Jose Ruiz em acção, actualizando-nos  com todos os benefícios do Informix 11.7&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-2768541534865365868?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/2768541534865365868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=2768541534865365868' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/2768541534865365868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/2768541534865365868'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/05/informix-roadshow-2011-lisboa-report.html' title='Informix Roadshow 2011 Lisboa (report)'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-Owd5JQ7uJFY/Tcv7Bf91c0I/AAAAAAAAACw/abfL3Yb7NR0/s72-c/InformixRoadshow2011Lisbon.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-8699943274094098784</id><published>2011-05-09T22:30:00.004+01:00</published><updated>2011-05-10T09:16:38.208+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iwa'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='Informix Warehouse Accelerator'/><category scheme='http://www.blogger.com/atom/ns#' term='2011'/><category scheme='http://www.blogger.com/atom/ns#' term='11.7'/><category scheme='http://www.blogger.com/atom/ns#' term='IIUG'/><category scheme='http://www.blogger.com/atom/ns#' term='panther'/><category scheme='http://www.blogger.com/atom/ns#' term='lenexa'/><category scheme='http://www.blogger.com/atom/ns#' term='conferência'/><category scheme='http://www.blogger.com/atom/ns#' term='comunidade informix'/><category scheme='http://www.blogger.com/atom/ns#' term='kansas city'/><title type='text'>IIUG 2011: Last call / Ultima chamada</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;English version:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.iiug.org/conf/2011/iiug/index.php"&gt;2011 International Informix User Group conference&lt;/a&gt; is just around the corner. It will take place in Lenexa, Kansas City between 15 and 18 May. The conference site has all the information you may need. This includes the sessions abstracts, the list of tutorials, hotel and transportation information etc.&lt;br /&gt;&lt;br /&gt;And what a great conference this will be. Remember that we have Informix 11.7, Informix Warehouse Accelerator and the Genero partnership with 4Js.&lt;br /&gt;And then you have all the permanent/usual attractions, like deep technical sessions, keynote speakers, the Sunday tutorials etc. Some of my personal favorites this year would be:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Sunday tutorials (Flexible grid, Fastest Informix DBA, Partitioning, Certification preparation)&lt;/li&gt;&lt;li&gt;Keynote speakers (Jerry Keesee - Director of Informix Database Development, Rob Thomas - Vice President of Business Development, Arvind Krishna - General Manager IBM Information Management) including this year's special with Dr. David Ferrucci the lead researcher and Principal Investigator (PI) for the Watson/Jeopardy! project&lt;br /&gt;These are great opportunities to understand IBM plans and to ask the difficult questions&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Several sessions on specific topics like Informix 11.7, Informix Warehouse Accelerator, Performance and Tunning, integrating Informix with other products&lt;/li&gt;&lt;li&gt;Free certification opportunity&lt;/li&gt;&lt;li&gt;Networking with many people from the Informix community&lt;/li&gt;&lt;li&gt;Evening specials... Great fun to trigger networking&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;As I observed in last year's conference, the IIUG team does everything possible to provide you the best value for money. And they, together with all the people delivering sessions in the conference, really manage to provide great sessions, great tutorials and great entertainment.&lt;br /&gt;&lt;br /&gt;If you never had the opportunity to go to one of the IIUG's conferences you really don't know what you're missing. If you had, you know it's worth it. Unfortunately this year I won't be able to join, but I'm eagerly waiting for feedback from the community and to check the presentation materials. To all the lucky attendees I wish you a great conference, and please blog/email about it!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Versão Portuguesa:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A &lt;a href="http://www.iiug.org/conf/2011/iiug/index.php"&gt;conferência de 2011 do grupo internacional de utilizadores de Informix&lt;/a&gt; está quase a acontecer. Terá lugar em Lenexas, Kansas City entre 15 e 18 de Maio. O &lt;span style="font-style: italic;"&gt;site&lt;/span&gt; da conferência tem toda a informação possível. Isto incluí as sinapses das sessões, a lista de &lt;span style="font-style: italic;"&gt;tutorials&lt;/span&gt;, informação sobre o hotel e transportes etc.&lt;br /&gt;&lt;br /&gt;E tudo indica que esta será uma grande conferência. Lembremo-nos que temos a versão 11.7 do Informix, o Informix Warehouse Accelerator e a parceria Genero com a 4JS.&lt;br /&gt;Para além disso teremos as atracções habituais, como sessões muito técnicas, os oradores especiais, os &lt;span style="font-style: italic;"&gt;tutorials&lt;/span&gt; de domingo etc. Alguns dos meus favoritos detes ano seriam:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Tutorials&lt;/span&gt; de domingo (Flexible grid, Fastest Informix DBA, Partitioning, Preparação para certificação)&lt;/li&gt;&lt;li&gt;Oradores especiais (Jerry Keesee - Director de Informix Database  Development, Rob Thomas - Vice Presidente de desenvolvimento de negócio, Arvind  Krishna - General Manager IBM Information Management) incluindo uma participação especial do Dr. David Ferrucci - &lt;span style="font-style: italic;"&gt;lead researcher and Principal Investigator (PI)&lt;/span&gt; para o projecto Watson/Jeopardy!&lt;br /&gt;São grandes oportunidades para entender os planos da IBM e para colocar as questões difíceis&lt;/li&gt;&lt;li&gt;Várias sessões sobre tópicos específicos como Informix 11.7, Informix  Warehouse Accelerator, &lt;span style="font-style: italic;"&gt;Performance&lt;/span&gt; e optimização, integração de Informix  com outros produtos&lt;/li&gt;&lt;li&gt;Oportunidade para obter a certificação gratuitamente&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Convivio com imensas pessoas da comunidade Informix&lt;/li&gt;&lt;li&gt;Animação nocturna... Muito divertimento para proporcionar o convivio e interacção entre os participantes&lt;/li&gt;&lt;/ul&gt;Como pude observar na conferência do ano passado, a equipa do IIUG faz tudo o possível para proporcionar o melhor retorno do investimento. E eles, juntamente com quem apresenta as sessões, conseguem realmente providenciar óptimas sessões, excelentes &lt;span style="font-style: italic;"&gt;tutorials&lt;/span&gt; e muito entretenimento.&lt;br /&gt;&lt;br /&gt;Se nunca teve a oportunidade de participar numa das conferências do IIUG então não sabe o que perde. Se já teve, então sabe que valem a pena. Infelizmente este ano não me vai ser possível participar, mas fico ansioso pelo feedback da comunidade e para espreitar as apresentações quando estiverem disponíveis. A todos os felizardos que vão assistir á conferência, desejo um excelente evento, e por favor &lt;span style="font-style: italic;"&gt;bloguem&lt;/span&gt; ou contem na lista de mail como está a ser.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-8699943274094098784?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/8699943274094098784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=8699943274094098784' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/8699943274094098784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/8699943274094098784'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/05/iiug-2011-last-call-ultima-chamada.html' title='IIUG 2011: Last call / Ultima chamada'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-6597197633917965896</id><published>2011-04-18T01:30:00.000+01:00</published><updated>2011-04-18T03:42:05.457+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='roadshow'/><category scheme='http://www.blogger.com/atom/ns#' term='agenda'/><category scheme='http://www.blogger.com/atom/ns#' term='2011'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><title type='text'>Informix Roadshow 2011 Lisboa (Agenda)</title><content type='html'>This article is only written in Portuguese due to it's local nature&lt;br /&gt;Este artigo só está escrito em Português dada a sua natureza local&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A agenda do evento Informix Roadshow 2011 a realizar no próximo dia 3 de Maio nas instalações da IBM é:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;AGENDA:&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;9:45 &lt;/span&gt;Registo e Boas Vindas&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;10.00 – 10.15&lt;/span&gt; Discover the Next Decade of Informix at IBM&lt;br /&gt;Juan Brogeras - SWG Information Management Sales Director SPGI&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;10.15 – 10.45&lt;/span&gt; Informix UltimateWarehouse.Transformational and Continuous Improvements for Your DataWarehouse.&lt;br /&gt;Steve Shoaf -WWSales Executive - Informix &amp;amp; solidDB&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;10.45 – 11.15&lt;/span&gt; Informix Genero: Broadening the Informix 4GL Portfolio.&lt;br /&gt;Manuel Jorge Sousa - Vice President 4Js for Iberia&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;11.15 – 11.45&lt;/span&gt; Café&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;11.45 – 12.15&lt;/span&gt; Informix 11.7 solutions, features, roadmap and evolution&lt;br /&gt;José Manuel Ruiz Gallud - Database Sales, Southwest IOT&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;12.15 – 12.45&lt;/span&gt; Upgrading Informix Dynamic Server / Case study.&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;12.45 – 13.15&lt;/span&gt; Testemunho de um Informix Business Partner&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;13.15 – 13.30&lt;/span&gt; Wrap up / Almoço&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;br /&gt;Faça a sua inscrição através do email ibmdm@pt.ibm.com&lt;br /&gt;Estacionamento gratuito no parque do Hotel Vip Art’s (mesmo em frente ao Edf IBM no Parque das Nações em Lisboa)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-6597197633917965896?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/6597197633917965896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=6597197633917965896' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/6597197633917965896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/6597197633917965896'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/04/informix-roadshow-2011-lisboa-agenda.html' title='Informix Roadshow 2011 Lisboa (Agenda)'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-5608765976815300937</id><published>2011-04-13T23:56:00.004+01:00</published><updated>2011-04-14T00:26:20.191+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IBM'/><category scheme='http://www.blogger.com/atom/ns#' term='roadshow'/><category scheme='http://www.blogger.com/atom/ns#' term='Informix Warehouse Accelerator'/><category scheme='http://www.blogger.com/atom/ns#' term='2011'/><category scheme='http://www.blogger.com/atom/ns#' term='panther'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='Informix Genero'/><category scheme='http://www.blogger.com/atom/ns#' term='IBM Portugal Informix warehouse evento Forum Lisboa'/><title type='text'>Informix Roadshow 2011 Lisboa</title><content type='html'>This article is written only in Portuguese due to it's local nature&lt;br /&gt;Este artigo só está escrito em Português dada a natureza local&lt;br /&gt;&lt;br /&gt;Versão Portuguesa:&lt;br /&gt;&lt;br /&gt;A IBM vai realizar o Informix Roadshow 2011 no dia 3 de Maio, no IBM Fórum Lisboa (instalações da IBM no Parque das Nações).&lt;br /&gt;Será meio dia dedicado às últimas novidades da família Informix. Em particular:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Funcionalidades da versão 11.7 (Panther)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Informix Warehouse Accelerator&lt;/li&gt;&lt;li&gt;Informix Genero&lt;/li&gt;&lt;/ul&gt;Comemoram-se este ano os primeiros 10 anos após a aquisição da Informix, pelo que será apresentado um balanço desta década e lançamento das bases para a próxima&lt;br /&gt;As sessões contarão com oradores nacionais e internacionais. Haverá tempo para questões e interação entre clientes, parceiros e equipa IBM.&lt;br /&gt;Não deixe se comparecer e se não receber convite nos próximos dias não deixe de contactar a IBM ou a mim pessoalmente.&lt;br /&gt;No final das sessões será proporcionado um almoço onde terá toda a equipa IBM e oradores à sua disposição para qualquer esclarecimento adicional.&lt;br /&gt;O convite é extensível a todos os que não sendo clientes ou parceiros desejem conhecer melhor uma base de dados fiável, robusta, rápida, moderna, extensível e especialmente adaptada para ambientes "embebidos".&lt;br /&gt;&lt;br /&gt;Finalmente, mantenha-se atento a este espaço para obter informação mais detalhada sobre a agenda.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-5608765976815300937?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/5608765976815300937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=5608765976815300937' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/5608765976815300937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/5608765976815300937'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/04/informix-roadshow-2011-lisboa.html' title='Informix Roadshow 2011 Lisboa'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-2767577515225313479</id><published>2011-04-05T01:10:00.000+01:00</published><updated>2011-04-05T04:14:15.107+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Informix Warehouse Accelerator'/><category scheme='http://www.blogger.com/atom/ns#' term='Informix Genero'/><title type='text'>New products / Novos produtos</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está disponível em Inglês e Português&lt;br /&gt;&lt;br /&gt;English version:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Informix Warehouse Accelerator&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are several news in the Informix area. As I mentioned in the last article, version 11.7.xC2 is already available (including the update on the documentation center), but that's not all. One of the major features of 11.7.xC2 is that it supports a new product called Informix Warehouse Accelerator. This is a separate installable component, that uses a columnar based approach and holds copy of certain groups of tables (datamarts). The data is stored in memory and the queries that can be solved by this system are transparently sent from the main instance. If the data you're querying is not stored/duplicated in the system than the query is solved by the Informix instance. The principle is terribly simple and the installation and configuration is very straight forward. The Accelerator is only available for Linux x86_64 but can work together with Informix on other platforms. The product includes an eclipse based tool to manage the data mapping and configuration of your Informix instance. The product is oriented for data warehouse workloads and was already available for DB2 on z/OS.&lt;br /&gt;The Informix Ultimate Warehouse Edition includes the usual Informix features, the Warehouse Accelerator, compression, LBAC, replications etc.&lt;br /&gt;I've done a few preliminary tests and I can assure you the configuration is very easy. Expect some details in a future article. Meanwhile you can start discovering it at the following URL:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www-01.ibm.com/software/data/informix/ultimate-warehouse-edition/"&gt;http://www-01.ibm.com/software/data/informix/ultimate-warehouse-edition/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Informix Genero&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Informix Genero is another new product targeting the 4GL users. You may recognize the name as a &lt;a href="http://www.4js.com/"&gt;4JS&lt;/a&gt; product. It enables the modernization of 4GL applications (new interface, new functionalities, new deployment environments).&lt;br /&gt;&lt;br /&gt;I've seen lots of customers with very customized, flexible and stable applications running with Informix 4GL that complain about the looks (character based) and some lack of functionalities. Nevertheless they don't want to leave 4GL for several reasons:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;4GL productivity&lt;/li&gt;&lt;li&gt;Programmers mindset (4GL is a procedural language, and moving to object oriented is not always easy)&lt;/li&gt;&lt;li&gt;Ease of debug&lt;/li&gt;&lt;li&gt;Stability&lt;/li&gt;&lt;li&gt;etc.&lt;/li&gt;&lt;/ul&gt;If you're one of this customers you may want to take a close look at this new IBM offer. Please start here:&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;a href="http://www-01.ibm.com/software/data/informix/tools/genero.html"&gt;http://www-01.ibm.com/software/data/informix/tools/genero.html&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Partners conference calls:&lt;br /&gt;&lt;br /&gt;If you have interest in these two topics, you can try to check these two partner conference calls:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Informix Ultimate Warehouse Editions:&lt;br /&gt;April 5, at 10:00 Eastern Time (for Americas and EMEA)&lt;br /&gt;&lt;br /&gt;&lt;a href="https://events.webdialogs.com/register.php?id=5585aaa88c&amp;amp;l=en-US"&gt;https://events.webdialogs.com/register.php?id=5585aaa88c&amp;amp;l=en-US&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;April 5, at 20:00 Eastern Time (for Asia and Pacific)&lt;br /&gt;&lt;br /&gt;&lt;a href="https://events.webdialogs.com/register.php?id=aff9b337a3&amp;amp;l=en-US"&gt;https://events.webdialogs.com/register.php?id=aff9b337a3&amp;amp;l=en-US&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Informix Genero&lt;br /&gt;April 7, at 10:00 Eastern Time (for Americas and EMEA)&lt;br /&gt;&lt;a href="https://events.webdialogs.com/register.php?id=ca67bb2acd&amp;amp;l=en-US"&gt;&lt;br /&gt;https://events.webdialogs.com/register.php?id=ca67bb2acd&amp;amp;l=en-US&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;April 7, at 20:00 Eastern Time (for Asia and Pacific)&lt;br /&gt;&lt;br /&gt;&lt;a href="https://events.webdialogs.com/register.php?id=6b389b0604&amp;amp;l=en-US"&gt;https://events.webdialogs.com/register.php?id=6b389b0604&amp;amp;l=en-US&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Versão Portuguesa:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Informix Warehouse Accelerator&lt;/span&gt;&lt;br /&gt;Há várias noticias na área de Informix. Como mencionei no último artigo, a versão 11.7.xC2 já está disponível (incluindo a actualização no centro de documentação), mas não é tudo. Uma das funcionalidades da 11.7.xC2 é suportar um novo produto chamado Informix Warehouse Accelerator. Este é um componente instalado separadamente, que usa uma abordagem orientada a colunas e que guarda uma cópia de vários groupos de tabelas (datamarts). Estes dados são guardados em memória e a queries que possam resolver-se no novo sistema serão enviadas transparentementde pelo sistema principal. Se os dados não que estamos a interrogar não existirem neste sistema, então a &lt;span style="font-style: italic;"&gt;query&lt;/span&gt; é resolvida pelo sistema principal. O princípi é terrivelmente simples bem como a configuração e instalação. O Accelerator só existe para Linux x86_64 (mas pode estar ligado a uma instância Informix noutra plataforma). O produto incluí uma ferramenta baseada no Eclipse que permite a gestão dos mapeamentos de dados e a configuração da instância Informix. O produto é orientado a ambientes de &lt;span style="font-style: italic;"&gt;data warehouse&lt;/span&gt; e já estava disponível para DB2 em z/OS.&lt;br /&gt;O Informix Ultimate Warehouse Edition incluí as funcionalidades habituais do motor, o Warehouse Accelerator, compressão LBAC, replicação etc.&lt;br /&gt;Já tive oportunidade de fazer alguns testes preliminares e posso assegurar que a configuração é de facto muito fácil. Aguarde mais detalhes num futuro artigo. Entretanto pode começar a descobrir o assunto no seguinte URL:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www-01.ibm.com/software/data/informix/ultimate-warehouse-edition/"&gt;http://www-01.ibm.com/software/data/informix/ultimate-warehouse-edition/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Informix Genero&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O Informix Genero é outro produto cujo alvo são os utilizadores de 4GL. Talvez reconheça o nome como um produto da &lt;a href="http://www.4js.com/"&gt;4JS&lt;/a&gt;. Permite a modernização de aplicações 4GL (novo interface, novas funcionalidades, novos ambinetes de utilização).&lt;br /&gt;&lt;br /&gt;Tenho visto muitos clientes com aplicações muito adaptadas, fléxivies e estáveis que sistematicamente se quixam do aspecto (baseado em caracter) e alguma falta de funcionalidades.&lt;br /&gt;No entanto não querem deixar o 4GL por várias razoes.:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Produtividade do 4GL&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Orientação dos programadores(4GL é uma linguagem procedimental e a mudança para programação orientada a objectos nem sempre é fácil)&lt;/li&gt;&lt;li&gt;Facilidade de despiste de problemas&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Estabilidade&lt;br /&gt;&lt;/li&gt;&lt;li&gt;etc.&lt;/li&gt;&lt;/ul&gt;Se é um destes clientes, talvez queira dar uma olhadela nestas novas ofertas da IBM: Comec aqui:&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;a href="http://www-01.ibm.com/software/data/informix/tools/genero.html"&gt; http://www-01.ibm.com/software/data/informix/tools/genero.html&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Conferências para parceiras;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Se tem interesse em algum destes tópicos pode tentar assistir a estas duas reuniões&lt;br /&gt;&lt;br /&gt;Informix Ultimate Warehouse Editions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; 5 de Abril, às 10:00 Eastern Time (para as Americas e EMEA)&lt;br /&gt;   &lt;br /&gt;    &lt;a href="https://events.webdialogs.com/register.php?id=5585aaa88c&amp;amp;l=en-US"&gt;https://events.webdialogs.com/register.php?id=5585aaa88c&amp;amp;l=en-US&lt;/a&gt;&lt;br /&gt;   &lt;br /&gt;5 de Abril, às 20:00 Eastern Time (para a Asia e o  Pacifico)&lt;br /&gt;   &lt;br /&gt;    &lt;a href="https://events.webdialogs.com/register.php?id=aff9b337a3&amp;amp;l=en-US"&gt;https://events.webdialogs.com/register.php?id=aff9b337a3&amp;amp;l=en-US&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;ul&gt;&lt;li&gt;Informix Genero&lt;br /&gt;   7 de Abril, às 10:00 Eastern Time (para as Americas e EMEA)&lt;br /&gt;    &lt;a href="https://events.webdialogs.com/register.php?id=ca67bb2acd&amp;amp;l=en-US"&gt;&lt;br /&gt;https://events.webdialogs.com/register.php?id=ca67bb2acd&amp;amp;l=en-US&lt;/a&gt;&lt;br /&gt;   &lt;br /&gt;7 de Abril, às 20:00 Eastern Time (Asia e Pacifico)&lt;br /&gt;   &lt;br /&gt;    &lt;a href="https://events.webdialogs.com/register.php?id=6b389b0604&amp;amp;l=en-US"&gt;https://events.webdialogs.com/register.php?id=6b389b0604&amp;amp;l=en-US&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-2767577515225313479?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/2767577515225313479/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=2767577515225313479' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/2767577515225313479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/2767577515225313479'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/04/new-products-novos-produtos.html' title='New products / Novos produtos'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-5131379305325390034</id><published>2011-03-28T22:01:00.003+01:00</published><updated>2011-03-28T23:56:41.627+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DSS'/><category scheme='http://www.blogger.com/atom/ns#' term='11.70.UC2'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='OLTP'/><category scheme='http://www.blogger.com/atom/ns#' term='in memory database'/><category scheme='http://www.blogger.com/atom/ns#' term='datawarehouse accelerator'/><category scheme='http://www.blogger.com/atom/ns#' term='columnar database'/><category scheme='http://www.blogger.com/atom/ns#' term='11.170.FC2'/><category scheme='http://www.blogger.com/atom/ns#' term='11.70'/><category scheme='http://www.blogger.com/atom/ns#' term='OLAP'/><title type='text'>Informix 11.70.xC2: It's out!</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;English Version:&lt;br /&gt;&lt;br /&gt;It's been too long since my last post. The reason is the usual lack of time. Sorry for that...&lt;br /&gt;This is just a small post to let you know that Informix version 11.70.xC2 is being made available. It's already possible to get if from the Fix Central site (link on the right). The Information Center documentation site is still not updated. But a quick look into the release notes shows some interesting stuff:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Installation without root privileges&lt;br /&gt;This makes it possible to install and use Informix without root privileges. But due to the Unix/Linux nature, some features may not be available. This was a request from some embedded solutions providers. So it's another feature that helps make Informix the right choice for those environments. I believe we'll see more developments in the usage without root privileges in the future.&lt;/li&gt;&lt;li&gt;More SQL Admin API commands&lt;br /&gt;This time will see things like CREATE/DROP DATABASE and ONTAPE/ONBAR/ONSMSYNC commands. This is great since you can trigger your backups as tasks. Something that we're missing.&lt;/li&gt;&lt;li&gt;More improvements in the BTS text search datablade. IBM continues to improve this datablade which it free of charges&lt;/li&gt;&lt;li&gt;Table and column ALIASES in DML instructions (SELECT, DELETE and UPDATE)&lt;br /&gt;The ALIAS can now be used in GROUP BY clauses. I like this one. We could use numbers, but if you change your projection list you also need to change the GROUP BY clause.&lt;/li&gt;&lt;li&gt;Case insensitive searches&lt;br /&gt;This was also a frequently asked for feature. It applies only to NCHAR and NVARCHAR fields and you need to specify it in the CREATE DATABASE statement&lt;/li&gt;&lt;li&gt;OAT improvements&lt;br /&gt;As usual, when we see engine improvements we also see them in OAT. This time, a new area lets you manage your backups. Other features include the ability to uninstall a plug-in (something I also missed), ability to create reports based on historical data, improvements in the schema manager plugin-in and a few more&lt;/li&gt;&lt;li&gt;Ability to configure the number of file descriptor servers&lt;br /&gt;This is an intriguing feature related to a nasty problem that affects Informix instances with very intensive usage (I'm talking about thousands of concurrent connections, and a very high rate of new connections per second - typical values lay in the vicinity of more than 2000 concurrent sessions and/or more than 15 new connections per second, but it really depends on the environment). This issue is worth a dedicated article, and tech support usually knows it by "nsf.lock issue". If you never heard about it, it's because you don't suffer from it. In any case, this feature is in fact present in several older versions (later v10 fixpacks and 11.50). Unfortunately it was not properly documented. Also note that v11.7 has some structural changes that should eliminate this problem. The feature is translated into a new parameter called NUMFDSERVERS. Classical versions (pre v10.??) used just one. Somewhere in the v10 family it was decided that more was better, but sometimes it isn't due to other points of contention (eliminated in v11.7). So now you can decide how many to use.&lt;/li&gt;&lt;li&gt;Informix Warehouse Accelerator&lt;br /&gt;This is a new product that uses new technology. It is composed of a new in-memory based query engine, and a tool you use to map your OLTP data into that new system. Then, when you send DSS like queries to the OLTP engine, it will decide if the "partner" system can handle them. If it does the query is routed transparently and the results sent back. If it doesn't than the OLTP will resolve the queries. The advantage is that you get much (really!) faster query times on the queries routed to the new system. There was a preview of these technology on IIUG conference last year and the results were impressive. Please be alert, because there will be some buzz around this (the same technology is already available on DB2 for z/OS)&lt;/li&gt;&lt;/ul&gt;In short that's it. And there as with any other fixpack there are some bug fixes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Versão Portuguesa:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Passou muito tempo desde o último artigo. A razão é a habitual falta de tempo. As minhas desculpas...&lt;br /&gt;Este artigo serve apenas para dar conta de que a versão 11.7.xC2 do Informix está a ser disponibilizada. Já é possível obtê-la do site Fix Central (ligação à direita). A documentação no Information Center ainda estará a ser actualizada. Mas uma pequena espreitadela nas &lt;span style="font-style: italic;"&gt;release notes&lt;/span&gt; mostra algumas coisas interessantes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Instalação sem privilégios de &lt;span style="font-style: italic;"&gt;root&lt;/span&gt;.&lt;br /&gt;Isto torna possível instalar e utilizar o Informix sem privilégios de &lt;span style="font-style: italic;"&gt;root&lt;/span&gt;. Mas dada a natureza dos sistemas operativos Unix/Linux, algumas funcionalidades poderão não estar disponíveis. Isto foi um pedido de alguns fornecedores de soluções embebidas. Por isso é mais uma funcionalidade que ajuda o Informix a ser a escolha acertada para este tipo de ambientes. Acredito que iremos ver mais desenvolvimentos relativos à utilização sem &lt;span style="font-style: italic;"&gt;root&lt;/span&gt; no futuro&lt;/li&gt;&lt;li&gt;Mais comandos da API de administração SQL&lt;br /&gt;Desta vez vemos comandos como CREATE/DROP DATABASE e ONTAPE/ONBAR/ONSMSYNC. Isto é óptimo pois passamos a poder despoletar &lt;span style="font-style: italic;"&gt;backups&lt;/span&gt; como tarefas. Algo que já se sentia falta&lt;/li&gt;&lt;li&gt;Mais melhorias no &lt;span style="font-style: italic;"&gt;datablade&lt;/span&gt; de pesquisa de texto livre (BTS)&lt;br /&gt;A IBM continua a melhorar este &lt;span style="font-style: italic;"&gt;datablade&lt;/span&gt; que é distribuído sem custos com o produto&lt;/li&gt;&lt;li&gt;ALIAS em tabelas e colunas nas instruções de DML ((SELECT, DELETE and UPDATE)&lt;br /&gt;Os ALIAS podem agora ser usados nas cláusulas de GROUP BY. Pessoalmente agrada-me bastante. Já podíamos usar números, mas se mudássemos a &lt;span style="font-style: italic;"&gt;projection list&lt;/span&gt; teríamos também de arranjar a cláusula GROUP BY&lt;/li&gt;&lt;li&gt;Pesquisas por caracteres não sensíveis a maiúsculas ou minúsculas&lt;br /&gt;Esta funcionalidade fazia parte da lista com mais pedidos. Só se aplica a colunas NCHAR e NVARCHAR e tem de ser especificada na criação da base de dados (instrução CREATE DATABASE)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Melhorias no OAT&lt;br /&gt;Como vem sendo hábito, sempre que temos melhorias no motor também as vemos no OAT. Desta vez, uma nova área permite gerir os &lt;span style="font-style: italic;"&gt;backups&lt;/span&gt;. Outras novidades inclúem a possibilidade de desinstalar &lt;span style="font-style: italic;"&gt;plug-ins&lt;/span&gt; (algo que sentia falta), criação de relatórios baseados em dados de histórico, melhorias no &lt;span style="font-style: italic;"&gt;plug-in&lt;/span&gt; de gestão de &lt;span style="font-style: italic;"&gt;schema&lt;/span&gt; e mais alguns&lt;/li&gt;&lt;li&gt;Possibilidade de configurar o número de servidores de &lt;span style="font-style: italic;"&gt;file descriptors&lt;/span&gt;.&lt;br /&gt;Isto é uma funcionalidade algo intrigante, relacionada com um problema complexo que afecta instâncias Informix com uma utilização muito intensiva (estou a falar de milhares de sessões concorrentes e uma taxa muito alta de novas sessões por segundo - valores tipicos situam-se perto de mais de 2000 sessões concorrentes e/ou mais de 15 novas sessões por segundo, mas dependerá sempre de cada ambiente)&lt;br /&gt;Este assunto mereceria por si só um artigo, mas o suporte técnico reconhece-o por "problema do nsf.lock". Se nunca ouviu falar nele é porque nunca sofreu com ele. Em qualquer caso, esta funcionalidade está de facto presente em várias versões já antigas (últimos fixpacks da versão 10 e fixpacks da versão 11.50). Infelizmente não estava devidamente documentadas. Note-se também que a versão 11.7 tem algumas modificações estruturuais que deverão eliminar este problema. A funcionalidade traduz-se num novo parâmetro chamado NUMFDSERVERS. Versões antigas (pre v10.??) usavam apenas um servidor de &lt;span style="font-style: italic;"&gt;file descriptors&lt;/span&gt;. Num determinado fixpack da versão 10 considerou-se que mais era melhora, mas em alguns casos não é, devido a outros pontos de contenção (eliminados na versão 11.7). Assim, agora podemos decidir e ajustar quantos queremos&lt;/li&gt;&lt;li&gt;Informix Warehouse Accelerator&lt;br /&gt;Isto é um novo produto que utiliza tecnologia nova. É composto por um motor de &lt;span style="font-style: italic;"&gt;queries&lt;/span&gt;, baseado em memória, e uma ferramenta que pode usar-se para mapear alguns dados do sistema OLTP neste novo sistema. Depois, quando enviados uma query do tipo DSS ao motor OLTP, ele decide se o novo sistema associado pode resolver a query. Se sim, a query é enviada transparentemente ao novo sistema, e os resultados são enviados de volta. Se a query não puder ser processada pelo sistema "emparceirado", então o sistema OLTP irá resolvê-la. A vantagem é que obteremos muito (mesmo muito!) melhores tempos de execução nas querys enviadas ao novo sistema. Houve uma antevisão do sistema na última conferência do IIUG e os resultados eram realmente impressionantes. Mantenha-se alerta, pois isto irá certamente dar que falar nos próximos tempos (a mesma tecnologia já existe para DB2 em z/OS)&lt;/li&gt;&lt;/ul&gt; Em resumo é isto. E como em qualquer outro fixpack contém igualmente um número de correcções.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-5131379305325390034?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/5131379305325390034/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=5131379305325390034' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/5131379305325390034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/5131379305325390034'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/03/informix-1170xc2-its-out.html' title='Informix 11.70.xC2: It&apos;s out!'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-8474331569686319480</id><published>2011-01-26T01:14:00.003Z</published><updated>2011-01-26T01:25:27.478Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='planet'/><category scheme='http://www.blogger.com/atom/ns#' term='smarter'/><category scheme='http://www.blogger.com/atom/ns#' term='centric'/><category scheme='http://www.blogger.com/atom/ns#' term='bank'/><category scheme='http://www.blogger.com/atom/ns#' term='swift'/><category scheme='http://www.blogger.com/atom/ns#' term='solutions'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='china'/><title type='text'>Informix making the world smarter...</title><content type='html'>This article is written only in English&lt;br /&gt;Este artigo apenas está disponível em Inglês&lt;br /&gt;&lt;br /&gt;Although I'm preparing some technical articles I'm happy to make a break to echo some good news...&lt;br /&gt;&lt;br /&gt;Informix is helping an IBM Partner, &lt;a href="http://www.centricisolutions.com/"&gt;Centric Solutions&lt;/a&gt;, in making the world &lt;a href="http://www.smartplanet.com/business/blog/business-brains/london-based-bank-slashes-paper-consumption-with-workflow-software/13192/"&gt;smarter&lt;/a&gt;. Bank of China is using it for a &lt;a href="http://en.wikipedia.org/wiki/Society_for_Worldwide_Interbank_Financial_Telecommunication"&gt;SWIFT&lt;/a&gt; application, that also helps to save trees.&lt;br /&gt;&lt;br /&gt;These are my words, but I think everyone agrees it must be robust, fast and trustworthy... and Informix is a perfect match for that!&lt;br /&gt;&lt;br /&gt;Read all about it here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.prnewswire.com/news-releases/bank-of-china-in-the-uk-works-with-ibm-to-become-a-smarter-greener-bank-114573679.html"&gt;http://www.prnewswire.com/news-releases/bank-of-china-in-the-uk-works-with-ibm-to-become-a-smarter-greener-bank-114573679.html&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-8474331569686319480?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/8474331569686319480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=8474331569686319480' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/8474331569686319480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/8474331569686319480'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/01/informix-making-world-smarter.html' title='Informix making the world smarter...'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-8542655163837757023</id><published>2011-01-09T00:40:00.005Z</published><updated>2011-01-12T22:51:07.371Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='cosmo'/><category scheme='http://www.blogger.com/atom/ns#' term='update statistics'/><category scheme='http://www.blogger.com/atom/ns#' term='stored'/><category scheme='http://www.blogger.com/atom/ns#' term='pdqpriority'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='pdq'/><category scheme='http://www.blogger.com/atom/ns#' term='procedure'/><category scheme='http://www.blogger.com/atom/ns#' term='simon david'/><title type='text'>Stored procedure PDQ / PDQ dos procedimentos</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;English version:&lt;br /&gt;&lt;br /&gt;A few years ago I needed to check if I had some stored procedures created with PDQ. Maybe some readers don't know, but if you have SET PDQPRIORITY n in your session before creating a procedure it will run with that PDQ. And that can cause abnormal resource consumption. In most cases you'll want your procedures created without PDQ.&lt;br /&gt;The PDQ associated with a procedure will also change if you run UPDATE STATISTICS FOR PROCEDURE [...], in a session with PDQ active. This is also a frequent issue when people forgot to turn it off or when the statistics are gathered for tables (where PDQ can be helpful) and procedures on the same command or script.&lt;br /&gt;&lt;br /&gt;So, how to check the PDQ of your procedures? The catalog tables don't provide this information, so at the time I asked for help internally within IBM. Cosmo, from UK came to my rescue with a strange query that I used successfully a couple of times. The query checks the first 3 characters of the column "data" from sysprocplan where planid = -2.... Don't ask... supposedly this is an encode of the PDQ value.&lt;br /&gt;Recently I had another situation on a customer, where we suspected they had their procedures with PDQ. We were expecting to see the value of 80 (which we caught in some sessions) but all we saw was NULL.  Once again I asked Cosmo for help, and during our conversations we noticed that we only had run the query on &lt;a href="http://en.wikipedia.org/wiki/Endianness"&gt;little endian&lt;/a&gt; platforms (Linux on Intel and Tru64). So, Cosmo sent me a script that created 100 procedures with different PDQ levels and then returns the encoded values. It was no surprise that the values were different. Following Cosmo's suggestion I joined both set of values into a big CASE statement that you can check at the end of this article.&lt;br /&gt;&lt;br /&gt;The query has a few important points:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;I used data[1,3] in the CASE statement. We could use data::CHAR(3), but with that it would not run on version 7. It's not supported anymore, but there are still people using it, so I decided to use a syntax that's compatible with those old versions.&lt;/li&gt;&lt;li&gt;If I remember correctly Cosmo's first query was really a function that received the  procedure name. I'm including that as another option in the end of the article. In that version the query raises and error if it enters the ELSE condition of the CASE statement. In the version I was using at the later customer, the case returned NULL and that fulled me... In this new version it will raise an error since it means there is something wrong with the query.&lt;br /&gt;For the non-procedural version, I did a small and dirty trick: If it enters the ELSE condition it will try to return a value divided by zero. This will cause an error.&lt;br /&gt;Note that this conditions can't happen because the PDQ must be a value between 0 and 100. So if in the future the encoding changes the query will start raising errors, and this should alert the user...&lt;/li&gt;&lt;li&gt;The encoded values for PDQ 1 to 100 are distinct in the two types of platforms. The encoded value for 0 however is equal. That's why we have two WHEN conditions for each value between 1 and 100 and just one for 0.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Versão Portuguesa:&lt;br /&gt;&lt;br /&gt;Há alguns anos atrás precisei de verificar se tinha criado algum procedimento com PDQ. Talvez alguns leitores não saibam, mas se tivermos executado SET PDQPRIORITY n na sessão antes de criar um procedimento, este irá ser executado com esse valor de PDQ. E isso pode causar um consumo anormal de recursos. Na maioria das situações não queremos ter procedimentos criados com PDQ.&lt;br /&gt;O PDQ associado a um procedimento também muda se corrermos um UPDATE STATISTICS FOR PROCEDURE [...], numa sessão com PDQ activo. Isto é um problema habitual quando nos esquecemos de desligar o PDQ, ou quando as estatísticas são criadas para tabelas (processo onde o PDQ é benéfico) e procedimentos no mesmo comando ou &lt;span style="font-style: italic;"&gt;script.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Como podemos verificar o PDQ dos procedimentos? As tabelas do catálogo não disponibilizam esta informação, por isso na altura pedi ajuda internamente na IBM. O Cosmo, de UK, auxiliou-me com o envio de uma query um pouco estranha que usei algumas vezes com sucesso. A query verifica os três primeiros caracteres de uma coluna "data" da tabela sysprocplan, onde "planid = -2"... Não pergunte... É suposto isto ser o valor de PDQ codificado de alguma forma.&lt;br /&gt;Recentemente tive outra situação num cliente onde suspeitávamos que tinham os procedimentos com PDQ. Esperávamos ver o valor 80 (que tinhamos visto activo em algumas sessões), mas tudo o que a query nos dava era NULL. Note-se que se tivesse olhado bem para a query deveria ter percebido que o NULL implicava um erro. Mas como estávamos à espera de ver um valor (80) cometi um "erro de simpatia". Recorri novamente ao Cosmo para ajuda. E durante as nossas trocas de impressões notámos que só tinhamos corrido a query em plataforms que usam &lt;a href="http://pt.wikipedia.org/wiki/Extremidade_%28ordena%C3%A7%C3%A3o%29"&gt;&lt;span style="font-style: italic;"&gt;little endian&lt;/span&gt;&lt;/a&gt; (Linux em Intel e Tru64). Assim o Cosmo enviou-me um &lt;span style="font-style: italic;"&gt;script&lt;/span&gt; que cria 100 procedimentos com diferentes valores de PDQ e que retorna os respectivos valores codificados. Não foi surpresa ver valores diferentes. Seguindo uma sugestão do Cosmo, juntei ambos os conjuntos de valores numa instrução CASE que pode ser consultada no final deste artigo.&lt;br /&gt;&lt;br /&gt;A query tem alguns pontos importantes:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Utilizei data[1,3] na instrução CASE. Podíamos utilizar data::CHAR(3), mas com isso a query não correria na versão 7. Esta versão já está sem suporte, mas ainda é usada, por isso preferi uma sintaxe compatível com versões mais antigas&lt;/li&gt;&lt;li&gt;Se bem me recordo a primeira query que o Cosmo me enviou, era na realidade uma função que recebia o nome do procedimento que queríamos verificar. Esta forma está também incluída no final do artigo. Nesta forma o código causa um erro caso entre na condição ELSE do CASE. Na versão que estava a usar neste último cliente, o CASE retornava NULL e isso enganou-me... Nesta versão actualizada e corrigida, irá gerar um erro, dado que isso implica que algo não está correcto na query. Não versão não procedimental incluí um pequeno truque: Se entrar no ELSE do CASE vai tentar retornar um valor a dividir por zero. Isto irá causar um erro.&lt;br /&gt;Note-se que esta condição não pode acontecer pois o PDQ será sempre um valor entre 0 e 100. Se no futuro os valores codificados forem alterados a query deverá começar a dar erro, e isso deverá alertar o utilizador...&lt;/li&gt;&lt;li&gt;Os valores codificados de PDQ de 1 a 100 são distintos nos dois tipos de plataforma (&lt;span style="font-style: italic;"&gt;little endian  &lt;/span&gt;e &lt;span style="font-style: italic;"&gt;big endian&lt;/span&gt;). No entanto o valor codificado para 0 é igual. É por isso que temos duas condições WHEN para cada valor entre 1 e 100 e só um para o valor 0.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Non-procedural query:&lt;br /&gt;Query não procedimental:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SELECT&lt;br /&gt; f.procname,&lt;br /&gt; CASE data[1,3]&lt;br /&gt;     WHEN "AAA" THEN 0&lt;br /&gt;     WHEN "AQA" THEN 1&lt;br /&gt;     WHEN "AAE" THEN 1&lt;br /&gt;     WHEN "AgA" THEN 2&lt;br /&gt;     WHEN "AAI" THEN 2&lt;br /&gt;     WHEN "AwA" THEN 3&lt;br /&gt;     WHEN "AAM" THEN 3&lt;br /&gt;     WHEN "BAA" THEN 4&lt;br /&gt;     WHEN "AAQ" THEN 4&lt;br /&gt;     WHEN "BQA" THEN 5&lt;br /&gt;     WHEN "AAU" THEN 5&lt;br /&gt;     WHEN "BgA" THEN 6&lt;br /&gt;     WHEN "AAY" THEN 6&lt;br /&gt;     WHEN "BwA" THEN 7&lt;br /&gt;     WHEN "AAc" THEN 7&lt;br /&gt;     WHEN "CAA" THEN 8&lt;br /&gt;     WHEN "AAg" THEN 8&lt;br /&gt;     WHEN "CQA" THEN 9&lt;br /&gt;     WHEN "AAk" THEN 9&lt;br /&gt;     WHEN "CgA" THEN 10&lt;br /&gt;     WHEN "AAo" THEN 10&lt;br /&gt;     WHEN "CwA" THEN 11&lt;br /&gt;     WHEN "AAs" THEN 11&lt;br /&gt;     WHEN "DAA" THEN 12&lt;br /&gt;     WHEN "AAw" THEN 12&lt;br /&gt;     WHEN "DQA" THEN 13&lt;br /&gt;     WHEN "AA0" THEN 13&lt;br /&gt;     WHEN "DgA" THEN 14&lt;br /&gt;     WHEN "AA4" THEN 14&lt;br /&gt;     WHEN "DwA" THEN 15&lt;br /&gt;     WHEN "AA8" THEN 15&lt;br /&gt;     WHEN "EAA" THEN 16&lt;br /&gt;     WHEN "ABA" THEN 16&lt;br /&gt;     WHEN "EQA" THEN 17&lt;br /&gt;     WHEN "ABE" THEN 17&lt;br /&gt;     WHEN "EgA" THEN 18&lt;br /&gt;     WHEN "ABI" THEN 18&lt;br /&gt;     WHEN "EwA" THEN 19&lt;br /&gt;     WHEN "ABM" THEN 19&lt;br /&gt;     WHEN "FAA" THEN 20&lt;br /&gt;     WHEN "ABQ" THEN 20&lt;br /&gt;     WHEN "FQA" THEN 21&lt;br /&gt;     WHEN "ABU" THEN 21&lt;br /&gt;     WHEN "FgA" THEN 22&lt;br /&gt;     WHEN "ABY" THEN 22&lt;br /&gt;     WHEN "FwA" THEN 23&lt;br /&gt;     WHEN "ABc" THEN 23&lt;br /&gt;     WHEN "GAA" THEN 24&lt;br /&gt;     WHEN "ABg" THEN 24&lt;br /&gt;     WHEN "GQA" THEN 25&lt;br /&gt;     WHEN "ABk" THEN 25&lt;br /&gt;     WHEN "GgA" THEN 26&lt;br /&gt;     WHEN "ABo" THEN 26&lt;br /&gt;     WHEN "GwA" THEN 27&lt;br /&gt;     WHEN "ABs" THEN 27&lt;br /&gt;     WHEN "HAA" THEN 28&lt;br /&gt;     WHEN "ABw" THEN 28&lt;br /&gt;     WHEN "HQA" THEN 29&lt;br /&gt;     WHEN "AB0" THEN 29&lt;br /&gt;     WHEN "HgA" THEN 30&lt;br /&gt;     WHEN "AB4" THEN 30&lt;br /&gt;     WHEN "HwA" THEN 31&lt;br /&gt;     WHEN "AB8" THEN 31&lt;br /&gt;     WHEN "IAA" THEN 32&lt;br /&gt;     WHEN "ACA" THEN 32&lt;br /&gt;     WHEN "IQA" THEN 33&lt;br /&gt;     WHEN "ACE" THEN 33&lt;br /&gt;     WHEN "IgA" THEN 34&lt;br /&gt;     WHEN "ACI" THEN 34&lt;br /&gt;     WHEN "IwA" THEN 35&lt;br /&gt;     WHEN "ACM" THEN 35&lt;br /&gt;     WHEN "JAA" THEN 36&lt;br /&gt;     WHEN "ACQ" THEN 36&lt;br /&gt;     WHEN "JQA" THEN 37&lt;br /&gt;     WHEN "ACU" THEN 37&lt;br /&gt;     WHEN "JgA" THEN 38&lt;br /&gt;     WHEN "ACY" THEN 38&lt;br /&gt;     WHEN "JwA" THEN 39&lt;br /&gt;     WHEN "ACc" THEN 39&lt;br /&gt;     WHEN "KAA" THEN 40&lt;br /&gt;     WHEN "ACg" THEN 40&lt;br /&gt;     WHEN "KQA" THEN 41&lt;br /&gt;     WHEN "ACk" THEN 41&lt;br /&gt;     WHEN "KgA" THEN 42&lt;br /&gt;     WHEN "ACo" THEN 42&lt;br /&gt;     WHEN "KwA" THEN 43&lt;br /&gt;     WHEN "ACs" THEN 43&lt;br /&gt;     WHEN "LAA" THEN 44&lt;br /&gt;     WHEN "ACw" THEN 44&lt;br /&gt;     WHEN "LQA" THEN 45&lt;br /&gt;     WHEN "AC0" THEN 45&lt;br /&gt;     WHEN "LgA" THEN 46&lt;br /&gt;     WHEN "AC4" THEN 46&lt;br /&gt;     WHEN "LwA" THEN 47&lt;br /&gt;     WHEN "AC8" THEN 47&lt;br /&gt;     WHEN "MAA" THEN 48&lt;br /&gt;     WHEN "ADA" THEN 48&lt;br /&gt;     WHEN "MQA" THEN 49&lt;br /&gt;     WHEN "ADE" THEN 49&lt;br /&gt;     WHEN "MgA" THEN 50&lt;br /&gt;     WHEN "ADI" THEN 50&lt;br /&gt;     WHEN "MwA" THEN 51&lt;br /&gt;     WHEN "ADM" THEN 51&lt;br /&gt;     WHEN "NAA" THEN 52&lt;br /&gt;     WHEN "ADQ" THEN 52&lt;br /&gt;     WHEN "NQA" THEN 53&lt;br /&gt;     WHEN "ADU" THEN 53&lt;br /&gt;     WHEN "NgA" THEN 54&lt;br /&gt;     WHEN "ADY" THEN 54&lt;br /&gt;     WHEN "NwA" THEN 55&lt;br /&gt;     WHEN "ADc" THEN 55&lt;br /&gt;     WHEN "OAA" THEN 56&lt;br /&gt;     WHEN "ADg" THEN 56&lt;br /&gt;     WHEN "OQA" THEN 57&lt;br /&gt;     WHEN "ADk" THEN 57&lt;br /&gt;     WHEN "OgA" THEN 58&lt;br /&gt;     WHEN "ADo" THEN 58&lt;br /&gt;     WHEN "OwA" THEN 59&lt;br /&gt;     WHEN "ADs" THEN 59&lt;br /&gt;     WHEN "PAA" THEN 60&lt;br /&gt;     WHEN "ADw" THEN 60&lt;br /&gt;     WHEN "PQA" THEN 61&lt;br /&gt;     WHEN "AD0" THEN 61&lt;br /&gt;     WHEN "PgA" THEN 62&lt;br /&gt;     WHEN "AD4" THEN 62&lt;br /&gt;     WHEN "PwA" THEN 63&lt;br /&gt;     WHEN "AD8" THEN 63&lt;br /&gt;     WHEN "QAA" THEN 64&lt;br /&gt;     WHEN "AEA" THEN 64&lt;br /&gt;     WHEN "QQA" THEN 65&lt;br /&gt;     WHEN "AEE" THEN 65&lt;br /&gt;     WHEN "QgA" THEN 66&lt;br /&gt;     WHEN "AEI" THEN 66&lt;br /&gt;     WHEN "QwA" THEN 67&lt;br /&gt;     WHEN "AEM" THEN 67&lt;br /&gt;     WHEN "RAA" THEN 68&lt;br /&gt;     WHEN "AEQ" THEN 68&lt;br /&gt;     WHEN "RQA" THEN 69&lt;br /&gt;     WHEN "AEU" THEN 69&lt;br /&gt;     WHEN "RgA" THEN 70&lt;br /&gt;     WHEN "AEY" THEN 70&lt;br /&gt;     WHEN "RwA" THEN 71&lt;br /&gt;     WHEN "AEc" THEN 71&lt;br /&gt;     WHEN "SAA" THEN 72&lt;br /&gt;     WHEN "AEg" THEN 72&lt;br /&gt;     WHEN "SQA" THEN 73&lt;br /&gt;     WHEN "AEk" THEN 73&lt;br /&gt;     WHEN "SgA" THEN 74&lt;br /&gt;     WHEN "AEo" THEN 74&lt;br /&gt;     WHEN "SwA" THEN 75&lt;br /&gt;     WHEN "AEs" THEN 75&lt;br /&gt;     WHEN "TAA" THEN 76&lt;br /&gt;     WHEN "AEw" THEN 76&lt;br /&gt;     WHEN "TQA" THEN 77&lt;br /&gt;     WHEN "AE0" THEN 77&lt;br /&gt;     WHEN "TgA" THEN 78&lt;br /&gt;     WHEN "AE4" THEN 78&lt;br /&gt;     WHEN "TwA" THEN 79&lt;br /&gt;     WHEN "AE8" THEN 79&lt;br /&gt;     WHEN "UAA" THEN 80&lt;br /&gt;     WHEN "AFA" THEN 80&lt;br /&gt;     WHEN "UQA" THEN 81&lt;br /&gt;     WHEN "AFE" THEN 81&lt;br /&gt;     WHEN "UgA" THEN 82&lt;br /&gt;     WHEN "AFI" THEN 82&lt;br /&gt;     WHEN "UwA" THEN 83&lt;br /&gt;     WHEN "AFM" THEN 83&lt;br /&gt;     WHEN "VAA" THEN 84&lt;br /&gt;     WHEN "AFQ" THEN 84&lt;br /&gt;     WHEN "VQA" THEN 85&lt;br /&gt;     WHEN "AFU" THEN 85&lt;br /&gt;     WHEN "VgA" THEN 86&lt;br /&gt;     WHEN "AFY" THEN 86&lt;br /&gt;     WHEN "VwA" THEN 87&lt;br /&gt;     WHEN "AFc" THEN 87&lt;br /&gt;     WHEN "WAA" THEN 88&lt;br /&gt;     WHEN "AFg" THEN 88&lt;br /&gt;     WHEN "WQA" THEN 89&lt;br /&gt;     WHEN "AFk" THEN 89&lt;br /&gt;     WHEN "WgA" THEN 90&lt;br /&gt;     WHEN "AFo" THEN 90&lt;br /&gt;     WHEN "WwA" THEN 91&lt;br /&gt;     WHEN "AFs" THEN 91&lt;br /&gt;     WHEN "XAA" THEN 92&lt;br /&gt;     WHEN "AFw" THEN 92&lt;br /&gt;     WHEN "XQA" THEN 93&lt;br /&gt;     WHEN "AF0" THEN 93&lt;br /&gt;     WHEN "XgA" THEN 94&lt;br /&gt;     WHEN "AF4" THEN 94&lt;br /&gt;     WHEN "XwA" THEN 95&lt;br /&gt;     WHEN "AF8" THEN 95&lt;br /&gt;     WHEN "YAA" THEN 96&lt;br /&gt;     WHEN "AGA" THEN 96&lt;br /&gt;     WHEN "YQA" THEN 97&lt;br /&gt;     WHEN "AGE" THEN 97&lt;br /&gt;     WHEN "YgA" THEN 98&lt;br /&gt;     WHEN "AGI" THEN 98&lt;br /&gt;     WHEN "YwA" THEN 99&lt;br /&gt;     WHEN "AGM" THEN 99&lt;br /&gt;     WHEN "ZAA" THEN 100&lt;br /&gt;     WHEN "AGQ" THEN 100&lt;br /&gt; ELSE&lt;br /&gt;     TRUNC(p.rowid / 0)&lt;br /&gt; END pdq_value&lt;br /&gt;FROM&lt;br /&gt; sysprocplan p, sysprocedures f&lt;br /&gt;WHERE&lt;br /&gt; p.planid = -2 AND&lt;br /&gt; f.procid = p.procid&lt;br /&gt;ORDER BY 2 DESC&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Procedural version:&lt;br /&gt;Versão procedimental:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;CREATE FUNCTION get_proc_pdq_value(v_proc_name VARCHAR(128))&lt;br /&gt;RETURNING SMALLINT;&lt;br /&gt;&lt;br /&gt;DEFINE v_ret_pdq_value SMALLINT;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;SELECT&lt;br /&gt; f.procname,&lt;br /&gt; CASE data[1,3]&lt;br /&gt;     WHEN "AAA" THEN 0&lt;br /&gt;     WHEN "AQA" THEN 1&lt;br /&gt;     WHEN "AAE" THEN 1&lt;br /&gt;     WHEN "AgA" THEN 2&lt;br /&gt;     WHEN "AAI" THEN 2&lt;br /&gt;     WHEN "AwA" THEN 3&lt;br /&gt;     WHEN "AAM" THEN 3&lt;br /&gt;     WHEN "BAA" THEN 4&lt;br /&gt;     WHEN "AAQ" THEN 4&lt;br /&gt;     WHEN "BQA" THEN 5&lt;br /&gt;     WHEN "AAU" THEN 5&lt;br /&gt;     WHEN "BgA" THEN 6&lt;br /&gt;     WHEN "AAY" THEN 6&lt;br /&gt;     WHEN "BwA" THEN 7&lt;br /&gt;     WHEN "AAc" THEN 7&lt;br /&gt;     WHEN "CAA" THEN 8&lt;br /&gt;     WHEN "AAg" THEN 8&lt;br /&gt;     WHEN "CQA" THEN 9&lt;br /&gt;     WHEN "AAk" THEN 9&lt;br /&gt;     WHEN "CgA" THEN 10&lt;br /&gt;     WHEN "AAo" THEN 10&lt;br /&gt;     WHEN "CwA" THEN 11&lt;br /&gt;     WHEN "AAs" THEN 11&lt;br /&gt;     WHEN "DAA" THEN 12&lt;br /&gt;     WHEN "AAw" THEN 12&lt;br /&gt;     WHEN "DQA" THEN 13&lt;br /&gt;     WHEN "AA0" THEN 13&lt;br /&gt;     WHEN "DgA" THEN 14&lt;br /&gt;     WHEN "AA4" THEN 14&lt;br /&gt;     WHEN "DwA" THEN 15&lt;br /&gt;     WHEN "AA8" THEN 15&lt;br /&gt;     WHEN "EAA" THEN 16&lt;br /&gt;     WHEN "ABA" THEN 16&lt;br /&gt;     WHEN "EQA" THEN 17&lt;br /&gt;     WHEN "ABE" THEN 17&lt;br /&gt;     WHEN "EgA" THEN 18&lt;br /&gt;     WHEN "ABI" THEN 18&lt;br /&gt;     WHEN "EwA" THEN 19&lt;br /&gt;     WHEN "ABM" THEN 19&lt;br /&gt;     WHEN "FAA" THEN 20&lt;br /&gt;     WHEN "ABQ" THEN 20&lt;br /&gt;     WHEN "FQA" THEN 21&lt;br /&gt;     WHEN "ABU" THEN 21&lt;br /&gt;     WHEN "FgA" THEN 22&lt;br /&gt;     WHEN "ABY" THEN 22&lt;br /&gt;     WHEN "FwA" THEN 23&lt;br /&gt;     WHEN "ABc" THEN 23&lt;br /&gt;     WHEN "GAA" THEN 24&lt;br /&gt;     WHEN "ABg" THEN 24&lt;br /&gt;     WHEN "GQA" THEN 25&lt;br /&gt;     WHEN "ABk" THEN 25&lt;br /&gt;     WHEN "GgA" THEN 26&lt;br /&gt;     WHEN "ABo" THEN 26&lt;br /&gt;     WHEN "GwA" THEN 27&lt;br /&gt;     WHEN "ABs" THEN 27&lt;br /&gt;     WHEN "HAA" THEN 28&lt;br /&gt;     WHEN "ABw" THEN 28&lt;br /&gt;     WHEN "HQA" THEN 29&lt;br /&gt;     WHEN "AB0" THEN 29&lt;br /&gt;     WHEN "HgA" THEN 30&lt;br /&gt;     WHEN "AB4" THEN 30&lt;br /&gt;     WHEN "HwA" THEN 31&lt;br /&gt;     WHEN "AB8" THEN 31&lt;br /&gt;     WHEN "IAA" THEN 32&lt;br /&gt;     WHEN "ACA" THEN 32&lt;br /&gt;     WHEN "IQA" THEN 33&lt;br /&gt;     WHEN "ACE" THEN 33&lt;br /&gt;     WHEN "IgA" THEN 34&lt;br /&gt;     WHEN "ACI" THEN 34&lt;br /&gt;     WHEN "IwA" THEN 35&lt;br /&gt;     WHEN "ACM" THEN 35&lt;br /&gt;     WHEN "JAA" THEN 36&lt;br /&gt;     WHEN "ACQ" THEN 36&lt;br /&gt;     WHEN "JQA" THEN 37&lt;br /&gt;     WHEN "ACU" THEN 37&lt;br /&gt;     WHEN "JgA" THEN 38&lt;br /&gt;     WHEN "ACY" THEN 38&lt;br /&gt;     WHEN "JwA" THEN 39&lt;br /&gt;     WHEN "ACc" THEN 39&lt;br /&gt;     WHEN "KAA" THEN 40&lt;br /&gt;     WHEN "ACg" THEN 40&lt;br /&gt;     WHEN "KQA" THEN 41&lt;br /&gt;     WHEN "ACk" THEN 41&lt;br /&gt;     WHEN "KgA" THEN 42&lt;br /&gt;     WHEN "ACo" THEN 42&lt;br /&gt;     WHEN "KwA" THEN 43&lt;br /&gt;     WHEN "ACs" THEN 43&lt;br /&gt;     WHEN "LAA" THEN 44&lt;br /&gt;     WHEN "ACw" THEN 44&lt;br /&gt;     WHEN "LQA" THEN 45&lt;br /&gt;     WHEN "AC0" THEN 45&lt;br /&gt;     WHEN "LgA" THEN 46&lt;br /&gt;     WHEN "AC4" THEN 46&lt;br /&gt;     WHEN "LwA" THEN 47&lt;br /&gt;     WHEN "AC8" THEN 47&lt;br /&gt;     WHEN "MAA" THEN 48&lt;br /&gt;     WHEN "ADA" THEN 48&lt;br /&gt;     WHEN "MQA" THEN 49&lt;br /&gt;     WHEN "ADE" THEN 49&lt;br /&gt;     WHEN "MgA" THEN 50&lt;br /&gt;     WHEN "ADI" THEN 50&lt;br /&gt;     WHEN "MwA" THEN 51&lt;br /&gt;     WHEN "ADM" THEN 51&lt;br /&gt;     WHEN "NAA" THEN 52&lt;br /&gt;     WHEN "ADQ" THEN 52&lt;br /&gt;     WHEN "NQA" THEN 53&lt;br /&gt;     WHEN "ADU" THEN 53&lt;br /&gt;     WHEN "NgA" THEN 54&lt;br /&gt;     WHEN "ADY" THEN 54&lt;br /&gt;     WHEN "NwA" THEN 55&lt;br /&gt;     WHEN "ADc" THEN 55&lt;br /&gt;     WHEN "OAA" THEN 56&lt;br /&gt;     WHEN "ADg" THEN 56&lt;br /&gt;     WHEN "OQA" THEN 57&lt;br /&gt;     WHEN "ADk" THEN 57&lt;br /&gt;     WHEN "OgA" THEN 58&lt;br /&gt;     WHEN "ADo" THEN 58&lt;br /&gt;     WHEN "OwA" THEN 59&lt;br /&gt;     WHEN "ADs" THEN 59&lt;br /&gt;     WHEN "PAA" THEN 60&lt;br /&gt;     WHEN "ADw" THEN 60&lt;br /&gt;     WHEN "PQA" THEN 61&lt;br /&gt;     WHEN "AD0" THEN 61&lt;br /&gt;     WHEN "PgA" THEN 62&lt;br /&gt;     WHEN "AD4" THEN 62&lt;br /&gt;     WHEN "PwA" THEN 63&lt;br /&gt;     WHEN "AD8" THEN 63&lt;br /&gt;     WHEN "QAA" THEN 64&lt;br /&gt;     WHEN "AEA" THEN 64&lt;br /&gt;     WHEN "QQA" THEN 65&lt;br /&gt;     WHEN "AEE" THEN 65&lt;br /&gt;     WHEN "QgA" THEN 66&lt;br /&gt;     WHEN "AEI" THEN 66&lt;br /&gt;     WHEN "QwA" THEN 67&lt;br /&gt;     WHEN "AEM" THEN 67&lt;br /&gt;     WHEN "RAA" THEN 68&lt;br /&gt;     WHEN "AEQ" THEN 68&lt;br /&gt;     WHEN "RQA" THEN 69&lt;br /&gt;     WHEN "AEU" THEN 69&lt;br /&gt;     WHEN "RgA" THEN 70&lt;br /&gt;     WHEN "AEY" THEN 70&lt;br /&gt;     WHEN "RwA" THEN 71&lt;br /&gt;     WHEN "AEc" THEN 71&lt;br /&gt;     WHEN "SAA" THEN 72&lt;br /&gt;     WHEN "AEg" THEN 72&lt;br /&gt;     WHEN "SQA" THEN 73&lt;br /&gt;     WHEN "AEk" THEN 73&lt;br /&gt;     WHEN "SgA" THEN 74&lt;br /&gt;     WHEN "AEo" THEN 74&lt;br /&gt;     WHEN "SwA" THEN 75&lt;br /&gt;     WHEN "AEs" THEN 75&lt;br /&gt;     WHEN "TAA" THEN 76&lt;br /&gt;     WHEN "AEw" THEN 76&lt;br /&gt;     WHEN "TQA" THEN 77&lt;br /&gt;     WHEN "AE0" THEN 77&lt;br /&gt;     WHEN "TgA" THEN 78&lt;br /&gt;     WHEN "AE4" THEN 78&lt;br /&gt;     WHEN "TwA" THEN 79&lt;br /&gt;     WHEN "AE8" THEN 79&lt;br /&gt;     WHEN "UAA" THEN 80&lt;br /&gt;     WHEN "AFA" THEN 80&lt;br /&gt;     WHEN "UQA" THEN 81&lt;br /&gt;     WHEN "AFE" THEN 81&lt;br /&gt;     WHEN "UgA" THEN 82&lt;br /&gt;     WHEN "AFI" THEN 82&lt;br /&gt;     WHEN "UwA" THEN 83&lt;br /&gt;     WHEN "AFM" THEN 83&lt;br /&gt;     WHEN "VAA" THEN 84&lt;br /&gt;     WHEN "AFQ" THEN 84&lt;br /&gt;     WHEN "VQA" THEN 85&lt;br /&gt;     WHEN "AFU" THEN 85&lt;br /&gt;     WHEN "VgA" THEN 86&lt;br /&gt;     WHEN "AFY" THEN 86&lt;br /&gt;     WHEN "VwA" THEN 87&lt;br /&gt;     WHEN "AFc" THEN 87&lt;br /&gt;     WHEN "WAA" THEN 88&lt;br /&gt;     WHEN "AFg" THEN 88&lt;br /&gt;     WHEN "WQA" THEN 89&lt;br /&gt;     WHEN "AFk" THEN 89&lt;br /&gt;     WHEN "WgA" THEN 90&lt;br /&gt;     WHEN "AFo" THEN 90&lt;br /&gt;     WHEN "WwA" THEN 91&lt;br /&gt;     WHEN "AFs" THEN 91&lt;br /&gt;     WHEN "XAA" THEN 92&lt;br /&gt;     WHEN "AFw" THEN 92&lt;br /&gt;     WHEN "XQA" THEN 93&lt;br /&gt;     WHEN "AF0" THEN 93&lt;br /&gt;     WHEN "XgA" THEN 94&lt;br /&gt;     WHEN "AF4" THEN 94&lt;br /&gt;     WHEN "XwA" THEN 95&lt;br /&gt;     WHEN "AF8" THEN 95&lt;br /&gt;     WHEN "YAA" THEN 96&lt;br /&gt;     WHEN "AGA" THEN 96&lt;br /&gt;     WHEN "YQA" THEN 97&lt;br /&gt;     WHEN "AGE" THEN 97&lt;br /&gt;     WHEN "YgA" THEN 98&lt;br /&gt;     WHEN "AGI" THEN 98&lt;br /&gt;     WHEN "YwA" THEN 99&lt;br /&gt;     WHEN "AGM" THEN 99&lt;br /&gt;     WHEN "ZAA" THEN 100&lt;br /&gt;     WHEN "AGQ" THEN 100&lt;br /&gt; ELSE&lt;br /&gt;     -1&lt;br /&gt; END pdq_value&lt;br /&gt;INTO&lt;br /&gt; v_ret_pdq_value&lt;br /&gt;FROM&lt;br /&gt; sysprocplan p, sysprocedures f&lt;br /&gt;WHERE&lt;br /&gt; p.planid = -2 AND&lt;br /&gt; f.procid = p.procid AND&lt;br /&gt; f.procname = v_proc_name;&lt;br /&gt;&lt;br /&gt;IF v_ret_pdq_value = -1&lt;br /&gt;THEN&lt;br /&gt; RAISE EXCEPTION -746,0,'Could not decode PDQ value. Please check query';&lt;br /&gt;ELSE&lt;br /&gt; RETURN v_ret_pdq_value;&lt;br /&gt;END IF&lt;br /&gt;END FUNCTION;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Updated on Jan 12, 2011: Cosmo noted that the procedure should be declared as a function and asked me to reference him as Cosmo instead of Simon David&lt;br /&gt;&lt;br /&gt;Alterado em 12 de Jan de 2011: O Cosmo referiu que o procedimento deveria ser declarado como função e pediu para ser referido como Cosmo em vez de Simon David&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-8542655163837757023?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/8542655163837757023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=8542655163837757023' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/8542655163837757023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/8542655163837757023'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2011/01/stored-procedure-pdq-pdq-dos.html' title='Stored procedure PDQ / PDQ dos procedimentos'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-226748804640361457</id><published>2010-12-16T23:18:00.003Z</published><updated>2010-12-16T23:49:05.445Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='francês'/><category scheme='http://www.blogger.com/atom/ns#' term='Eric'/><category scheme='http://www.blogger.com/atom/ns#' term='community'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='french'/><category scheme='http://www.blogger.com/atom/ns#' term='comunidade'/><category scheme='http://www.blogger.com/atom/ns#' term='Vercelletto'/><title type='text'>New French Blog / Novo blog em Francês</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;English Version:&lt;br /&gt;&lt;br /&gt;It's a great pleasure to present you another Informix blog. This one is written in French. The author is Eric Vercelletto, which was a colleague at Informix Portugal. Eric has a long history with Informix. We was working at Informix France and decided to join Informix Portugal mainly to participate in a big and complex project several years ago (before I joined Informix). After that we met and worked together on another customer. At the time I was working mainly with tools and he managed all the engine side stuff. When he decided to embrace other challenges outside Informix, I assumed his position at that customer. It was a big challenge for me (I had relatively low experience with the engine) and Eric was a great help. I still use some of his scripts today, and I learned many things with him.&lt;br /&gt;But the world never stops spinning and currently Eric is back on Informix, and he's enthusiastic about it. I wish him all the best and I really hope he is able to share some of his knowledge about Informix with the community.&lt;br /&gt;He decided to write the blog in French since French people like to take care of their language. This is great news for the French community. As for us, non French speaking people we can try our best to understand it. It would be interesting to see it in English also... (just a challenge Eric ;) ). But for now, the important it to keep a steady rate of articles. And I can assure you it's hard. Welcome Eric!&lt;br /&gt;&lt;br /&gt;The blog address is:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://levillageinformix.blogspot.com/"&gt;http://levillageinformix.blogspot.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(something like "the Informix village")&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Versão Portuguesa:&lt;br /&gt;&lt;br /&gt;É um grande prazer poder apresentar-vos um novo &lt;span style="font-style: italic;"&gt;blog&lt;/span&gt; Informix. Desta feita escrito em Francês. O autor é Eric Vercelletto, que foi um colega da Informix Portugal. O Eric tem um longo passado com Informix. Estava a trabalhar na Informix França e decidiu juntar-se à Informix Portugal, pricipalmente para participar num projecto grande e complexo há vários anos atrás (antes de eu ingressar na Informix Portugal). Após isso conhecemo-nos e trabalhámos juntos num outro cliente. Na altura eu trabalhava essencialmente com ferramentas e ele geria o lado do motor.&lt;br /&gt;Quando ele decidiu abraçar outros desafios fora da Informix, assumi a sua posição no cliente. Foi um grande desafio para mim (tinha muito pouca experiência com o motor) e o Eric foi uma grande ajuda. Ainda utilizo alguns dos seus scripts hoje, e aprendi muitas coisas com ele.&lt;br /&gt;Mas o mundo dá voltas e mais voltas e actualmente o Eric está de volta ao Informix, e continua entusiasta. Desejo-lhe tudo de bom e espero sinceramente que ele consiga partilhar algum do seu conhecimento Informix com a comunidade.&lt;br /&gt;Ele decidiu escrever o &lt;span style="font-style: italic;"&gt;blog&lt;/span&gt; em Francês porque os Franceses gostam de cuidar da sua língua. Isto são excelentes notícias para a comunidade Francófona. Quanto a nós, que não dominamos a língua, tentaremos o nosso melhor para o perceber. Era interessante ver o conteúdo também em Inglês (só um desafio Eric... :) ). Mas por agora, o importante é manter um ritmo constante de novos artigos. E posso assegurar que não é fácl. Bem vindo Eric!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;O endereço do &lt;span style="font-style: italic;"&gt;blog&lt;/span&gt; é:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://levillageinformix.blogspot.com/"&gt;http://levillageinformix.blogspot.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(algo como "a aldeia do Informix", o que vindo da Gália, trás boas recordações de criança)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-226748804640361457?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/226748804640361457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=226748804640361457' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/226748804640361457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/226748804640361457'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2010/12/new-french-blog-novo-blog-em-frances.html' title='New French Blog / Novo blog em Francês'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-901698268087030152</id><published>2010-12-16T00:15:00.004Z</published><updated>2010-12-16T00:26:39.708Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='retorno do investimento'/><category scheme='http://www.blogger.com/atom/ns#' term='study'/><category scheme='http://www.blogger.com/atom/ns#' term='estudo'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='economic'/><category scheme='http://www.blogger.com/atom/ns#' term='return on investment'/><category scheme='http://www.blogger.com/atom/ns#' term='roi'/><category scheme='http://www.blogger.com/atom/ns#' term='forrester'/><title type='text'>Informix ROI webcast</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Português e Inglês&lt;br /&gt;&lt;br /&gt;English version:&lt;br /&gt;&lt;br /&gt;Following the recent announcement of a Forrester study about Informix ROI, a webcast was held on December 13. The replay can be seen here:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.techwebonlineevents.com/ars/eventregistration.do?mode=eventreg&amp;amp;F=1002717&amp;amp;K=4ON"&gt;https://www.techwebonlineevents.com/ars/eventregistration.do?mode=eventreg&amp;amp;F=1002717&amp;amp;K=4ON&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can listen to it in webcast format and also download the slides and sound file.&lt;br /&gt;The presentation was done by Jon Erickson from Forrester and Richard Wozniak who browses through some of the Panther key features.&lt;br /&gt;Be sure to pass this to your company management!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Versão Portuguesa:&lt;br /&gt;&lt;br /&gt;No seguimento do recente anúncio sobre um estudo da Forrester sobre o ROI (&lt;span style="font-style: italic;"&gt;return on investment&lt;/span&gt;) do Informix, foi apresentado um &lt;span style="font-style: italic;"&gt;webcast&lt;/span&gt; no dia 13 de Dezembro. Pode rever esta apresentação aqui:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.techwebonlineevents.com/ars/eventregistration.do?mode=eventreg&amp;amp;F=1002717&amp;amp;K=4ON"&gt;https://www.techwebonlineevents.com/ars/eventregistration.do?mode=eventreg&amp;amp;F=1002717&amp;amp;K=4ON&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pode ouvir/ver em formato &lt;span style="font-style: italic;"&gt;webcast&lt;/span&gt; e também fazer o &lt;span style="font-style: italic;"&gt;download&lt;/span&gt; dos ficheiros com os &lt;span style="font-style: italic;"&gt;slides&lt;/span&gt; e o som.&lt;br /&gt;A apresentação foi feita por Jon Erickson da Forrester e Richard Wozniak que abordou algumas das principais funcionalidades da versão Panther (11.7)&lt;br /&gt;Não deixe de divulgar esta informação aos gestores da sua organização!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024011-901698268087030152?l=informix-technology.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://informix-technology.blogspot.com/feeds/901698268087030152/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024011&amp;postID=901698268087030152' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/901698268087030152'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024011/posts/default/901698268087030152'/><link rel='alternate' type='text/html' href='http://informix-technology.blogspot.com/2010/12/informix-roi-webcast.html' title='Informix ROI webcast'/><author><name>Fernando Nunes</name><uri>http://www.blogger.com/profile/15733748635390133382</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='23' height='32' src='http://4.bp.blogspot.com/_owXf8TIBUXI/S2bpGijdAWI/AAAAAAAAABc/AlV-RTx0M38/S220/fnunes.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024011.post-1099206779029122248</id><published>2010-12-12T23:25:00.002Z</published><updated>2010-12-12T23:59:54.284Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='service'/><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='dns'/><category scheme='http://www.blogger.com/atom/ns#' term='conexão'/><category scheme='http://www.blogger.com/atom/ns#' term='reverse dns'/><category scheme='http://www.blogger.com/atom/ns#' term='informix'/><category scheme='http://www.blogger.com/atom/ns#' term='cache'/><category scheme='http://www.blogger.com/atom/ns#' term='conection'/><title type='text'>Panther: Name service cache</title><content type='html'>This article is written in English and Portuguese&lt;br /&gt;Este artigo está escrito em Inglês e Português&lt;br /&gt;&lt;br /&gt;English version:&lt;br /&gt;&lt;br /&gt;A recent thread in the IIUG mailing list (relative to a reverse DNS issue) reminded me of a new Panther (version 11.7) functionality that was on my list for articles. I've been avoiding many of the bigger and more important features because they will take a lot of time to write about... I hope this one will be shorter.&lt;br /&gt;&lt;br /&gt;Informix needs to read several files or interact with DNS servers each time you try to open a connection. Considering Unix and Linux (Windows is a bit different technically, but not that much conceptually), these are some of the actions the engine must do:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Depending on your host resolution criteria it will probably open the /etc/hosts file to search for your client's IP address. If it's not there it will contact your DNS server in order to request the name associated with the IP address.&lt;br /&gt;Note that all this is done by a system call.&lt;/li&gt;&lt;li&gt;It will access /etc/passwd (or equivalent) to get your user details (HOME dir, password - this is probably stored in another file like /etc/shadow - , user id, group id etc.)&lt;/li&gt;&lt;/ol&gt;The engine must also access /etc/services and /etc/group in other situations.&lt;br /&gt;Depending on your environment these activities can take a bit of time, and require some significant CPU usage. There are systems with high number of connections per second which can naturally transform this into a significant issue.&lt;br /&gt;To give you an example I do regular work on a system that used to receive a very large number of requests from CGI programs. So, each request received by HTTP required a new process on the application server, and a new connection on the database server. They had peaks of tens of requests per second. Currently they're using Fast CGI with noticeable improvements.&lt;br /&gt;Anyway, IBM decided to give us the chance to optimize this by caching previous results (file searches and DNS requests). This is done with the new parameter called NS_CACHE (from Name Service Cache). The format of this $ONCONFIG parameter is:&lt;br /&gt;&lt;br /&gt;host=num_secs,services=num_secs,user=num_secs,group=num_secs&lt;br /&gt;&lt;br /&gt;Each comma separated pair (functionality=num_secs) configures the number of seconds that the engine will cache a query result for that functionality. I'm calling it functionality, because it can be implemented through files or system APIs. The documentation could be clearer, but let's check each one:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;host&lt;br /&gt;This is the host and IP address resolution service. Depending on your system configuration (on most Unixes and Linux this is specified in /etc/nsswitch.conf) it c
