Thursday, December 01, 2016

INFORMIXDIR and files configuration / INFORMIXDIR e configuração de ficheiros

Setting up INFORMIXDIR and instance files, specially in a cluster configuration (original version here: http://informix-technology.blogspot.com/2016/11/informixdir-and-files-configuration.html)


English version
Ok... the article title is a bit confusing, but sometimes so is this subject. I've received a few questions about how to setup the Informix related files, in particular if a cluster (active/passive) configuration is being used. Let's start by listing the files I'm referring to

Files or directories we can configure

  • INFORMIXDIR
    The product installation directory. Note that different instances can share a single $INFORMIXDIR
  • ONCONFIG file
    This is the instance configuration file. All the parameters for instance initialization and subsequent startups are contained in this file. This file is pointed to by the environment variable $ONCONFIG, but the variable only specifies the file name. The file location must be $INFORMIXDIR/etc
  • online.log
    This is the instance log file where the instances messages will be written. The file can have the name we want and it's location is defined by an $ONCONFIG parameter (MSGPATH)
  • SQLHOSTS
    This is the file containing the names, addresses, ports, protocols and options of each listener. By default it's $INFORMIXDIR/etc/sqlhosts, but it can be overridden by the value in $INFORMIXSQLHOSTS variable (full PATH)
  • chunks
    The chunks are Informix datafiles. In the good old days, when everybody was using RAW devices, the recommendation used to be creating symbolic links that would point to the raw devices. I still like to do this, even when using cooked files (datafiles in operating system file system). It gives us an extra flexibility in case we need to move the physical files
  • console file
    This file is somehow "ignored" by many customers. It's a file where some messages are written. We don't normally need to check it. The full path is defined by an $ONCONFIG parameter (CONSOLE)
  • Restore point dir
    This is a file system location (directory) where Informix write some information during upgrades. It's defined by an $ONCONFIG parameter (RESTORE_POINT_DIR)
  • LTAPEDEV/TAPEDEV
    These are the locations for logical log backup and instance backups, defined by the $ONCONFIG parameters with the same names. They can be defined with a special value ("/dev/null") if you want/need to discard the objects. Note that LTAPEDEV requires an instance restart if we're changing it to/from "/dev/null". Normally they'll point to a directory in the file system (or a file on very old Informix versions). If we're using a storage manager, their value is not really important (unless we're referring to LTAPEDEV and it has the "/dev/null" value - this is not compatible with the use of onbar and a storage manager)
  • BAR activity log
    The onbar activity log. Defined by the $ONCONFIG parameter BAR_ACT_LOG
  • BAR debug log
    The onbar debug log. Only used for debugging and pointed to by the $ONCONFIG parameter BAR_DEBUG_LOG
  • IXBAR file
    The very important file which contains the onbar catalog. This is defined by an $ONCONFIG parameter (BAR_IXBAR_PATH). The default is $INFORMIXDIR/etc/ixbar.N where "N" is the instance SERVERNUM
  • BAR BSA library path
    The full location of the XBSA library we're using, if we setup a storage manager. The location will be dependent on the storage manager Informix client installation. The value is defined in the BAR_BSA_LIBPATH $ONCONFIG parameter
  • Database Library Path
    The location where we allow the engine to load dynamic libraries for extensibility purposes. The location is defined by the $ONCONFIG parameter DB_LIBRARY_PATH
  • Data Replication lost and found
    Base file name for HDR environments to store transactions committed on a primary server that were not successfully transmitted to the secondary server. This is defined by the $ONCONFIG parameter DRLOSTFOUND
  • Dump directory
    The directory where shared memory dumps and diagnostic files will be written. This must be a filesystem location with enough storage for a few shared memory dumps (assuming the instance is configured to create them in case of failure). The location is defined by an $ONCONFIG parameter (DUMPDIR)
  • Alarmprogram
    The script/program to run when certain events happen. The location is defined by an $ONCONFIG parameter (ALARMPROGRAM)
  • System alarm program
    The system alarm program/script. This one is called when serious (crash/assert fails) happen and is defined by an $ONCONFIG parameter (SYSALARMPROGRAM)
  • Java Virtual Processor log
    File that takes trace outputs and stack dumps from the java virtual CPUs. Defined in the $ONCONFIG parameter JVPLOGFILE
  • ADTCFG file
    This is the file controlling the auditing feature. It exists in $INFORMIXDIR/aaodir. After chnages are made the system creates an adtcfg.N where N is the value of SERVERNUM.

Aspects to consider

The INFORMIXDIR

The first thing to consider is the $INFORMIXDIR. Many people usually use /opt/informix, or /usr/informix and install the product there. This is not the best option because when we're planning an upgrade we need to have both the old and the new version available. Some customers solve this by installing the product in a directory that contains the version (let's assume "my" standard) like /usr/informix/srvr1210fc7w1 and then create a symbolic link /usr/informix/server and point it to the version they want to use. This may work for a single instance, but becomes problematic if you use several instances and you want the option to upgrade them at different moments

The existence of a cluster configuration raises another problem. Should you install the product on both nodes, or just in a single cluster controlled path that moves between nodes? There are people who defend the idea of a single INFORMIXDIR installation which is moved to the active node. But again, if you have several instances and you consider spreading them across the two nodes (all in a single node if the hardware fails or needs maintenance) that won't fulfill the requirements. A single $INFORMIXDIR moving between nodes simplifies other issues. If you have an INFORMIXDIR on node A, and an INFORMIXDIR on node B, you'll have two $ONCONFIG, ADTCFGs and maybe a few others that you cannot define their full path.

Another aspect related to this, is that if you configure role separation (a very nice and free Informix feature that allows different people to have different security functions in an Informix instance), if you have a single INFORMIXDIR for several instances, you can't separate the roles differently across the instances. In most cases this would not be an issue. Actually most customers don't have enough people managing the database to be able to separate the roles even for a single instance.

The log files

The log files, like online.log, onbar activity and debug logs etc. sometimes have defaults that are inside $INFORMIXDIR, and even when the defaults are not like that, too often I find customers that put them there. The problem in doing that is simple. When we upgrade, the logs history becomes "broken" because now you have logs inside the old and the new $INFORMIXDIR.

Another obvious problem with logs comes from cluster environments where an instance moves from node A to node B. If the logs are not pointing to a common cluster resource you'll have parts of the logs spread across the nodes.
On the other hand, if the logs are pointing to a common location we loose track of where the instance was started. And for problem analysis this is important (more about this in a later article).

The chunks

The decision here is if we use symbolic links or not. This used to be much more important because sometimes a change in the raw devices would mean a different path. And we couldn't change the path of the chunks as the engine knows them. In modern systems and Informix versions, we can create the raw devices with specific names (so if we need to rebuild or change some options we can re-use the old names) and we can change the path name of the chunks by doing a "fake" external backup/restore with chunk renaming.

The scripts

Usually the instances require a set of scripts maintained by the DBAs. Once again, too many often I see these scripts inside the $INFORMIXDIR, or $INFORMIXDIR/bin. As mentioned earlier, this is not a good practice because during upgrades it would be a mess, and the same happens if you run several instances on the same box and consider having different INFORMIXDIRs (one reason would be that they can be in different versions).

The tricky part is that sometimes the scripts must be customized for each instance. And another problem (again) arises from the use of a cluster environment. In that case you may need to keep as many copies of the scripts as nodes you're running. Eventually, if the cluster allows you to have a common mount point or a cluster filesystem (like GPFS, or GFS/GFS2) you may have a solution. For situations where a single script must have different configurations for different instances, we can use a "case/esac" structure in SHELL conditioned by $INFORMIXSERVER. This is a possibility for example to implement a common alarm program which may need to have different backup configurations for example.

Recommendations

INFORMIXDIR

I usually install the product in locations that clearly indicate the version (/usr/informix/srvr1210fc7w1). But then I use a script (ixvirtdir) to create a "special" INFORMIXDIR for each specific instance. The script takes a few parameters like the existing INFORMIXDIR and the new one which I normally define with a suffix equal to the instance name. Additionally we can provide operating system groups that will be used as DBSA, AAO and DBSSO for role separation. The "special" INFORMIXDIR will be a new directory where inside I'll create a link to each original INFORMIXDIR's sub-directory with a few exceptions. Let's see an example:

castelo@primary:informix-> echo $INFORMIXSERVER $INFORMIXDIR
castelo /opt/informix/srvr1210fc7w1_castelo
castelo@primary:informix-> pwd
/opt/informix/srvr1210fc7w1_castelo
castelo@primary:informix-> ls -l
total 84
drwxrwx--- 2 informix ixaao    4096 Aug 18 02:46 aaodir
lrwxrwxrwx 1 informix informix   31 Nov 13 03:21 bin -> /opt/informix/srvr1210fc7w1/bin
drwxrwx--- 2 informix ixdbsso  4096 Aug  1 13:44 dbssodir
lrwxrwxrwx 1 informix informix   32 Nov 13 03:21 demo -> /opt/informix/srvr1210fc7w1/demo
lrwxrwxrwx 1 informix informix   31 Nov 13 03:21 doc -> /opt/informix/srvr1210fc7w1/doc
drwxrwxr-x 4 informix ixdbsa   4096 Aug 23 11:10 etc
lrwxrwxrwx 1 informix informix   34 Nov 13 03:21 extend -> /opt/informix/srvr1210fc7w1/extend
lrwxrwxrwx 1 informix informix   31 Nov 13 03:21 gls -> /opt/informix/srvr1210fc7w1/gls
lrwxrwxrwx 1 informix informix   33 Nov 13 03:21 gskit -> /opt/informix/srvr1210fc7w1/gskit
lrwxrwxrwx 1 informix informix   32 Nov 13 03:21 help -> /opt/informix/srvr1210fc7w1/help
lrwxrwxrwx 1 informix informix   32 Nov 13 03:21 incl -> /opt/informix/srvr1210fc7w1/incl
lrwxrwxrwx 1 informix informix   31 Nov 13 03:21 isa -> /opt/informix/srvr1210fc7w1/isa
lrwxrwxrwx 1 informix informix   31 Nov 13 03:21 lib -> /opt/informix/srvr1210fc7w1/lib
lrwxrwxrwx 1 informix informix   35 Nov 13 03:21 license -> /opt/informix/srvr1210fc7w1/license
lrwxrwxrwx 1 informix informix   31 Nov 13 03:21 msg -> /opt/informix/srvr1210fc7w1/msg
lrwxrwxrwx 1 informix informix   38 Nov 13 03:21 properties -> /opt/informix/srvr1210fc7w1/properties
lrwxrwxrwx 1 informix informix   35 Nov 13 03:21 release -> /opt/informix/srvr1210fc7w1/release
lrwxrwxrwx 1 informix informix   31 Nov 13 03:21 SDK -> /opt/informix/srvr1210fc7w1/SDK
lrwxrwxrwx 1 informix informix   32 Nov 13 03:21 snmp -> /opt/informix/srvr1210fc7w1/snmp
drwxrwx--- 3 informix ixdbsa   4096 Aug  1 13:44 ssl
drwxrwx--- 2 informix informix 4096 Aug 23 11:10 tmp


So, INFORMIXDIR is /opt/informix/srvr1210fc7w1_castelo. "castelo" is the INFORMIXSERVER which acts as a suffix. Most sub-directories are just links to the base product installation. The exceptions are "aaodir", "dbssodir", "etc", "ssl" and "tmp". These are real directories for several reasons. In a cluster configuration, the "virtual" INFORMIXDIR would be on a cluster resource and the base product installation would either also be in a cluster resource (single instance on the machine, or if the decision to move to another node would imply move all the instances), or a local product installation. Note that by creating that list of sub-directories as real directories, I'm isolating everything that can vary from one instance to the other. Note also that these sub-directories would not contain very large content, with the possible exception for "tmp" if it's defined as the DUMPDIR for example.
With this method we can achieve maximum flexibility and instance isolation in the following situations:
  1. Several instances on a single machine
  2. Cluster environments even with several instances that don't necessarily move from one node to another as a group
  3. Full role separation at each instance level, allowing for different groups for different instances

Informix user home

The home of the informix user (let's assume /home/informix) will contain two directories: "bin" and "etc". In the "bin" directory I put every script I use for the instances management including the alarmprogram.sh. In the "etc" I put all the configuration scripts/files like:
  • sqlhosts (single file per machine) facilitates configurations for distributed queries etc.
  • The configuration file (infx_env.lst) for my script to position across the instances environment (setinfx)
  • The configuration file for the alarmprogram.sh (alarm_conf.sh) where each instance specific configurations are defined in a case/esac structure
This setup does not solve the cluster problems. In a cluster environment, assuming all the nodes may have some instance(s) running at the same time, this structure must be replicated across nodes. If however you move all the instances as a single block, the /home/informix could be a cluster resource (or at least the two sub-directories - /home/informix/etc and /home/informix/bin ). In any case the "bin" directory must be placed in the PATH environment variable.
We should also try to avoid having two copies of configuration files like $INFORMIXSQLHOSTS, and we may consider using symbolic links to a shared location.

Log files and others

Things like online.log, onbar activity and debug files, ixbar etc should be put on a cluster resource that moves with each instance. On a non cluster environment these files can be created inside a informix's HOME sub-directory like /home/informix/logs and /home/informix/conf.
Even if the files are created inside a cluster resource, specific for each instance I prefer to create the files with a suffix like INFORMIXSERVER (e.g. online_${INFORMIXSERVER}.log, ixbar.${INFORMIXSERVER} etc.
It's important to underline the importance of having a single IXBAR file in the cluster. Otherwise you'll have the catalog information spread across the cluster and it will make the restore process impossible.

Chunks and links

For the chunks I still prefer to use symbolic links. These can point to cooked files or RAW devices. Both the links and the files (RAW or cooked) must be configured as a cluster resource on a cluster environment.

DUMP dirs

There are a few directories that are used sporadically but are very important. One is the configuration of the parameter DUMPDIR where the assert fail files are written. Somehow similar are the parameters RESTORE_POINT_DIR, DRLOSTFOUND and PLOG_OVERFLOW_PATH.
These are important for certain activities, but typically once the issue is solved the files can and are removed. So, it's important that their locations point to large enough and existing directories, but it's not very relevant if they're specific for each instance or a single cluster location.


Versão Portuguesa
OK... o título do artigo é um pouco confuso, mas por vezes também este assunto o é. Tenho recebido algumas questões sobre como configurar os ficheiros usados pelo Informix, em particular num ambiente de cluster (ativo/passivo). Comecemos por enunciar uma lista de ficheiros a que me estou a referir.

Ficheiros ou diretórios que podemos configurar

  • INFORMIXDIR
    O diretório de instalação do produto. Note-se que diferentes instâncias podem partilhar um único $INFORMIXDIR
  • Ficheiro ONCONFIG
    É o ficheiro de configuração da instância. Todos os parâmetros para a inicialização da instância e sub-sequentes arranques estão contidos neste ficheiro. A variável de ambiente $ONCONFIG aponta para o nome do ficheiro, sendo que a sua localização é forçosamente $INFORMIXDIR/etc
  • online.log
    O ficheiro de log onde as mensagens da instância são escritas. O ficheiro pode ter o nome e localização que quisermos e isto é definido pelo parâmetro MSGPATH no $ONCONFIG
  • SQLHOSTS
    O ficheiro que contém os nomes, endereços, portos TCP, protocolos e opções de cada listener. Por omissão a sua localização é $INFORMIXDIR/etc/sqlhosts, mas pode ser redefinido pelo valor da variável de ambiente $INFORMIXSQLHSOSTS (caminho completo)
  • chunks
    Os chunks são os "ficheiros" de dados do Informix. Nos bons velhos tempos em que toda a gente usava dispositivos RAW, a recomendação era utilizar links simbólicos que apontariam para esses dispositivos. Eu ainda gosto desta ideia, mesmo que se utilizem ficheiros em filesystem (cooked files). Esta opção oferece uma flexibilidade extra caso necessitemos de mover os ficheiros físicos
  • Ficheiro "console"
    Este ficheiro costuma ser de alguma forma ignorado por muitos clientes. É um ficheiro onde algumas mensagens são escritas. Normalmente não é muito necessário verificar estas mensagens. O caminho completo é definido por um parâmetro do $ONCONFIG (CONSOLE)
  • Restore point dir
    É uma localização em filesystem (diretório) onde o Informix escreve alguma informação durante os upgrades. É definido por um parâmetro do $ONCONFIG (RESTORE_POINT_DIR)
  • LTAPEDEV/TAPEDEV
    São as localizações para o backup dos logical logs e backup de instâncias, definidos pelos parâmetros de $ONCONFIG com o mesmo nome. Podem ser definidos com um valor especial ("/dev/null") se quisermos descartar os objetos. Note-se que o LTAPEDEV requer um restart da instância para mudar de/para "/dev/null". Normalmente apontam para um diretório no file system (ou em versões muito antigas do Informix apontarão para ficheiros). Se usarmos um storage manager o seu valor não é muito importante (exceto se o LTAEPDEV estiver para "/dev/null" - isto não é compatível com a utilização de um storage manager), visto que na realidade os objetos não serão guardados nesta localização, mas antes enviados para o storage manager.
  • Log de atividade do onbar
    Log de atividade de backup usando o onbar. Definido por um parâmetro do $ONCONFIG (BAR_ACT_LOG)
  • Log de debug do onbar
    Localização onde é escrito o debug do onbar. Apenas é usado se ativarmos o debug. O seu valor é definido por um parâmetro do $ONCONFIG (BAR_DEBUG_LOG)
  • Ficheiro IXBAR
    Um ficheiro muito importante que contém o catálogo do onbar. É definido pelo parâmetro BAR_IXBAR_PATH do $ONCONFIG. Por omissão é $INFORMIXDIR/etc/ixbar.N onde "N" é o valor do parâmetro SERVERNUM (único para cada instância)
  • Caminho da biblioteca BAR BSA
    O caminho completo para a biblioteca XBSA que estamos a usar, caso estejamos a integrar com um storage manager. A localização será dependente da instalação do cliente Informix do storage manager. O valor é definido pelo parâmetro BAR_BSA_LIBPATH do $ONCONFIG
  • Database Library Path
    A localização onde permitimos que o motor carregue bibliotecas dinâmicas para fins de extensibilidade. O valor é definido pelo parâmetro DB_LIBRARY_PATH do $ONCONFIG
  • Data Replication lost and found
    Nome base onde os ambientes HDR podem guardar transações committed no servidor primário que não foram transmitidas com sucesso para o servidor secundário. Definido pelo parâmetro DRLOSTFOUND do $ONCONFIG
  • Diretório de dumps
    Directório onde os dumps de memória partilhada e ficheiros de diagnóstico serão criados. Tem de ser uma localização com espaço suficiente para alguns dumps de memória (assumindo que a instância está configurada para os gerar em caso de falhas). A localização é definida pelo parâmetro "DUMPDIR" do $ONCONFIG
  • Alarmprogram
    O script ou programa que é executado pelo motor quando certos eventos acontecem. A localização é definida pelo parâmetro ALARMPROGRAM do $ONCONFIG
  • System alarm program
    Semelhante ao alarmprogram mas para ser chamado em casos de falhas graves (quedas do motor ou assert fails). Definido pelo parâmetro SYSALARMPROGRAM do $ONCONFIG
  • Log dos processadores virtuais para Java
    Ficheiro que recebe os "traces" e "dumps" de "stack" do JVPs. Definido pelo parâmetro JVPLOGFILE do $ONCONFIG
  • ADTCFG
    Ficheiro de configuração do audit. Existe no diretório $INFORMIXDIR/aaodir e depois de efetuadas alterações será criado o ficheiro adtcfg.N onde N é o valor do parâmetro $SERVERNUM

Aspetos a considerar

  O INFORMIXDIX

A primeira coisa a considerar é o valor de $INFORMIXDIR. Muitas pessoas simplesmente usam /opt/informix ou /usr/informix e instalam aí o produto. Isto não é a melhor opção pois durante os upgrades devemos ter disponíveis ambas as versões (antiga e nova). Em alguns casos resolvem isto instalado o produto num diretório que contém a versão (vamos assumir o "meu" standard) como /usr/informix/srvr1210fc7w1 e depois criam um link simbólico do tipo /usr/informix/server que aponta para a instalação que pretendem usar. Isto pode funcionar quando existe apenas uma instância no servidor, mas torna-se complicado quando há várias instalações e se pretende a opção de fazer upgrades em alturas diferentes.

A existência de um cluster levanta ainda mais um problema. Deveremos instalar o produto em ambos os nós ou apenas numa localização controlada pelo cluster e que é movida entre os nós? Há quem defenda a ideia de uma única instalação (INFORMIXDIR) que é movida para o nó que se quer "ativo". Mas novamente, se temos várias instâncias e consideramos dividir a carga entre os nós (apenas tendo as instâncias todas num só nó se o outro estiver indisponível), uma só instalação não responde aos requisitos. Ter um só $INFORMIXDIR para cada instância que é movido dentro do cluster simplifica outros aspetos. Se temos um INFORMIXDIR no nó A, e outro INFORMIXDIR no nó B, teremos dois ficheiros $ONCONFIG, ADTCFG e eventualmente outros cujo caminho não pode ser mudado (só o nome).

Outro aspeto relacionado com isto, é se configurarmos a separação de funções (role separation), que é uma excelente funcionalidade do Informix (sem custos adicionais) que permite que diferentes grupos de pessoas tenham acesso a diferentes funções numa instância Informix, então um só INFORMIXDIR para várias instâncias não permite fazer também a segregação por instância. Embora na realidade a maioria dos clientes não tenha pessoas suficientes para a separação de uma única instância...

Ficheiros de log

Os ficheiros de log, como o online.log, o de actividade do onbar, o de debug do onbar etc. por vezes têm valores por omissão dentro do $INFORMIXDIR, e mesmo quando assim não é, muitas vezes encontro clientes que os colocam lá. O problema de fazer isto é simples. Quando fazemos um ugrade o histórico dos ficheiros perde-se, pois parte fica no $INFORMIXDIR antigo e outra parte no novo (ou obriga a cópia para que tal não aconteça)

Outro problema óbvio com os logs deriva de ambientes de cluster onde as instâncias "saltitam" entre o nó A e o nó B. Se os logs não estiverem a apontar uma uma localização comum nos dois nós, acabamos com partes dos ficheiros no nó A e outra parte no nó B.

Por outro lado, se os logs estiverem a apontar para uma localização comum perdemos o registo de onde estava a instância em cada momento (o que pode ser conveniente para despiste de problemas - mais sobre isto num futuro artigo)

Os chunks

Aqui a decisão é se usamos links simbólicos ou não. Isto era muito mais importante antigamente porque por vezes alguma alteração nos raw devices implicava um caminho diferente e não era possível trocar o nome dos chunks pelo qual o motor os conhece. Em ambientes modernos e versões recentes do Informix, podemos criar os raw devices com os nomes que quisermos (se necessitarmos de reconstruir ou mudar opções podemos re-utilizar os nomes), e também podemos mudar os caminhos como o Informix os conhece através de um falso backup/restore externo.

Os scripts

Normalmente as instâncias requerem um conjunto de scripts mantidos pelos DBAs. Mais uma vez, vezes demais eu vejo estes scripts dentro do $INFORMIXDIR ou $INFORMIXDIR/bin. Como mencionado atrás isto não é uma boa prática, pois durante os upgrades torna-se uma confusão, e o mesmo se passa se necessitarmos de várias instâncias no mesmo servidor e pensarmos em ter vários $INFORMIXDIR (bastando para isso que estejam em versões diferentes)

O difícil pode ser que alguns scripts podem ter se ser adaptados para cada instância. E novamente a existência de um cluster pode trazer problemas. Neste caso poderemos ter de manter tantas cópias quantos nós existam no mesmo. Se porventura o cluster permitir algum tipo de sistema de ficheiros partilhado (GPFS ou GFS/GFS2 por exemplo), poderá haver solução para isso.
Os casos em que um só script tem de estar adaptado a várias instâncias poderemos usar uma estrutura "case/esac" dentro do script, cujo condicionamento terá por base o valor de $INFORMIXSERVER. Podemos usar isto por exemplo para ter um "alarmprogram" comum, que pode ter por exemplo diferentes tipos de configuração de backups.

Recomendações

INFORMIXDIR

Normalmente instalo o produto numa localização que indique claramente a versão (/usr/informix/srvr1210fc7w1), mas depois utilizo um script (ixvirtdir) para criar um $INFORMIXDIR "especial" para cada instância. O script recebe alguns parâmetros como o $INFORMIXDIR existente (da instalação) e o novo (que normalmente defino com um sufixo igual ao INFORMIXSERVER). Opcionalmente posso dar os grupos de sistema operativo a que correspondem os DBSA, AAO e DBSSOs para a separação de funções.
O INFORMIXDIR "especial" será um novo diretório onde serão criados links simbólicos para os sub-diretórios existentes dentro de $INFORMIXDIR, com algumas exceções. Vejamos um exemplo:

castelo@primary:informix-> echo $INFORMIXSERVER $INFORMIXDIR
castelo /opt/informix/srvr1210fc7w1_castelo
castelo@primary:informix-> pwd
/opt/informix/srvr1210fc7w1_castelo
castelo@primary:informix-> ls -l
total 84
drwxrwx--- 2 informix ixaao    4096 Aug 18 02:46 aaodir
lrwxrwxrwx 1 informix informix   31 Nov 13 03:21 bin -> /opt/informix/srvr1210fc7w1/bin
drwxrwx--- 2 informix ixdbsso  4096 Aug  1 13:44 dbssodir
lrwxrwxrwx 1 informix informix   32 Nov 13 03:21 demo -> /opt/informix/srvr1210fc7w1/demo
lrwxrwxrwx 1 informix informix   31 Nov 13 03:21 doc -> /opt/informix/srvr1210fc7w1/doc
drwxrwxr-x 4 informix ixdbsa   4096 Aug 23 11:10 etc
lrwxrwxrwx 1 informix informix   34 Nov 13 03:21 extend -> /opt/informix/srvr1210fc7w1/extend
lrwxrwxrwx 1 informix informix   31 Nov 13 03:21 gls -> /opt/informix/srvr1210fc7w1/gls
lrwxrwxrwx 1 informix informix   33 Nov 13 03:21 gskit -> /opt/informix/srvr1210fc7w1/gskit
lrwxrwxrwx 1 informix informix   32 Nov 13 03:21 help -> /opt/informix/srvr1210fc7w1/help
lrwxrwxrwx 1 informix informix   32 Nov 13 03:21 incl -> /opt/informix/srvr1210fc7w1/incl
lrwxrwxrwx 1 informix informix   31 Nov 13 03:21 isa -> /opt/informix/srvr1210fc7w1/isa
lrwxrwxrwx 1 informix informix   31 Nov 13 03:21 lib -> /opt/informix/srvr1210fc7w1/lib
lrwxrwxrwx 1 informix informix   35 Nov 13 03:21 license -> /opt/informix/srvr1210fc7w1/license
lrwxrwxrwx 1 informix informix   31 Nov 13 03:21 msg -> /opt/informix/srvr1210fc7w1/msg
lrwxrwxrwx 1 informix informix   38 Nov 13 03:21 properties -> /opt/informix/srvr1210fc7w1/properties
lrwxrwxrwx 1 informix informix   35 Nov 13 03:21 release -> /opt/informix/srvr1210fc7w1/release
lrwxrwxrwx 1 informix informix   31 Nov 13 03:21 SDK -> /opt/informix/srvr1210fc7w1/SDK
lrwxrwxrwx 1 informix informix   32 Nov 13 03:21 snmp -> /opt/informix/srvr1210fc7w1/snmp
drwxrwx--- 3 informix ixdbsa   4096 Aug  1 13:44 ssl
drwxrwx--- 2 informix informix 4096 Aug 23 11:10 tmp

Portanto, o INFORMIXDIR é /opt/informix/srvr1210fc7w1_castelo. "castelo" é o INFORMIXSERVER que atúa como sufixo para se identificar facilmente a que instância pertence. A maioria dos sub-diretórios dentro do $INFORMIXDIR são apenas links simbólicos para a instalação base do produto. As exceções são "aaodir", "dbssodir", "etc", "ssl" e "tmp". Estes são criados como sub-diretórios por várias razões. Num ambiente cluster o INFORMIXDIR "virtual" pode ser um recurso de cluster e a instalação base seria ou um recurso de cluster (no caso se haver apenas uma instância, ou se a movimentação for feita em bloco), ou uma instalação local em cada nó. Note-se que ao criar aquela lista específica de sub-diretórios como sub-diretórios reais, estou a isolar tudo o que pode variar de uma instância para outra. Note-se também que tipicamente estes diretórios não deverão requerer muito espaço, com a possível exceção do "tmp" se estiver definido como DUMPDIR por exemplo.
Com este método podemos alcançar o máximo de flexibilidade e isolamento das instâncias para as seguintes situações:
  1. Várias instâncias num só servidor
  2. Ambiente de cluster, mesmo com várias instâncias que não sejam necessariamente movidas em bloco para outro(s) nós
  3. Completa separação de papéis em cada instância, permitindo diferentes grupos para diferentes instâncias

$HOME do utilizador Informix

A $HOME do utilizador informix (vamos assumir /home/informix) deverá conter duas diretorias:
"bin" e "etc".  Na "bin", coloco todos os scripts que utilizo para gestão das instâncias, incluindo o alarmprogram.sh. Na "etc" coloco todos os ficheiros ou scripts de configuração como:
  • sqlhosts (ficheiro único por máquina) facilita as configurações para queries distribuídas etc.
  • Ficheiro de configuração do meu script que permite posicionar o ambiente de cada instância (setinfx)
  • Ficheiro de configuração do alarmprogram.sh onde cada secção específica para cada instância é permitido por uma estrutura case/esac
Esta configuração não resolve os problemas de cluster. Num ambiente de cluster, assmindo que todos os nós podem ter alguma(s) instãncia(s) a correr ao mesmo tempo a estrutura da $HOME do informix tem de ser replicada pelos nós. No entanto se mover as instâncias em bloco, o diretório pode ser um recurso de cluster (ou pelo menos as duas referidas sub-diretorias). Em qualquer caso o "bin" tem de ser colocado na variável de ambiente $PATH.
Deve ser evitada a duplicação dos ficheiros de configuração (um por cada nó do cluster), nomeadamente do $INFORMIXSQLHOSTS, para que baste alterar num só nó. Uma hipótese para isto seria criar links simbólicos para um ficheiro num recurso de cluster

Log files and others

Coisas como o online.log, ficheiros de atividade e debug do onbar, ixbar.* etc. devem ser colocados num recurso de cluster que seja movido com a instância. Num ambiente não cluster estes ficheiros podem ser colocados por exemplo num sub-diretório da $HOME do informix como /home/informix/logs e /home/informix/conf
Mesmo que os ficheiros sejam criados num recurso de cluster associado à instâncias, prefiro criá-los com um sufixo como $INFORMIXSERVER (ex: online_$INFORMIXSERVER.log, ixbar.$INFORMIXSERVER etc.
É importante sublinhar a importância de ter apenas um IXBAR no cluster. Caso contrário iremos acabar com o catálogo espalhado pelo cluster o que tornará o processo de restore muito difícil ou impossível.

Chunks e links

Para os chunks ainda continuo a preferir usar links simbólicos. Estes podem apontar para cooked files ou RAW. Tantos os links como os ficheiros (RAW ou cooked) devem ser configurados como um recurso de cluster.

Diretórios de DUMP

Existem alguns diretórios que só são usados esporadicamente mas que são muito importantes. Um é usado na configuração do parâmetro DUMPDIR, onde os ficheiros de assert fails são escritos. De alguma forma semelhantes são os parâmetros RESTORE_POINT_DIR, DRLOSTFOUND e PLOG_OVERFLOW_PATH.
Estes são importantes em certas ocasiões ou actividades, mas normalmente após resolvido o problema os ficheiros podem ser removidos. Portanto, é importante que as suas localizações tenham espaço suficiente e sejam diretórios existentes, mas não é assim tão relevante se são específicos de uma instância ou uma só localização em cluster.

Tuesday, October 11, 2016

ixtempuse news / novidades sobre o ixtempuse

Some slight changes in ixtempuse script (original version here: http://informix-technology.blogspot.com/2016/10/ixtempuse-news-novidades-sobre-o.html)


English version
A few weeks ago I announced the availability of a new script that allows a DBA to see which sessions are consuming temporary space. After release I received some feedback about it's use which triggered some changes and /or thoughts.  Specifically users faced these two issues:

  1. The script didn't work in version 9.40
    After some investigation I noticed I was using a column in one of the sysmaster view which didn't exist in version 9.40. I managed to use a workaround, but after that I've found another issue when I tried to retrieve the page size of a dbspace. I was getting it from a column on the sysdbstab view, but because we only introduced the ability to have chunks of different pagesizes in V10 the column didn't exist in previous versions
  2. The script didn't run when it was most needed: when the temporary dbspaces are full
    At first glance this seemed a very short sight on the way I created the script. In fact I need to create a temporary table and those will be created in the temporary dbspaces. If they're full I may have a problem. But further investigation showed the engine moves those table creation to other dbspaces. The issue seems to be the execution of the script on secondary servers when the temporary dbspaces are full.
To solve issue 1) above I did some changes in the script. It tries to adapt to the version currently being used. The solution for problem 2) is more complex. It's not feasible to do the script without the temporary tables. It could be possible but it would be very difficult. As already explained, the script should run on primary/standard servers because the engine will shift the temporary tables location to the dbspace holding a database or to rootdbs (in the case of the script it will be rootdbs as it's connecting to sysmaster). For secondary servers, this shift is not possible. The only workaround I can think of requires a "trick" and some planning in advance: A DBA can create a very small temporary dbspace (10-50MB is more than enough) without adding it to the list of dbspaces in DBSPACETEMP. And then export DBSPACETEMP=newtinydbspace to run the script. Because we're not adding it to the DBSPACETEMP $ONCONFIG parameter, it will not be used for the session's work and will be reserved for the script usage when needed. It's not a pretty solution, but it's the only I can think about currently.

Meanwhile I received some interesting feedback and I think we can see a solution for the base problem in future versions. We have to wait and see, but I really hope this script will become nearly useless in the future, which as weird as it sounds is actually a very good thing!

The new version of the script is available in the same place:
https://github.com/domusonline/InformixScripts/tree/master/scripts/ix



Versão Portuguesa
Há algumas semanas atrás anunciei a disponibilidade de um script que permite ao DBA verificar quais as sessões que estão a consumir espaço temporário. Depois disso recebi feedback sobre a sua utilização que suscitaram algumas alterações e análises. Especificamente os utilizadores depararam-se com os dois problemas seguintes::
  1. O script não funcionava na versão 9.40
    Na verdade o script não era suposto funcionar, dado que não foi testado em versões sem suporte. Mas após alguma investigação verifiquei que estava a utilizar uma coluna numa das views da sysmaster. Consegui recorrer a outra forma de efetuar a query mas rapidamente bati noutra coluna que também não existia (estava a ver o tamanho da página de um dbspace numa coluna da view sysdbstab, mas como só introduzimos a possibilidade de ter dbspaces com diferentes tamanhos de página na V10, a coluna só então foi introduzida)
  2. O script não corria quando era mais necessário: quando os dbspaces temporários estavam cheios
    à primeira vista parecia um erro básico na forma como construí o script. Na verdade eu necessito de criar tabelas temporárias e estas serão criadas nos temporários. Se já estão cheios é natural que tenha um problema. Mas depois de investigar, verifiquei que o motor muda a localização das tabelas temporárias para um dbspace normal (o da BD ou o rootdbs). O problema afinal trata-se da execução do script em servidores secundários quando os temporários estão cheios.
Para resolver o problema 1) acima, efetuei algumas alterações no script. Agora tenta adaptar-se à versão de motor que está a ser usada. A solução para o problema 2) é mais complexa. Não é viável fazer o script sem criar as tabelas temporárias. Não seria impossível mas seria bastante difícil. Como explicado atrás o script correrá em motores primários/standard pois o motor cria as tabelas temporárias para o dbspace onde a BD foi criada ou para o rootdbs (neste caso será sempre o rootdbs uma vez que estamos a ligar-nos à sysmaster). Mas nos servidores secundários esta adaptação não é possível. A única solução que me ocorre requer planeamento antecipado para implementar um "truque". Um DBA poderá criar  um dbspace temporário muito pequeno (10-50MB será mais que suficiente) não o adicionando à lista definida no parâmetro DBSPACETEMP no $ONCONFIG. E depois para a execução do script exportar a variável DBSPACETEMP=dbspacetemp_pequeno. Como não o adicionamos ao DBSPACETEMP do motor ele não será usado pelo trabalho normal das sessões e estará reservado para utilização do script quando necessário. Não é uma solução bonita, mas é a única que me parece possível de momento.

Entretanto recebi algum feedback interessante, e penso que poderemos ter uma solução definitiva para o problema base (saber as sessões que estão a consumir espaço temporário). Teremos de esperar para ver, mas espero que realmente este script venha a ser inútil no futuro, o que por muito estranho que pareça, é uma coisa muito boa!

A nova versão do script está disponível no mesmo endereço:
https://github.com/domusonline/InformixScripts/tree/master/scripts/ix

Saturday, October 01, 2016

Cloud replay and more... / Apresentação da cloud e mais...

Review the Informix on cloud presentation, announcement, tips and something more (original version here: http://informix-technology.blogspot.com/2016/09/cloud-replay-and-more-apresentacao-da.html)


English version
Last Monday we had the webcast about the new Informix on Cloud offering. For those who couldn't attend the live conference, the webcast replay is available in the following address:
http://event.on24.com/wcc/r/1180944/97874EAFB7BAA6C10771A1D273B6BCEA

The official announcement can be found here (EMEA):
http://www-01.ibm.com/common/ssi/ShowDoc.wss?docURL=/common/ssi/rep_ca/9/877/ENUSZP16-0499/index.html&lang=en&request_locale=en

The slides for from the presentation were uploaded to slideshare.net:
http://bit.ly/2d6wqq7

The actual service can be accessed here:
https://console.ng.bluemix.net/catalog/services/informix-on-cloud/

 The main characteristics of this offering are:

  • Users will have full (root) access and will be responsible for managing a Linux server (CentOS)
  • Informix advanced Enterprise Edition will be installed and Informix Warehouse Accelerator will be included (not configured)
  • There will be 4 sizes of server with different resources (CPU, Memory, DISK, Network)
  • The server will be available through public Interner access. It can be configured by the users to participate in a VPN for example
  • No managing, monitoring or backing up services are currently offered. This can change in the future, but currently the customer has total freedom to implement whatever best fits their requirements
  • It works as if a server was rented in the cloud and the customer used their Informix licenses but of course that's not necessary as customers are charged on a monthly base that includes everything, including product support
The lack of backup services is relative issue. IBM and other vendors have several methods for storage use in the cloud. Some solutions could be considered.
Actually something that I personally find interesting is the possibility to run backups to the cloud. Currently Informix already supports it for Amazon S3. But the implementation seems a bit too simplistic. Something I've been trying as an exercise seems more interesting and with a bit more potential: Our backup tool, onbar, interacts with the Storage managers using a standard and open protocol called XBSA. It's possible to create a XBSA library that sends the objects to the cloud. Just a few hours ago I managed to make my first restore  from a previous backup sent to the cloud. It took me less than a week of free time to create this. It currently has less than 1000 lines of codes written by me. And yes, it's incomplete, doesn't have proper error handling or debugging, doesn't manage metadata or an object catalog etc. But it clearly shows it could be a path to cloud storage use for database backups. Additionally some cloud services (like IBM's Bluemix Object Storage) use a standard called SWIFT which makes it relatively easy to support several cloud providers if the library can be configured externally. Hopefully in the future I'll be able to write an article dedicated to this proof of concept.

Versão Portuguesa
Na passada segunda-feira tivemos o webcast sobre a nova oferta de Informix na nuvem. Para quem não pôde assistir em direto, a gravação da conferência está disponível no seguinte endereço:
http://event.on24.com/wcc/r/1180944/97874EAFB7BAA6C10771A1D273B6BCEA

O anúncio oficial pode ser encontrado em (EMEA):
http://www-01.ibm.com/common/ssi/ShowDoc.wss?docURL=/common/ssi/rep_ca/9/877/ENUSZP16-0499/index.html&lang=en&request_locale=en

Os slides da apresentação foram carregados no slideshare.net:
http://bit.ly/2d6wqq7

O serviço propriamente dito pode ser encontrado aqui:
https://console.ng.bluemix.net/catalog/services/informix-on-cloud/

As características principais do serviço são:
  • Os utilizadores terão acesso total (root), e serão responsáveis pela gestão de um servidor Linux  (CentOS)
  • A edição Advanced Enterprise do Informix estará instalada e o Informix Warehouse Accelerator estará disponível para configuração
  • Existem 4 tamanhos para os servidores com diferentes recursos (CPU, memória, disco e rede)
  • O servidor estará acessível pela Internet pública. Poderá ser configurado pelos utilizadores para fazer parte de uma VPN
  • Não são oferecidos serviços de gestão, monitorização ou backup. Estes aspectos poderão vir a ser alterados no futuro, mas neste momento os clientes têm total liberdade para implementar o que quer que seja que complete o que é oferecido agora, conforme as suas necessidades
  • Funciona como se o cliente alugasse um servidor na nuvem e usasse as suas prórpias licenças, embora isso não seja obviamente necessário visto que o serviço é facturado numa base mensal que inclúi a utilização e o suporte do produto
A falta de um serviço de backup é um problema relativo. Tanto a IBM como outros fornecedores têm disponíveis vários métodos de utilização de armazenamento na nuvem. Poderão ser consideradas algumas soluções.
Na verdade, algo que eu pessoalmente acho interessante é a possibilidade de executar backups para a nuvem. O Informix já disponibiliza essa funcionalidade para o serviço S3 da Amazon. Mas a implementação parece um pouco simplista ou limitada (usa o ontape). Algo que tenho estado a testar como exercício parece-me mais interessante e com mais potencial. A nossa ferramenta de backup, o onbar, interage com os storage managers utilizando um protocolo aberto e standards chamado XBSA. É possível criar uma biblioteca XBSA que envie os objetos para a nuvem. Há apenas algumas horas atrás consegui fazer o primeiro restore a partir de um backup para a nuvem. Levei menos de uma semana de ocupação de tempos livres a criar isto. Neste momento tem menos de 1000 linhas de código escrito por mim. E sim, não tem gestão de erros adequada, ou debugging, não gere metadata nem possuí um catálogo de objetos etc. Mas serve para mostrar claramente que este poderia ser um caminho para integração de backups com a nuvem. Por acréscimo, alguns dos serviços de armazenamento na nuvem (como o Object Storage no IBM Bluemix) utilizam um standard chamado  SWIFT . o que tornaria mais fácil suportar vários serviços desde que a biblioteca pudesse ser configurada externamente. Espero no futuro conseguir fazer um artigo dedicado apenas a este tema

Friday, September 30, 2016

Sysadmin during upgrades / Sysadmin durante upgrades

Curious situation related to sysadmin during an upgrade (original version here: http://informix-technology.blogspot.com/2016/09/sysadmin-during-upgrades-sysadmin.html)


English version
Recently at a customer we were testing an upgrade from 11.50.xC7 to 12.10.xC7W1 and it apparently hanged. That's not what you like to see during an upgrade, even in a test environment.
We waited a few minutes and tried to understand what was happening. There was a thread called "convert" that apparently was idle. The thread stack trace apparently didn't change.
The functions showing up in the stack suggested it was trying to connect to a remote server following up what looks to be a call to UPDATE STATISTICS. That was a bit of a surprise.... looking at the online.log it was "hanged" during the "SCHAPI" phase. This is related to sysadmin.
Considering the upgrade didn't look good and it was a test system we decided to kill the engine and use onrestorept to revert back to version 11.50.
Then we decided to run an UPDATE STATISTICS FOR PROCEDURE on sysadmin database and voilá.... hanged again.
So, an UPDATE STATISTICS FOR PROCEDURE on sysadmin got hanged, and apparently that same thing happened during the upgrade. Further investigation led to a simple conclusion. We had created procedures in sysadmin to implement some monitoring tasks. And some of them tried to do remote operations on an engine where we centralize the monitoring data. Just before the upgrade a change was made to the instance $INFORMIXSQLHOSTS so that we "isolated" it from the outside world. This was done by adding some value to the service ports. The consequence of this was that during the upgrade, when it tried to run the UPDATE STATISTICS FOR PROCEDURE it tried to access a non-reachable remote engine. As it was not possible, it hanged some time for each remote instruction. Later tests on 12.10 showed the time it waits for each connection attempt is by default 60s and can be defined by changing the relatively new ONCONFIG parameter INFORMIXCONTIME

This can be easily reproduced. On a version 11.50 engine we create a simple (dumb) procedure:


bica@primary:informix-> onstat -

IBM Informix Dynamic Server Version 11.50.FC7 -- On-Line -- Up 00:30:33 -- 269068 Kbytes


bica@primary:informix-> cat test_remote_proc_stats.sql


CREATE PROCEDURE test_updstats_remote()

DEFINE i INTEGER;

SELECT 1 INTO i FROM stores@test:systables WHERE tabid = 1;

SELECT 2 INTO i FROM somedb@test:systables WHERE tabid = 1;

END PROCEDURE;
bica@primary:informix-> 



bica@primary:informix-> dbaccess sysadmin test_remote_proc_stats.sql

Database selected.

Routine created.

Database closed.

bica@primary:informix->

Database server "test" exists in the $INFORMIXSQLHOSTS, but points to a wrong port. Let's try an upgrade to 12.10.FC7 and see what happens.

From the online.log we get:


01:30:52 IBM Informix Dynamic Server Started.
01:30:52 Requested shared memory segment size rounded from 4308KB to 4796KB

Wed Aug 31 01:30:54 2016

01:30:54 Requested shared memory segment size rounded from 221001KB to 221004KB
01:30:54 Successfully added a bufferpool of page size 2K.

01:30:54 Event alarms enabled. ALARMPROG = '/usr/informix/srvr1210fc7w1/etc/alarmprogram.sh'
01:30:54 Booting Language from module <>
01:30:54 Loading Module
01:30:54 Booting Language from module <>
01:30:54 Loading Module
01:30:59 DR: DRAUTO is 0 (Off)
01:30:59 DR: ENCRYPT_HDR is 0 (HDR encryption Disabled)
01:30:59 Event notification facility epoll enabled.
01:31:00 Trusted host cache successfully built:/etc/hosts.equiv.
01:31:00 CCFLAGS2 value set to 0x200
01:31:00 SQL_FEAT_CTRL value set to 0x8008
01:31:00 SQL_DEF_CTRL value set to 0x4b0
01:31:00 IBM Informix Dynamic Server Version 12.10.FC7W1 Software Serial Number AAA#B000000
01:31:00 Conversion from version 11.50.xC6 Started

[...]

01:31:05 processing sysmaster
01:31:05 *** entity_ver=31 targetVersion=36 indexVersion= 0 ***
01:31:05 *** FromVersion=10 ToVersion=26 entity_ver=31 targetVersion=36 indexVersion=0 ***
01:31:05 *** FromVersion=26 ToVersion=28 entity_ver=31 targetVersion=36 indexVersion=1 ***
01:31:05 *** FromVersion=28 ToVersion=29 entity_ver=31 targetVersion=36 indexVersion=2 ***
01:31:05 *** FromVersion=29 ToVersion=30 entity_ver=31 targetVersion=36 indexVersion=3 ***
01:31:05 *** FromVersion=30 ToVersion=31 entity_ver=31 targetVersion=36 indexVersion=4 ***
01:31:05 *** FromVersion=31 ToVersion=32 entity_ver=31 targetVersion=36 indexVersion=5 ***
01:31:05 *** SQL 1 11.70.xC1 ***
01:31:05 Converting database sysmaster ...
01:31:06 The database sysmaster has been converted successfully.
01:31:06 *** FromVersion=32 ToVersion=33 entity_ver=32 targetVersion=36 indexVersion=6 ***
01:31:06 *** SQL 1 11.70.xC3 ***
01:31:06 Converting database sysmaster ...
01:31:06 The database sysmaster has been converted successfully.
01:31:06 *** FromVersion=33 ToVersion=34 entity_ver=33 targetVersion=36 indexVersion=7 ***
01:31:06 *** SQL 1 12.10.xC1 ***
01:31:06 Converting database sysmaster ...
01:31:06 The database sysmaster has been converted successfully.
01:31:06 *** FromVersion=34 ToVersion=35 entity_ver=34 targetVersion=36 indexVersion=8 ***
01:31:06 *** SQL 1 12.10.xC4 ***
01:31:06 Converting database sysmaster ...
01:31:06 The database sysmaster has been converted successfully.
01:31:06 *** FromVersion=35 ToVersion=36 entity_ver=35 targetVersion=36 indexVersion=9 ***
01:31:06 *** SQL 1 12.10.xC4 ***
01:31:06 processing sysutils

[...]

01:31:17 Conv/rev: calling conversion to 12.10.xC1 ...
01:31:19 Conv/rev: blade conversion to 12.10.xC1 completed
01:31:19 *** FromVersion=6 ToVersion=7 entity_ver=6 targetVersion=7 indexVersion=6 ***
01:31:19 *** BLADE 1 12.10.xC4 ***
01:31:19 Conv/rev: calling conversion to 12.10.xC4 ...
01:31:21 Conv/rev: blade conversion to 12.10.xC4 completed
01:31:21 Conv/rev: Finished conversion for component BLADE
01:31:21 Conv/rev: Started conversion for component SCHAPI
01:31:21 *** numVersions=7 targetVersion=7 ***
01:31:21 *** entity_ver=3 targetVersion=7 indexVersion= 0 ***
01:31:21 *** FromVersion=0 ToVersion=1 entity_ver=3 targetVersion=7 indexVersion=0 ***
01:31:21 *** FromVersion=1 ToVersion=2 entity_ver=3 targetVersion=7 indexVersion=1 ***
01:31:21 *** FromVersion=2 ToVersion=3 entity_ver=3 targetVersion=7 indexVersion=2 ***
01:31:21 *** FromVersion=3 ToVersion=4 entity_ver=3 targetVersion=7 indexVersion=3 ***
01:31:21 *** SCHAPI 1 11.70.xC1 ***
01:31:21 calling schapi_cvr1170_convert
01:31:21 *** FromVersion=4 ToVersion=5 entity_ver=4 targetVersion=7 indexVersion=4 ***
01:31:21 *** SCHAPI 1 11.70.xC3 ***



and it hangs...
Looking into the threads and thread stack:


IBM Informix Dynamic Server Version 12.10.FC7W1 -- Single-User -- Up 00:00:54 -- 266648 Kbytes

Threads:
tid tcb rstcb prty status vp-class name
2 4579d9e8 0 1 IO Idle 3lio* lio vp 0
3 458fd368 0 1 IO Idle 4pio* pio vp 0
4 4591e368 0 1 IO Idle 5aio* aio vp 0
5 4593f368 1d43600 1 IO Idle 6msc* msc vp 0
6 45970368 0 1 IO Idle 7fifo* fifo vp 0
7 45991608 44c1e028 3 sleeping secs: 1 1cpu main_loop()
8 459ed4c0 0 1 running 8soc* soctcppoll
9 459edc98 0 2 sleeping forever 1cpu* soctcplst
10 45a3cc88 44c1e8f0 1 sleeping secs: 1 1cpu flush_sub(0)
11 45a59028 44c1f1b8 1 sleeping secs: 1 1cpu flush_sub(1)
12 45a59368 44c1fa80 1 sleeping secs: 1 1cpu flush_sub(2)
13 45a596a8 44c20348 1 sleeping secs: 1 1cpu flush_sub(3)
14 45a599e8 44c20c10 1 sleeping secs: 1 1cpu flush_sub(4)
15 45a59d28 44c214d8 1 sleeping secs: 1 1cpu flush_sub(5)
16 45ab70e0 44c21da0 1 sleeping secs: 1 1cpu flush_sub(6)
17 45ab7420 44c22668 1 sleeping secs: 1 1cpu flush_sub(7)
18 45ab7760 0 3 IO Idle 1cpu* kaio
19 45c0c2c8 44c22f30 3 sleeping secs: 1 1cpu convert
20 45c0c9f8 44c237f8 2 sleeping secs: 1 1cpu aslogflush
21 45ccc958 44c240c0 1 sleeping secs: 8 1cpu btscanner_0
22 45ceba00 44c24988 3 cond wait ReadAhead 1cpu readahead_0
23 45d0eb50 44c25250 3 sleeping secs: 1 1cpu auto_tune
27 45d8aa80 44c25b18 1 sleeping secs: 0 1cpu sbspclean
28 45d30aa8 44c26ca8 1 sleeping secs: 1 1cpu defragclean
30 45d738f0 44c27570 3 sleeping secs: 1 1cpu* onmode_mon
31 45d89028 44c27e38 3 sleeping secs: 1 1cpu periodic
32 45d89608 44c28700 3 sleeping forever 1cpu memory
33 45d89be8 44c28fc8 3 sleeping secs: 15 1cpu session_mgr
35 45e08768 44c263e0 1 cond wait bp_cond 1cpu bf_priosweep()

IBM Informix Dynamic Server Version 12.10.FC7W1 -- Single-User -- Up 00:01:03 -- 266648 Kbytes

Stack for thread: 19 convert
base: 0x0000000045c19000
len: 69632
pc: 0x00000000013eaa6f
tos: 0x0000000045c24d50
state: sleeping
vp: 1

0x00000000013eaa6f (oninit) yield_processor_svp
0x00000000013ed5d3 (oninit) mt_yield
0x0000000001501340 (oninit) net_wait_for_connect
0x0000000001506ade (oninit) connsocket
0x000000000155f3c0 (oninit) tlConnect
0x000000000155c56a (oninit) slSQIreq
0x0000000001555343 (oninit) pfConReq
0x000000000154c628 (oninit) cmReqSync
0x000000000154d7ef (oninit) cmConReq
0x00000000014ee62e (oninit) ASF_Call
0x000000000076fd94 (oninit) dd_newconnect
0x00000000007712d0 (oninit) dd_remconnect
0x0000000000765404 (oninit) remcatalog
0x0000000000734831 (oninit) readtab
0x000000000073a372 (oninit) ddgettable_hierarchy_trace
0x00000000006bd1d5 (oninit) aud_ddgettable_trace
0x0000000000601206 (oninit) gettab_trace
0x0000000000655f15 (oninit) tlgetddtab_trace
0x0000000000656530 (oninit) tlp2tnode
0x000000000065af3b (oninit) tbl2tab
0x000000000063785d (oninit) sel2cb
0x0000000000639498 (oninit) subq2cb
0x00000000006632c1 (oninit) sq2expr
0x0000000000663373 (oninit) subq2expr
0x000000000066cca4 (oninit) expr2expr
0x0000000000682764 (oninit) ip_exprparse
0x00000000006a28fe (oninit) cmp_stmt
0x00000000006a2c1d (oninit) pr_compile
0x00000000006bf021 (oninit) aud_pr_compile
0x00000000006a3987 (oninit) updprocstat
0x00000000005cfba6 (oninit) excommand
0x0000000000f7eed7 (oninit) admin_exec_cmd
0x0000000000f7f2d5 (oninit) run_sql_script
0x0000000000f7f418 (oninit) run_script_etc
0x0000000000f9b826 (oninit) run_script_conv
0x0000000000f9b936 (oninit) ph_convrev
0x0000000000f42233 (oninit) schapi_cvr1170XC3_convert
0x0000000000f3f906 (oninit) do_each_version_work
0x0000000000f402d3 (oninit) generic_fw_main
0x0000000000f40cf6 (oninit) convertSM
0x00000000013c3720 (oninit) th_init_initgls
0x000000000142a518 (oninit) startup




The stack trace is clear. And precisely 2 minutes later it continues:


01:31:21 *** SCHAPI 1 11.70.xC3 ***
01:33:22 *** FromVersion=5 ToVersion=6 entity_ver=5 targetVersion=7 indexVersion=5 ***
01:33:22 *** SCHAPI 1 12.10.xC1 ***
01:33:22 calling schapi_cvr1210_convert
01:33:22 *** FromVersion=6 ToVersion=7 entity_ver=6 targetVersion=7 indexVersion=6 ***
01:33:22 *** SCHAPI 1 12.10.xC4 ***
01:33:22 calling schapi_cvr1210XC4_convert
01:33:23 Dynamically allocated new virtual shared memory segment (size 8192KB)
01:33:23 Memory sizes:resident:4796 KB, virtual:270044 KB, no SHMTOTAL limit
01:33:23 Conv/rev: Finished conversion for component SCHAPI




And it completed the conversion. In the customer situation, a later test showed a "hang" period of around 45m. So, a big warning.... The conversion process will run an UPDATE STATISTICS FOR PROCEDURE on sysadmin database. If you have created some procedures that do remote/distributed operations than you must consider this "problem" during the upgrade. Here are your options:

  1. Allow connections to that remote server(s)
  2. Remove the procedures and recreate them
  3. Use INFORMIXCONTIME parameter (12.10 only) to reduce the timeouts
  4. Remove the remote INFORMIXSERVER from the INFORMIXSQLHOSTS during migration. This also makes the connections attempts very quickly (as it simply can't find where to connect)


Versão Portuguesa
Há algum tempo num cliente, estando a testar uma migração de uma versão 11.50.FC7 para 12.10.FC7W1 deparámo-nos com um aparente bloqueio. Não é o que gostamos de ver, ainda que seja num ambiente de testes.
Esperámos uns minutos e tentámos perceber o que se estava a passar. Havia uma thread chamada "convert" que aparentemente estava inativa. O seu stack trace não parecia mudar
As funções que apareciam no stack sugeriam que estava a tentar contactar um servidor remoto, seguindo o que parecia ser uma chamada a um UPDATE STATISTICS. Isto foi uma grande surpresa.... Olhando para o online.log estava parado na fase "SCHAPI". Isto está relacionado com a sysadmin.
Considerando que o upgrade não estava com bom aspeto e que se tratava de um ambiente de testes decidimos abortar e usámos o onrestorept para reverter para a versão 11.50 (umas das minhas funcionalidades favoritas).
Para efeitos de teste e investigação decidimos executar um UPDATE STATISTICS FOR PROCEDURE na base de dados sysadmin. E voilá, preso de novo.
Portanto um UPDATE STATISTICS FOR PROCEDURE na sysadmin bloqueava o sistema e isso teria acontecido durante o upgrade. Após mais investigação concluímos que tínhamos criado procedimentos nesta base de dados para implementar algumas tarefas de monitorização e que esses procedimentos executavam algumas operações remotas para enviar a informação de monitorização para um sistema central. E antes do upgrade tinha sido feito uma alteração "de rotina" que consistiu na alteração do $INFORMIXSQLHOSTS de forma a "isolar" este motor. Basicamente foi adicionado um valor a todas as portas dos listeners, o que faz com que os clientes (não alterados) não consigam chegar ao ambiente. A consequência disto é que quando efetuamos o UPDATE STATISTICS este motor tenta aceder ao(s) motores referenciados nas operações remotas o que também não será possível. E como tal temos um timeout por cada operação remota encontrada nos procedimentos. Testes posteriores na 12.10 mostraram que a espera por cada tentativa de conexão é o valor por omissão (60s) ou o que estiver definido no parâmetro de $ONCONFIG INFORMIXCONTIME introduzido recentemente.

Tudo isto pode ser reproduzido facilmente. Num motor com a versão 11.50 criamos um procedimento simples (inútil):


bica@primary:informix-> onstat -

IBM Informix Dynamic Server Version 11.50.FC7 -- On-Line -- Up 00:30:33 -- 269068 Kbytes


bica@primary:informix-> cat test_remote_proc_stats.sql


CREATE PROCEDURE test_updstats_remote()

DEFINE i INTEGER;

SELECT 1 INTO i FROM stores@test:systables WHERE tabid = 1;

SELECT 2 INTO i FROM somedb@test:systables WHERE tabid = 1;

END PROCEDURE;
bica@primary:informix-> 



bica@primary:informix-> dbaccess sysadmin test_remote_proc_stats.sql

Database selected.

Routine created.

Database closed.

bica@primary:informix->

O servidor de base de dados "test" existe no $INFORMIXSQLHOSTS, mas aponta para um serviço não existente. Tentemos um upgrade para a 12.10.FC7 e vejamos o que acontece:

No online.log temos:


01:30:52 IBM Informix Dynamic Server Started.
01:30:52 Requested shared memory segment size rounded from 4308KB to 4796KB

Wed Aug 31 01:30:54 2016

01:30:54 Requested shared memory segment size rounded from 221001KB to 221004KB
01:30:54 Successfully added a bufferpool of page size 2K.

01:30:54 Event alarms enabled. ALARMPROG = '/usr/informix/srvr1210fc7w1/etc/alarmprogram.sh'
01:30:54 Booting Language from module <>
01:30:54 Loading Module
01:30:54 Booting Language from module <>
01:30:54 Loading Module
01:30:59 DR: DRAUTO is 0 (Off)
01:30:59 DR: ENCRYPT_HDR is 0 (HDR encryption Disabled)
01:30:59 Event notification facility epoll enabled.
01:31:00 Trusted host cache successfully built:/etc/hosts.equiv.
01:31:00 CCFLAGS2 value set to 0x200
01:31:00 SQL_FEAT_CTRL value set to 0x8008
01:31:00 SQL_DEF_CTRL value set to 0x4b0
01:31:00 IBM Informix Dynamic Server Version 12.10.FC7W1 Software Serial Number AAA#B000000
01:31:00 Conversion from version 11.50.xC6 Started

[...]

01:31:05 processing sysmaster
01:31:05 *** entity_ver=31 targetVersion=36 indexVersion= 0 ***
01:31:05 *** FromVersion=10 ToVersion=26 entity_ver=31 targetVersion=36 indexVersion=0 ***
01:31:05 *** FromVersion=26 ToVersion=28 entity_ver=31 targetVersion=36 indexVersion=1 ***
01:31:05 *** FromVersion=28 ToVersion=29 entity_ver=31 targetVersion=36 indexVersion=2 ***
01:31:05 *** FromVersion=29 ToVersion=30 entity_ver=31 targetVersion=36 indexVersion=3 ***
01:31:05 *** FromVersion=30 ToVersion=31 entity_ver=31 targetVersion=36 indexVersion=4 ***
01:31:05 *** FromVersion=31 ToVersion=32 entity_ver=31 targetVersion=36 indexVersion=5 ***
01:31:05 *** SQL 1 11.70.xC1 ***
01:31:05 Converting database sysmaster ...
01:31:06 The database sysmaster has been converted successfully.
01:31:06 *** FromVersion=32 ToVersion=33 entity_ver=32 targetVersion=36 indexVersion=6 ***
01:31:06 *** SQL 1 11.70.xC3 ***
01:31:06 Converting database sysmaster ...
01:31:06 The database sysmaster has been converted successfully.
01:31:06 *** FromVersion=33 ToVersion=34 entity_ver=33 targetVersion=36 indexVersion=7 ***
01:31:06 *** SQL 1 12.10.xC1 ***
01:31:06 Converting database sysmaster ...
01:31:06 The database sysmaster has been converted successfully.
01:31:06 *** FromVersion=34 ToVersion=35 entity_ver=34 targetVersion=36 indexVersion=8 ***
01:31:06 *** SQL 1 12.10.xC4 ***
01:31:06 Converting database sysmaster ...
01:31:06 The database sysmaster has been converted successfully.
01:31:06 *** FromVersion=35 ToVersion=36 entity_ver=35 targetVersion=36 indexVersion=9 ***
01:31:06 *** SQL 1 12.10.xC4 ***
01:31:06 processing sysutils

[...]

01:31:17 Conv/rev: calling conversion to 12.10.xC1 ...
01:31:19 Conv/rev: blade conversion to 12.10.xC1 completed
01:31:19 *** FromVersion=6 ToVersion=7 entity_ver=6 targetVersion=7 indexVersion=6 ***
01:31:19 *** BLADE 1 12.10.xC4 ***
01:31:19 Conv/rev: calling conversion to 12.10.xC4 ...
01:31:21 Conv/rev: blade conversion to 12.10.xC4 completed
01:31:21 Conv/rev: Finished conversion for component BLADE
01:31:21 Conv/rev: Started conversion for component SCHAPI
01:31:21 *** numVersions=7 targetVersion=7 ***
01:31:21 *** entity_ver=3 targetVersion=7 indexVersion= 0 ***
01:31:21 *** FromVersion=0 ToVersion=1 entity_ver=3 targetVersion=7 indexVersion=0 ***
01:31:21 *** FromVersion=1 ToVersion=2 entity_ver=3 targetVersion=7 indexVersion=1 ***
01:31:21 *** FromVersion=2 ToVersion=3 entity_ver=3 targetVersion=7 indexVersion=2 ***
01:31:21 *** FromVersion=3 ToVersion=4 entity_ver=3 targetVersion=7 indexVersion=3 ***
01:31:21 *** SCHAPI 1 11.70.xC1 ***
01:31:21 calling schapi_cvr1170_convert
01:31:21 *** FromVersion=4 ToVersion=5 entity_ver=4 targetVersion=7 indexVersion=4 ***
01:31:21 *** SCHAPI 1 11.70.xC3 ***



e bloqueia...
Vejamos as threads e o respetivo stack:


IBM Informix Dynamic Server Version 12.10.FC7W1 -- Single-User -- Up 00:00:54 -- 266648 Kbytes

Threads:
tid tcb rstcb prty status vp-class name
2 4579d9e8 0 1 IO Idle 3lio* lio vp 0
3 458fd368 0 1 IO Idle 4pio* pio vp 0
4 4591e368 0 1 IO Idle 5aio* aio vp 0
5 4593f368 1d43600 1 IO Idle 6msc* msc vp 0
6 45970368 0 1 IO Idle 7fifo* fifo vp 0
7 45991608 44c1e028 3 sleeping secs: 1 1cpu main_loop()
8 459ed4c0 0 1 running 8soc* soctcppoll
9 459edc98 0 2 sleeping forever 1cpu* soctcplst
10 45a3cc88 44c1e8f0 1 sleeping secs: 1 1cpu flush_sub(0)
11 45a59028 44c1f1b8 1 sleeping secs: 1 1cpu flush_sub(1)
12 45a59368 44c1fa80 1 sleeping secs: 1 1cpu flush_sub(2)
13 45a596a8 44c20348 1 sleeping secs: 1 1cpu flush_sub(3)
14 45a599e8 44c20c10 1 sleeping secs: 1 1cpu flush_sub(4)
15 45a59d28 44c214d8 1 sleeping secs: 1 1cpu flush_sub(5)
16 45ab70e0 44c21da0 1 sleeping secs: 1 1cpu flush_sub(6)
17 45ab7420 44c22668 1 sleeping secs: 1 1cpu flush_sub(7)
18 45ab7760 0 3 IO Idle 1cpu* kaio
19 45c0c2c8 44c22f30 3 sleeping secs: 1 1cpu convert
20 45c0c9f8 44c237f8 2 sleeping secs: 1 1cpu aslogflush
21 45ccc958 44c240c0 1 sleeping secs: 8 1cpu btscanner_0
22 45ceba00 44c24988 3 cond wait ReadAhead 1cpu readahead_0
23 45d0eb50 44c25250 3 sleeping secs: 1 1cpu auto_tune
27 45d8aa80 44c25b18 1 sleeping secs: 0 1cpu sbspclean
28 45d30aa8 44c26ca8 1 sleeping secs: 1 1cpu defragclean
30 45d738f0 44c27570 3 sleeping secs: 1 1cpu* onmode_mon
31 45d89028 44c27e38 3 sleeping secs: 1 1cpu periodic
32 45d89608 44c28700 3 sleeping forever 1cpu memory
33 45d89be8 44c28fc8 3 sleeping secs: 15 1cpu session_mgr
35 45e08768 44c263e0 1 cond wait bp_cond 1cpu bf_priosweep()

IBM Informix Dynamic Server Version 12.10.FC7W1 -- Single-User -- Up 00:01:03 -- 266648 Kbytes

Stack for thread: 19 convert
base: 0x0000000045c19000
len: 69632
pc: 0x00000000013eaa6f
tos: 0x0000000045c24d50
state: sleeping
vp: 1

0x00000000013eaa6f (oninit) yield_processor_svp
0x00000000013ed5d3 (oninit) mt_yield
0x0000000001501340 (oninit) net_wait_for_connect
0x0000000001506ade (oninit) connsocket
0x000000000155f3c0 (oninit) tlConnect
0x000000000155c56a (oninit) slSQIreq
0x0000000001555343 (oninit) pfConReq
0x000000000154c628 (oninit) cmReqSync
0x000000000154d7ef (oninit) cmConReq
0x00000000014ee62e (oninit) ASF_Call
0x000000000076fd94 (oninit) dd_newconnect
0x00000000007712d0 (oninit) dd_remconnect
0x0000000000765404 (oninit) remcatalog
0x0000000000734831 (oninit) readtab
0x000000000073a372 (oninit) ddgettable_hierarchy_trace
0x00000000006bd1d5 (oninit) aud_ddgettable_trace
0x0000000000601206 (oninit) gettab_trace
0x0000000000655f15 (oninit) tlgetddtab_trace
0x0000000000656530 (oninit) tlp2tnode
0x000000000065af3b (oninit) tbl2tab
0x000000000063785d (oninit) sel2cb
0x0000000000639498 (oninit) subq2cb
0x00000000006632c1 (oninit) sq2expr
0x0000000000663373 (oninit) subq2expr
0x000000000066cca4 (oninit) expr2expr
0x0000000000682764 (oninit) ip_exprparse
0x00000000006a28fe (oninit) cmp_stmt
0x00000000006a2c1d (oninit) pr_compile
0x00000000006bf021 (oninit) aud_pr_compile
0x00000000006a3987 (oninit) updprocstat
0x00000000005cfba6 (oninit) excommand
0x0000000000f7eed7 (oninit) admin_exec_cmd
0x0000000000f7f2d5 (oninit) run_sql_script
0x0000000000f7f418 (oninit) run_script_etc
0x0000000000f9b826 (oninit) run_script_conv
0x0000000000f9b936 (oninit) ph_convrev
0x0000000000f42233 (oninit) schapi_cvr1170XC3_convert
0x0000000000f3f906 (oninit) do_each_version_work
0x0000000000f402d3 (oninit) generic_fw_main
0x0000000000f40cf6 (oninit) convertSM
0x00000000013c3720 (oninit) th_init_initgls
0x000000000142a518 (oninit) startup




O stack é claro. E precisamente 2 minutos depois a conversão continua (o procedimento tinha duas instruções remotas):


01:31:21 *** SCHAPI 1 11.70.xC3 ***
01:33:22 *** FromVersion=5 ToVersion=6 entity_ver=5 targetVersion=7 indexVersion=5 ***
01:33:22 *** SCHAPI 1 12.10.xC1 ***
01:33:22 calling schapi_cvr1210_convert
01:33:22 *** FromVersion=6 ToVersion=7 entity_ver=6 targetVersion=7 indexVersion=6 ***
01:33:22 *** SCHAPI 1 12.10.xC4 ***
01:33:22 calling schapi_cvr1210XC4_convert
01:33:23 Dynamically allocated new virtual shared memory segment (size 8192KB)
01:33:23 Memory sizes:resident:4796 KB, virtual:270044 KB, no SHMTOTAL limit
01:33:23 Conv/rev: Finished conversion for component SCHAPI




E termina a conversão. Na situação concreta do cliente, um novo teste com a mesma instância apresentou um "bloqueio" durante cerca de 45m (correspondente a sensivelmente o mesmo número de instruções remotas nos procedimentos da sysadmin). Portanto um grande alerta...: O processo de conversão irá executar um UPDATE STATISTICS FOR PROCEDURE na base de dados sysadmin (isto não está documentado, mas é natural tendo em conta o processo de conversão da mesma). Se porventura criou procedimentos que acedem a instâncias remotas, então deverá ter isto em conta As opções para lidar com isto serão::
  1. Permitir as ligações ao(s) servidor remoto
  2. Remover os procedimentos e recriá-los depois da migração
  3. Usar o parâmetro INFORMIXCONTIME (a partir da 12.10) para reduzir os tempos de espera
  4. Remover o INFORMIXSERVER remoto do $INFORMIXSQLHOSTS durante a conversão. Isto também permite acelerar as tentativas de conexão pois ao não encontrar a referência no ficheiro o motor não sabe onde se ligar, e portanto não se aplicam os timeouts