terça-feira, 26 de julho de 2011

A Arquitetura Multithreaded

O que é uma Thread?

Uma Thread é uma sequencia de instruções sendo executadas em um programa.

Antes, observaremos a arquitetura do servidor, pois é útil examinar o conceito usual de uma thread.

Uma thread pode ser interpretada como uma sequencia de instruções sendo executadas em um programa. Quando múltiplas thread são executadas em uma mesma entidade (no nosso caso, um processo), ela é chamada de multithreading.

Single-Threaded vs. Multithreaded

 

processo

Um processo regular UNIX que não implementa threads pode ser pensado como um processo single-threaded, apesar de não ser chamado assim. Uma sequencia de instruções é executada para este processo, e o sistema operacional é responsável por agendar e executar esses processos.

Multithreading é um método de muitas execuções repetidas de um processo para diferentes usuários sem ter que formar muitas instancias daquele processo ao nível do sistema operacional.

Um processo multhreaded pode ter threads múltiplas pesquisando dentro de um processo UNIX, cada um executando sequencialmente e dando o controle para outras threads em um ponto especifico de tempo. A forma como uma arquitetura multithread é executada é o que difere de uma arquitetura de single-thread recebendo e executando solicitações de um processo de um único usuário.

Multithreading é um conceito ao nível do sistema por onde os programas realmente executam instruções ao nível da maquina para manipular os processos, então esse é executado para vários usuários ao invés de apenas um. O programa executa estas instruções totalmente ao nível do usuário, e não nível do Kernel do UNIX. Longe de afetar o UNIX, um processo em arquitetura multithread é um processo único, como qualquer outro processo.

Um programa Single-Threaded

Considerar como o UNIX trabalha com multiprocessamento.

Cada processo UNIX tem um espaço de endereço consistindo em três segmentos: text, data e stack. O segmento text contem a instrução da maquina que gera o programa de codificação executável. Os segmentos stack contem variáveis locais usada pelos programas funcionais. Finalmente, o segmento data contem o programa global e as variáveis estáticas, strings, array e outros dados.

Em uma maquina monoprocessada que esteja executando 1000 processos, somente um processo esta sendo executado pelo UNIX em algum momento. Cada processo esta sendo executado dentro de uma quantidade especifica de tempo antes dele ser pré-desocupado (interrompido) pelo kernel de maneira que o próximo processo agendado possa ser executado. Quando um processo em execução é pré-desocupado, devem ser salvas informações suficientes de maneira que o processo possa ser reiniciado mais tarde. Esta informação é chamada de context do processo. O context consiste basicamente dos seguintes componentes:

  • O program counter, o qual especifica o endereço das próximas instruções a serem executadas.
  • O stack pointer, o qual contem o endereço atual da próxima entrada no stack.
  • O general purpose registers, os quais contem os dados gerados pelo processo durante essa execução.

Existem outros componentes do context do processo UNIX, chamado de system level context, porem não vamos abortar, pois não são críticos para a compreensão de multithreading.

Um Context Switch (Alternância de Contexto)

Em UNIX, um context switch ocorre quando um processo em execução é interrompido pelo sistema operacional. Para fazer isto, o sistema operacional salva, correntemente, o context do processo em execução em estruturas de dados pré-alocadas em memoria e carrega o contexto do próximo processo agendado.

Carregar o context envolve restauração do program counter, o stack pointer e todos os general purpose registers para os valores salvos pelo sistema operacional na ultima vez que o processo em execução foi pré-desocupado. Uma vez completo, o processo continua sua execução a partir da linha de código especificada pelo program counter.

Um processo Multithreaded

O processo multithread, cada thread tem o seu próprio context, isto é, seu próprio local no código ( program counter ) e suas próprias variáveis de dados. Um processo multithread trabalha muito parecido com o sistema operacional na maneira da troca de um context de uma thread para outra.

O próprio processo executa instruções de maquinas para realizar uma copia da thread executada no momento e trazer a próxima thread agendada. Isto permite basicamente o mesmo resultado que o sistema operacional alcança fazendo um context switch. O resultado é que o program counter aponta para uma nova instrução dentro do segmento text, o stack pointer aponta para uma diferente área de memoria  e os general purpose register são restaurados para os valores previamente salvados por este context. No caso do IDS Multithreading, o stack de uma thread é mantido em shared memory para se mover entre os processos do servidor (virtual processors). O tamanho padrão de stack é 32 kilobytes por cada userthread. O servidor verifica o overflow do stack e automaticamente expande o tamanho stack.

Uma vez que o processo multithread age como um mini sistema operacional, ele é responsável por manter coisas do tipo:

  • Agendamento: a thread  atual decide quando ceder controle de um processo e transferir controle para outra thread. A thread atual tambem decide qual a próxima thread que será executada baseado em mecanismo de prioridade interno.
  • Troca de Context: quando a thread atual decide que é a hora de executar outra thread, ele deve executar instruções de maquina para efetuar a troca de context entre as threads.

Agendamentos e a troca de context ainda são efetuados pelo UNIX normalmente. O processo multithread efetua agendamento e a troca de context de threads. Mantenha estes dois conceitos separados.

Virtual Processors

Os processos que compõe o database server são conhecidos para Virtual Processors. Cada VP pertence a um virtual processor class. Um VP class é um grupo de processos responsáveis por um conjunto especifico de tarefas (na forma de threads), como, por exemplo, gravar para o logical log ou ler dados do disco. Isto quer dizer que um VP de uma certa classe pode somente pesquisar thread de uma mesma classe. Uma classe de VP pode ter um ou mais VPs, a qual na maior parte dos casos é configurada pelo administrador do sistema. O nome de um VP executável é oninit. Todos os VPs de todas as classes são exemplos de mesmo programa, oninit.

Executando uma Thread

Uma Thread esta sendo executada em um processador particular, ou esta em uma de uma serie de filas. As filas ready (ready queues) mantem os contexts de threads esperando para executa-los em um processador. Quando um processador esta livre, ele obterá o context de uma thread de uma ready queue. Ha um mecanismo de prioridade interno que determina qual thread o processador obterá da fila. O processador os substitui o context atual com o context da nova thread e continua o processamento daquela thread.

As ready queues são compartilhadas entre processadores de mesma classe de modo que uma thread possa migrar entre vários processadores durante sua existência (apesar do server tender em manter a execução de uma thread em um mesmo processo). Este mecanismo mentem o trabalho balanceado entre os processos e garante que uma thread será executada se algum processador estiver disponível.

Passando o controle para outra Thread

A um ponto especifico de execução, a thread cede o controle do processador para outra thread. Algumas ações comuns que poderiam fazer a thread ceder são:

  • Aguardando por uma operação de leitura ou de gravação no disco;
  • Aguardando por uma solicitação do processo de aplicação;
  • Aguardando por um lock ou outro recurso;
  • Não há mais trabalho a fazer.

Uma thread tambem poderia ceder o controle por nenhuma razão, além de dar a uma outra thread uma chance de ser executada.

Quando um thread cede controle, ela é responsável pela colocação de seu próprio context em uma de muitas filas de espera (wait queue) ou uma fila de aguardo (sleep queue). As wait queue são usadas basicamente para esperar uma operação. As sleep queues são usadas por threads que necessitam ser reativadas depois de um período de tempo.

O processador, então, pega o context de uma thread qualquer de uma ready queue e a substitui seu context com a nova thread. O processador continua a execução com o novo context.

Vantagens das Threads do Servidor

Algumas das vantagens do server threads são listadas abaixo:

  • São necessários poucos processos para fazer o mesmo trabalho. Este é particularmente eficiente em um ambiente OLTP quando há um grande numero de usuários. Você pode pensar nisto como fan-in, onde há um grande numero de processos de aplicação com um pequeno numero de processos do database server suportando suas solicitações. Uma vantagem adicional é que um sistema que pode suportar mais usuários porque ha menos processos que necessitam ser suportados pelo sistema operacional.
  • Além das capacidades fan-in, o server tambem oferece uma capacidade fan-out. Múltiplos processos do database server podem fazer o trabalho por uma aplicação.
  • A arquitetura multithreaded substitui muito a troca do context feito pelo sistema operacional com a troca do context feitos pelos processos dentro do database server. Uma troca de context é mais rápido quando feito dentro de um processo porque ha menos informações para trocar.
  • O processo do database server faz o seu próprio agendamento de thread. Isto dignifica que o DBMS, a frente do que o sistema operacional determina a prioridade de tarefas.
  • Algumas características oferecidas por um sistema multi-processado fazem deste tipo de arquitetura, muito mais eficiente. Por exemplo, nós poderíamos dar um importante processo do database server direitos exclusivos para usar um processador em partilhar.

Fan-out

Uma das vantagens do server está em suas capacidades fan-out. Isto significa que usuários podem levar vantagens de múltiplos processadores do database server (e múltiplos CPUs, se disponível) trabalhando simultaneamente para fazer o trabalho deles.

o Server criará múltiplas threads que farão o trabalho de um usuário para as operações seguintes:

  • Ordenação
  • Indexação
  • Recuperação

segunda-feira, 25 de julho de 2011

Atualizando o Informix (In-Place)

Na atualização do Informix sempre surge duvidas, devo atualizar no mesmo diretório? não vou perder meus dados que estão lá? não vai danificar meu chunk primário?

A IBM diz que atualizar o Informix diretamente para a versão atual, deve-se instalar o produto em um novo diretório,  copiando alguns arquivos de configuração e iniciar o servidor para automaticamente converter os dados de sua base atual.

Segundo a IBM pode-se atualizar diretamente qualquer desses produtos: Informix Versão 11.10, 10.00, 9.40, 9.30, 9.21 ou 7.31

A atualização é um método de migração in-loco que usa uma base teste e produção.

A atualização é um método de migração in-loco que usa seu teste existentes e hardware de produção. O sistema operacional nesses servidores devem ser suportados pelo Informix. Além disso, você deve ter espaço suficiente para a conversão dos dados.

Uma atualização segura consiste de alguns procedimentos:

  1. Prepare seu sistema, que inclui fechar todas as transações, verifique a integridade dos dados com o utilitário oncheck, e faça um backup do nível 0. ( Se você estiver utilizando o Enterprise Replication ou cluster de alta disponibilidade, você deve para esse serviço e realizar algumas tarefas adicionais).

    Uma boa pratica é fazer backup de todos os arquivos de configuração, tanto do sistema operacional quanto do Informix.
  2. Instale o novo produto no servidor.

    Importante: A forma mais segura de atualizar o Informix é instalar uma nova versão em outro diretório. Para economizar espaço você pode selecionar somente os produtos que necessita para a instalação. Somente depois de testar a instancia do servidor com as configurações semelhantes ao de produção é que vamos aplicar essa atualização no servidor de produção, depois de validado esse ambiente de produção, pode-se remover a versão antiga.

    Se você não tem espaço em seu servidor para suportar as duas versões, instale a nova versão sobre a versão existente. Nesse caso você não pode selecionar a instalação de componentes.
    Certifique-se também nesse caso, que você tenha a mídia da versão anterior, pois se algo der errado não pode reverter isso.
  3. Copie o arquivo ONCONFIG para o novo diretório do Informix.
  4. Inicialize a instancia com a nova versão do Informix. Os dados do banco serão convertidos automaticamente.
  5. Se você tiver problemas de performance, rode o UPDATE STATISTICS e UPDATE STATISTICS FOR PROCEDURE.

    Esse tipo de migração minimiza os riscos. Se algo der errado você poderá voltar a versão antiga. Em caso de problema durante a conversão então terá que voltar o backup nível 0.

sexta-feira, 22 de julho de 2011

Atualizando o Informix (In-Place)

Na atualização do Informix sempre surge duvidas, devo atualizar no mesmo diretório? não vou perder meus dados que estão lá? não vai danificar meu chunk primário?

A IBM diz que atualizar o Informix diretamente para a versão atual, deve-se instalar o produto em um novo diretório,  copiando alguns arquivos de configuração e iniciar o servidor para automaticamente converter os dados de sua base atual.

Segundo a IBM pode-se atualizar diretamente qualquer desses produtos: Informix Versão 11.10, 10.00, 9.40, 9.30, 9.21 ou 7.31

A atualização é um método de migração in-loco que usa uma base teste e produção.

A atualização é um método de migração in-loco que usa seu teste existentes e hardware de produção. O sistema operacional nesses servidores devem ser suportados pelo Informix. Além disso, você deve ter espaço suficiente para a conversão dos dados.

Uma atualização segura consiste de alguns procedimentos:

  1. Prepare seu sistema, que inclui fechar todas as transações, verifique a integridade dos dados com o utilitário oncheck, e faça um backup do nível 0. ( Se você estiver utilizando o Enterprise Replication ou cluster de alta disponibilidade, você deve para esse serviço e realizar algumas tarefas adicionais).

    Uma boa pratica é fazer backup de todos os arquivos de configuração, tanto do sistema operacional quanto do Informix.
  2. Instale o novo produto no servidor.

    Importante: A forma mais segura de atualizar o Informix é instalar uma nova versão em outro diretório. Para economizar espaço você pode selecionar somente os produtos que necessita para a instalação. Somente depois de testar a instancia do servidor com as configurações semelhantes ao de produção é que vamos aplicar essa atualização no servidor de produção, depois de validado esse ambiente de produção, pode-se remover a versão antiga.

    Se você não tem espaço em seu servidor para suportar as duas versões, instale a nova versão sobre a versão existente. Nesse caso você não pode selecionar a instalação de componentes.
    Certifique-se também nesse caso, que você tenha a mídia da versão anterior, pois se algo der errado não pode reverter isso.
  3. Copie o arquivo ONCONFIG para o novo diretório do Informix.
  4. Inicialize a instancia com a nova versão do Informix. Os dados do banco serão convertidos automaticamente.
  5. Se você tiver problemas de performance, rode o UPDATE STATISTICS e UPDATE STATISTICS FOR PROCEDURE.

    Esse tipo de migração minimiza os riscos. Se algo der errado você poderá voltar a versão antiga. Em caso de problema durante a conversão então terá que voltar o backup nível 0.

Warning no arquivo online.log

Saudações,

Olhando o meu online.log , arquivo de log do informix, me deparei com um warning que se refere a prioridade do PDQ, o bloco do warning estou postando a seguir:

Warning: PDQ functionality is not supported in IDS Growth Edition.
The value of MAX_PDQPRIORITY cannot be set to 100. It is reset to 0.

Bem, vamos tentar entender o que é exatamente esse warning.

Existem vários tipos de Edição do Informix, além do Growth Edition, temos o Enterprise, entre outros.

Mas a pergunta chave aqui é… o que é esse parâmetro MAX_PDQPRIORITY?

MAX_PDQPRIORITY limita os recursos PDQ que o servidor de banco de dados pode atribuir a qualquer consulta DSS. MAX_PDQPRIORITY é um fator que é usado para dimensionar o valor de prioridade PDQ definidas pelos usuários. Por exemplo, suponha que o DBA atribuiu à MAX_PDQPRIORITY um valor de 80. 

MAX_PDQPRIORITY é um fator que é usado para dimensionar o valor de prioridade PDQ definidas pelos usuários. Se um usuário configura a variável de ambiente PDQPRIORITY para 50 e executa a query, o banco de dados vai executar essa query com um prioridade de 40.

Podemos usar o onmode para alterar o valor do MAX_PDQPRIORITY quando o servidor de banco estiver online.

No IDS, os recursos PDQ incluem memoria, CPU, I/O em discos e scan threads, e se o valor de MAX_PDQPRIORITY for muito baixo, a performance pode cair muito.

Por padrão no onconfig.std o valor de PDQ_PRIORITY é 100.

PDQ é abreviação de Parallel Database Query e o objetivo do PDQ é melhorar a performance das queries que são executadas no banco de dados.

Infelizmente esse recurso somente esta disponível em algumas edições do Informix e como percebemos na versão Growth não esta disponível.

Como não gosto muito de ficar vendo warning nos arquivos de log, fiz algumas ações para passar o valor de MAX_PRIORITY  para 0, assim não fico mais recebendo essa mensagem de warning.

a primeira ação foi rodar o onmode –D 0, esse comando define a prioridade do PDQ deve ser usado um valor de 0 a 100, porem não resolveu o problema, então fiz a mudança manualmente no arquivo onconfig alterando o valor da variável MAX_PDQPRIORITY para 0. Feito isso o warning não sai mais no online.log.

quinta-feira, 21 de julho de 2011

Rastreamento de endereço IP com Xtrace

Resolução de Problemas

Problema

Rastreamento do endereço IP e numero de porta com xtrace no IBM Informix Dynamic Server

Resolvendo o problema

No IDS versão 10x em diante o usuario com privilegios administrativos pode rastrear o endereço IP de todos os cliente conexão com o servidor de banco de dados usando o utilitario IDS Xtrace.

Esta facilidade é util no diagnostico de problemas com conexão no banco de dados vinda de clientes (conexão de entradas).

Esta facilidade é aplicavel somente nos servidores IDS que tem chamadas SOC (Sockets) usando conexão TCP (Transmission Control Protocol) e TLI (Transport Level Interface) utilizando TCP e SPX.

Passos para Utilização

Para rastrear o IP faça o seguinte:

  1. Verifique o status do IDS Server;
    Certifique-se de que o IDS esta ativo e no modo ‘On-Line’. O comando ‘onstat –‘ pode ser usado para se verificar o status do server.
  2. Defina os valores das variaveis. Este passo é opcional.
    O valor padrão do xtrace é 4096. Este valor pode ser mudado quanto o xtrace estiver no modo off.
    Exemplo:

    xtrace size 8000
  3. Inicializar os componentes do IP trace
    Setar o componente ‘XTF_IPTRACE’ e a variavel ‘XTF_SYSCALLS’ para o IP trace
    Exemplo:

    xtrace heavy –c XTF_IPTRACE –f XTF_SYSCALLS
  4. Iniciar o rastreamento
    Isso forçara o IDS a coletar todos os dados relacionados as conexões  para dentro do repositorio. O tamanho desse repositorio é definido na variavel xtrace size.
    Exemplo:

    xtrace on
  5. Analisar os detalhes das conexões dos clientes.
    Os detalhes do xtrace pode ser visualizado usando o comando xtrace view.
    Exemplo:

    xtrace view

    Abaixo uma saida do xtrace:
    For Sockets:
    Quando um host name existe
    accpsocket - Accepted IP Address <Hex Address>(<Host Name>)

    Quando um host name nao existe
    accpsocket - Accepted IP Address <Hex Address>

    For TLI:
    Quando um host name existe
    accptli - Rejected IP Address <Hex Address>(<Host Name>)
    accptli - Queuing IP Address <Hex Address>(<Host Name
    >)
    accptli - Failed accept IP Address <Hex Address>(<Host Name
    >)
    accptli - Accepting IP Address <Hex Address>(<Host Name
    >)

    Quando um host name nao existe
    accptli - Rejected IP Address <Hex Address>
    accptli - Rejected IP Address <
    Hex Address>
    accptli - Queuing IP Address <
    Hex Address>
    accptli - Failed accept IP Address <
    Hex Address>
    accptli - Accepting IP Address <
    Hex Address>
  6. Finalizando o rastreamento
    O rastreamento é finalizado com o comando xtrace off
    Exemplo:

    xtrace off

quarta-feira, 20 de julho de 2011

Usos do Shell

Uma das maiores funções do shell é para interpretar comandos digitados em linhas de comandos. O shell analisa a linha de comando, quebra-os em palavras (chamados de tokens), separados por um espaço em branco, que consiste em tabulações, espaços ou nova linha. Se a palavra contem metacaracteres especiais, o shell avalia-os tambem. O shell trata processamentos em primeiro plano (foreground) e tambem em segundo plano (background). Apos a linha de comando ser processada, o shell procura pelo comando e inicia a sua execução.

Outra função importante do shell é a personalização do ambiente dos usuários, feito normalmente em arquivos de inicialização. Estes arquivos contem definições para a configuração de terminais e características de ambientes gráficos; configuração de variáveis que define as pesquisas de comandos (search path), permissões, prompts e tipos de terminais, e configurações de variáveis requeridas por aplicações especificas como um x-window, programas para processar textos, e bibliotecas para linguagem de programação. O Korn Shell e o C Shell tambem fornece uma maior personalização com o histórico e aliases, variáveis embutida configura proteção contra sobreposição de arquivos, de forma não intencional, e notifica o usuário quando tarefas foram completadas.

O shell pode ser usado como um interpretador de linguagem de programação. Programas Shell, chamados de scripts, consiste de uma lista de comando em um arquivo. Os programas são criados em um editor. Estes arquivos consistem de comandos UNIX em forma de programação como atribuições de variáveis, condições e loops. Os shell scripts não precisam ser compilados. O shell interpreta cada linha do script como se tivesse sido digitado via teclado. Porque o shell é responsável por interpretar os comandos, é necessário que o usuário tenha conhecimento dos comandos UNIX.

Eventos Importantes no Servidor IDS

Data Caching

Quando o servidor quer acessar algum dado, ela deve achar a pagina onde aquele dado esta alocado. Uma vez que a pagina é localizada, esta é lida do disco para dentro de um dos buffers no shared memory buffer pool. Uma vez que esta pagina esta no buffer pool, qualquer outro usuário que queira ler aquela pagina pode faze-lo sem ter que lê-lo novamente do disco; as pagina no shared memory buffer pool são compartilhadas por todo os processos do servidor.

A leitura de pagina do disco dentro do shared memory buffers é conhecida como data caching. Se o dado na pagina é modificado por um servidor (durante um INSERT, DELETE ou UPDATE), ela é modificada diretamente no buffer. Isto quer dizer que todo o processo do servidor terá acesso imediato para o dado modificado.

Os buffers modificados em shared memory serão copiados de volta para o disco mais tarde.

Checkpoints

Como as paginas são lidas dos discos para dentro da shared memory buffers e então modificadas dentro destes buffers, as paginas dos discos e as copias destas paginas no shared memory buffers tornam-se fora de sincronização. É necessário, nesta ocasião, ressincronizar estes dois de modo que eles estejam iguais. Esta ressincronização é executada por um evento do sistema conhecido como checkpoint. Durante um checkpoint, todas as paginas na shared memory buffers que foram modificadas são copiadas de volta para o disco. Este trabalho é executado por um dos virtuais processors. Quando o checkpoint esta terminado, todas as paginas na shared memory buffers estão novamente sincronizadas com as paginas do disco.

Point of Recovery

Estes checkpoints também sevem como um recovery point. Se o sistema sofre um crash, nenhuma mudança feita pelas paginas em shared memory esta sincronizada com as paginas de disco. Mas nós sabemos, que somente as mudanças feitas deste o ultimo checkpoint não estão sincronizadas no disco. O mecanismo automático de recovery se previne de recuperar essas mudanças feitas desde o ultimo checkpoint.

segunda-feira, 18 de julho de 2011

Componente do Disco

Chunks

O servidor não usa o sistema de arquivo do UNIX para fazer a sua administração de espaço em disco, mas apropriadamente, ele utiliza seus próprios mecanismos de gerenciamento do espaço em disco – mecanismos que são bem melhores adaptados à gerencia de banco de dados do que o sistema de arquivo do UNIX.

É necessário construir um espaço disponível para o servidor. Este espaço é associado em unidades chamadas chunks. Um chunk é uma unidade de espaço continuo que é associado ao servidor para seu uso; o servidor administrará o uso do espaço dentro de cada chunk. Um chunk pode ser um raw device do UNIX.

Paginas

Quando um chunk é associado ao servidor, ele será quebrado em pequenas unidades chamadas paginas. A pagina é a unidade básica de I/O de um servidor Informix. Todos os dados em um servidor são guardados em paginas. Por exemplo, se você quiser guardar uma linha de uma tabela do banco de dados, o dado para esta linha deve ser guardado em uma pagina. Quando o dado é lido do disco para um buffer na shared memory, a pagina inteira na qual este dado esta guardado será lida para dentro do buffer. Uma grande quantidade de dados pode ser guarda em uma única pagina.

Page Size

O tamanho de uma pagina usada por um servidor é determinado quando o porte é feito para uma maquina / sistema em particular. O tamanho mais comum de pagina usado é 2 Kbytes, embora alguns sistemas usem um tamanho de 4 Kbytes.

O tamanho da pagina para um servidor não pode ser alterado. Isto é exceto, para blobpages, as quais são atualmente um tamanho logico de paginas ou um numero que representa um múltiplo do tamanho da pagina do servidor.

Tblspaces

Um tblspace é um termo logico usado para referir-se a uma coleção logica de todas as paginas alocadas para uma determinada tabela ou um fragmento de tabela se sua tabela esta fragmentada.

O espaço representando por um tblspace não é necessariamente continuo, aqui pode haver paginas espalhadas por um chunk, ou pode haver paginas de uma tabela em diferentes chunks.

Para tabelas não fragmentadas, um tblspace residira sempre em um dbspace. Se o dbspace tem somente um chunk associado a ele, então todas as paginas de um tblspace residirão sobre este único chunk. Se o dbspace tem vários chunks associados a ele, as paginas de um tblspace podem residir em qualquer dum dos chunks naquele dbspace.

Para tabelas fragmentadas, cada fragmento tem um tablespace id único. Este numero de tablespace é o partnum na systables do catalogo do sistema, e o campo partn em sysframents.

Dbspaces

dbspace

Um dbspace é uma coleção de chunks. Cada dbspace deve ter no mínimo um chunk associado a ele inicialmente; este é conhecido como primary chunk. Dbspaces podem ter tantos chunks associados a ele quanto necessário. Se você esgotar o espaço em um dbspace particular ( em virtude de que todos os chunks associados a ele estão cheios), você pode adicionar chunks extras a ele.

Banco de dados e tabelas pode ser criados em dbspaces separados. Isto significa que aquela tabela ou banco de dados pode crescer tanto quanto o espaço disponível naquele dbspace. Você não pode controlar em quais chunks dentro de um dbspace um banco de dados serão criados em um device físico em especifico, você de associar somente aqueles chunks residentes no device físico ao dbspace.

Root Dbspace

Cada servidor deve ter no mínimo um dbspace; o root dbspace. Este é onde todas as informações importantes do sistema que controlam o servidor estão localizados.

Agrupamento Logico

dbspaces e tblspaces

Podemos pensar em dbspaces e tblspaces como agrupamentos lógicos de espaço físico.

  • Um dbspace é um agrupamento logico de chunks físicos. Os chunks pode estar em diferentes discos, contudo eles são parte de um mesmo dbspace.
  • Um tblspace é um agrupamento logico de extents. Os extents dentro de um tblspace podem estar em chunks diferentes (e, portanto em discos diferentes).

Tipo de Dado Blob

Bynary Large Objects, BLOBs, são conjuntos de bytes de comprimento e valor indeterminado. Um BLOB pode ser uma imagem ou som digitalizado, um modulo de programa ou um contrato legal.

Qualquer coisa que você pode guardar em um arquivo de um computador você pode guardar um um BLOB.

O limite teórico para o tamanho deles é de 2 gigabytes; este tamanho é baseado no maior valor que pode ser armazenado em inteiro de 4-bytes.

Ha dois tipos de BLOBs: TEXT e BYTE. O tipo de dado TEXT é usado para armazenar textos ASCII como memorandos capítulos de manuais e documentos de negócios. O tipo de dado BYTE é usado para arquivar qualquer classe de dado binário, como planilhas, módulos de programas de carga, e imagens e sons digitalizados.

Blobspace

Um blobspace é uma entidade logica que representa uma coleção de espaços físicos na forma de chunks.

Cada blobspace deve ter no mínimo um chink associado a ele; o qual é conhecido como o primary chunk. Blobspaces podem ter tantos chunks associados a ele quanto for necessário.

Colunas BYTE e TEXT podem ser colocadas em blobspace separados. Isto significa que os dados destas colunas blob serão guardados naquele blobspace. Você não pode controlar em qual chunk, dentro de um blobspace o dado blob será guardado. Um servidor pode ter tantos blobspaces quanto queria. Qualquer blobspace pode conter dados blob de diferentes colunas de diferentes tabelas, mesmo de diferentes banco de dados. O blobspace forma um conjunto de espaço de armazenamento que pode ser usado por qualquer coluna blob no servidor.

Todos os arquivos de blobs em um único blobspace, mesmo que estes estejam em tabelas diferentes , usarão o mesmo tamanho de blobpage. Cada blobspace arquiva um dado blob usando o mesmo tamanho de blobpage. Você pode ter vários blobspaces, e cada blobspace pode ter um diferente tamanho de blobpage do que os outros.

 

Mirroring (Espelhamento)

Mirroring é um processo de replicação de dados automático. O servidor permite a escolha de Mirroring ao nível de dbspaces ou blobspaces. Em casos quando há requerimentos para segurança e disponibilidade, o disco mirroring é um dos vários aspectos para escolher. Sem o disco mirroring, o retorno de uma queda de um disco geraria:

  • Torna o dado indisponível para o usuário.
  • Substituição do hardware que teve a falha.
  • Restauração de fitas de backup.
  • Rollback de alguns logs de transação.

Com o disco mirroring, a recuperação pode ser completada sem nenhuma interrupção para a disposição de dados.

A escolha para o mirror de disco é feita quando o servidor esta sendo inicializado (initialize). Apesar disso, mirror de dbspaces ou blobspaces individuais, pode ser feito a qualquer momento.

Quanto um dbspaces ou blobspace é espelhado, ambos, primary chunk e mirror chunk são especificados nas criações do espaço ou sempre que um novo chunk precisar ser adicionado. As escritas feitas para o primary chunk e para o mirror chunk são assíncronas. As leituras são separadas entre o primary e o mirror chunk para o aumento de performance.

Logical Logs

Dentro dos limites de um servidor,  uma certa quantidade do espaço do disco será reservada para o logical logs.

O logical logs são coleções de paginas continuas de um disco que são usadas para registrar transações arquivadas para o servidor. Estas transações registradas são usadas para mapear todas as mudanças que são feitas no database server. Toda mudança no banco esta registrada no logical log. Cada servidor deve ter no mínimo três logical logs.

Physical Log

O servidor tem um log especial que é usado para propósitos de recuperação automática. Este log é chamado de physical log. O physical log é uma coleção de paginas continuas sobre o disco.

Quando uma pagina tem que ser lida dentro de um shared memory buffer, e um usuário quer modificar dados naquela pagina, antes que a mudança seja feita, uma copia da pagina em sua forma original é gravada no physical log. Esta copia de pagina é conhecida como before image. Somente a primeira mudança para uma pagina em um buffer ocasionará um before image para ser gravada no physical log. Outras mudanças subsequentes para aquela mesma pagina não causarão before images adicionais para serem escritas no physical log. Estas before images serão usados por um mecanismo automático de recuperação.

Shared Memory: The Message Portion

residen

A message portion da shared memory ou porção de comunicação é alocada quando o servidor é iniciado. A message portion contém os message buffers para as aplicações clientes locais que usam a shared memory na comunicação com o servidor.

As aplicações cliente e o servidor ligam-se ao mesmo segmento de shared memory. O cliente deixa mensagens para o servidor na porção message e depois recupera as mensagens do servidor para ele. O tamanho da porção message é aproximadamente de 12 Kb para cada usuário que use a shared memory para se comunicar com o servidor.

The Virtual Portion: Exemplo de Cache

cache

A virtual portion da shared memory contem memory pools que são designados a manter tabelas de catalogo do sistema para uso das sessões.

Qualquer sessão executando um comando SQL que necessite de informações sobre as tabelas pela primeira vez, deve recuperar estas informações das tabelas de catalogo do sistema. Isto exige uma leitura de disco para obtenção das paginas das tabelas de catalogo do sistema que não estão nos shared memory buffer pools. Uma vez que o servidor de banco de dados lê as paginas que contem o catalogo do sistema, a informação para a tabela é colocada em uma estrutura que é mais eficiente para a o acesso  do servidor de banco de dados.

Esta estrutura é parte do shared memory dictionary pool. Apos o primeiro acesso de uma usuário, todos os usuários podem acessar os dictionary pools para obter a informação do dictionary da tabela, ganhando tempo e memoria.

Outro exemplo de manutenção de tabelas em memoria é a manutenção de stores procedures. O valor default para este pool é de 50 stored procedures. Deste modo, usuários acessando stored procedures não terão que recupera-las sempre do disco.

sexta-feira, 8 de julho de 2011

Datas de Calendário em Informix

O tipo de dados DATE armazena uma data do calendário.  Um valor DATE é um numero inteiro representando o numero de dias corridos desde meia-noite do dia 31 de dezembro de 1899.

O formato DATE tem precisão suficiente para realizar as datas para o futuro distante (58.000 séculos). Valores DATE negativos são interpretados como contagem de dias antes da data de época; isto é, um valor DATE –1 representa 30 de dezembro de 1899.

Os valores DATE por ser inteiros, podem ser usados em expressões aritméticas.  Por exemplo, você pode querer a média de uma coluna DATE, ou você pode adicionar 7 ou 365 para uma coluna DATE. Além disso, um rico conjunto de funções existem especificamente para manipular valores de data.

O tipo de dados DATE é compacto, 4 bytes por item. Funções aritméticas e comparações são executadas rapidamente em colunas DATE.

Função MONTHS_BETWEEN

A função MONTHS_BETWEEN requer dois argumentos, cada um dos quais podem ser uma expressão DATE ou DATETIME. Se o primeiro argumento maior que o primeiro, o valor retornado é positivo.

O valor retornado é tipo DECIMAL, representando a diferença entre os dois argumentos, expresso como um valor decimal. Se o primeiro argumento é menor que o segundo argumento, o valor retornado é negativo.

Se as datas do argumentos forem os mesmos dias de um mês ou são os últimos dias de um mês, o resultado é um numero inteiro. Senão um resultado em fração é retornado, com base em um mês de 31 dias. Esta parte fracionaria também pode incluir a diferença na hora, minutos ou segundos, a menos que ambos os argumentos sejam uma expressão DATE.

Abaixo uma query chamando uma função MONTHS_BETWEEN, usando dois valores DATE.

SELECT  MONTHS_BETWEEN((SELECT DATE(parametro_dat)
                                        FROM ped_info_compl
                                        WHERE empresa = a.empresa
                                        AND pedido = a.pedido
                                        AND campo = 'Data Final Projeto'), (SELECT DATE(parametro_dat)
                                                                                         FROM ped_info_compl
                                                                                         WHERE empresa = a.empresa
                                                                                         AND pedido = a.pedido
                                                                                         AND campo = 'Data Inicial Projeto'))
FROM ped_info_compl a
WHERE a.empresa = '01'
AND a.pedido = 18188

O valor retornado da query acima seria de 12 meses, nesse exemplo que coloquei ai, o primeiro argumento desse pedido esta com com o campo definido em DATATIME e seu conteúdo é 2011-07-06 00:00:00 e o segundo argumento tem o seguinte conteúdo 2012-07-06 00:00:00, por isso o retorno seria 12 inteiros.

Função ADD_MONTH

A função ADD_MONTHS trabalha com a expressão DATETIME ou DATE como um primeiro argumento, e requer como segundo argumento um inteiro, especificando o numero de meses para adicionar ao primeiro argumento. O secundo argumento pode ser positivo ou negativo.

O Valor que é retornado é a soma de um valor DATE ou DATETIME do primeiro argumento e um valor INTERVAL UNITS MONTH que é baseado em um numero de meses especificado no segundo argumento.

O tipo de dados retornados depende do tipo de dados do primeiro argumento:

  • Se o primeiro argumento for um valor DATE, ADD_MONTHS retornara um valor DATE;
  • Se o primeiro argumento for um valor DATETIME, ADD_MONTHS retornara um valor DATETIME YEAR TO FRACTIONS(5), com os mesmos valores para unidades de tempo menor do dia como no primeiro argumento.

Se a unidade de tempo day e month especificado no primeiro argumento é o ultimo dia do mês, ou se o mês resultante tem menos dias que o primeiro argumento, então o valor retornado é o ultimo dia do mês em questão. Caso contrario o valor retornara a mesma quantidade de dias do mês do primeiro argumento.

O valor retornado pode ser um ano diferente, se o mês resultante for maior que dezembro ( ou o segundo argumento for um numero negativo, menor que janeiro) do ano do primeiro argumento. Veja os exemplos abaixo:

Uma Query onde é um resultado normal

SELECT order_date
FROM ami_backlog_prev
WHERE order_num = 18188

Resultado

order_date   
-------------
04/05/2011

Adicionando 5 meses

SELECT ADD_MONTHS(order_date,5)
FROM ami_backlog_prev
WHERE order_num = 18188

(expression)   
---------------
04/10/2011 

Adicionando 12 meses

SELECT ADD_MONTHS(order_date,12)
FROM ami_backlog_prev
WHERE order_num = 18188

(expression)   
---------------
04/05/2012
     

Tirando 3 meses

SELECT ADD_MONTHS(order_date,-3)
FROM ami_backlog_prev
WHERE order_num = 18188

(expression)   
---------------
04/02/2011

Tirando 12 meses

SELECT ADD_MONTHS(order_date,-12)
FROM ami_backlog_prev
WHERE order_num = 18188

(expression)   
---------------
04/05/2010
  

Função DATE

A função DATE converte um argumento para um valor DATE. O seu argumento não DATE pode ser qualquer expressão que possa ser convertido para um valor DATE, geralmente um CHAR, DATETIME ou um valor INTEIRO, veja o  exemplo abaixo:

SELECT *
FROM pedidos
WHERE num_pedido < DATE ('31/12/07’)

segunda-feira, 4 de julho de 2011

Execução de Gatilhos (Triggers)

Um gatilho (trigger) é um mecanismo de banco de dados que executa uma instrução SQL automaticamente quando um determinado evento ocorrer. Você pode criar um gatilho em uma tabela para executar um SELECT, INSERT, UPDATE ou DELETE.

Quando se cria um gatilho com a declaração CREATE TRIGGER, o database server coloca informações sobre a trigger no system catalog (systriggers). O server coloca a declaração de que o gatilho é executado dentro do system catalog (systrigbody). Além disso, tabelas de dicionário são armazenados na memoria para indicar se a tabela possui gatilhos definidos para ele. Sempre que o servidor executa uma declaração SELECT, INSERT, UPDATE ou DELETE, verifica se um gatilho esta definido para o tipo de declaração e a tabela e coluna na qual a instrução opera. Se uma declaração requer um gatilho pra ser executado, o server  recupera o texto de instrução de systrigbody e executa a rotina SPL, quando necessário, antes, durante e apos a instrução.

SINTAXE:

Skip visual syntax diagram>>-CREATE TRIGGER--+---------------------+--trigger------------->
| (1) |
'-| Owner Name |------'

>--+---------------------------------------------------+-------->
| (2) |
+-| Trigger on a Table |----------------------------+
| (3) |
'--------INSTEAD OF--+----------------------------+-'
| (4) |
'-| Trigger on a View |------'

(3) .-ENABLED--.
>---------+-DISABLED-+-----------------------------------------><


 



Um gatilho, exceto se for desativado, executa automaticamente um conjunto de instruções SQL, chamada trigger action, quando um evento especifico de gatilho ocorrer.



Quando se dispara um gatilho



Pode-se utilizar a declaração CREATE TRIGGER de duas maneiras distintas:




  • Pode-se definir um gatilho em um tabela no banco de dados corrente;


  • Para o IDS, pode-se também definir um gatilho INSTEAD OF em uma view no banco de dados corrente.



Qualquer instrução SQL que é uma instancia do evento da trigger é chamado de instrução de acionamento (triggering statement), quando o evento ocorre, gatilhos definidos em tabelas e gatilhos definidos em view são tratadas de maneiras diferentes quando executada:




  • Para tabelas, o trigger event e o trigger action são executados


  • Para views, somente o trigger action é executado, ao invés do evento.



A declaração CREATE TRIGGER pode suportar a integridade dos dados no banco através de definição de regras pelas operações DML (o triggering events) o que faz com que o servidor tome ações especificas.



pode suportar a integridade dos dados no banco de dados através da definição de regras pelas quais especificado operações DML (a fatos geradores) fazer com que o servidor de banco de dados para tomar ações especificadas.



Exemplo de gatilho em uma tabela:



|--+-+-DELETE----------------------------+--ON--table--| DELETE and SELECT Subclauses |-+--|
| | (1) | |
| '--------SELECT--+----------------+-' |
| | .-,------. | |
| | V | | |
| '-OF----column-+-' |
+-UPDATE--+----------------+--ON--table--| UPDATE Subclauses |-----------------------+
| | .-,------. | |
| | V | | |
| '-OF----column-+-' |
| (2) (3) |
'-INSERT--ON--table--+-| NEW Declaration |-------| Correlated Table Action |------+--'
| (4) |
'-| Action Clause |------------------------------------------'


 


Sub-clausula DELETE e SELECT:


                      (4)
|--+-| Action Clause |--------------------------------------------------------------------+--|
| (5) (3) |
+-| OLD Declaration |-------| Correlated Table Action |--------------------------------+
| (5) (2) (3) |
'-| OLD Declaration |-------| NEW Declaration |-------| Correlated Table Action |------'


 


Gatilho em uma View:


   (1)
|--------------------------------------------------------------->

>--+-INSERT ON--view--+------------------------------+------------------------+-->
| '-REFERENCING NEW--+----+--new-' |
| '-AS-' |
+-DELETE ON--view--+-------------------------------+-----------------------+
| '-REFERENCING--OLD--+----+--old-' |
| '-AS-' |
'-UPDATE ON--view--+-----------------------------------------------------+-'
+-REFERENCING--OLD--+----+--old--+------------------+-+
| '-AS-' '-NEW--+----+--new-' |
| '-AS-' |
'-REFERENCING--NEW--+----+--new--+------------------+-'
'-AS-' '-OLD--+----+--old-'
'-AS-'


 


Restrições dos Gatilhos


Para criar uma trigger em uma tabela ou uma View, deve-se possuir direitos sobre a tabela ou view, ou ter status de DBA.  


A tabela na qual esta criando o gatilho deve existir no banco de dados. Não pode criar uma trigger em qualquer das seguintes situações:



  • Uma tabela de diagnostico,  uma tabela violada ou uma tabela em outro banco de dados;


  • uma raw table, uma tabela temporária ou tabela do system catalog.



No DB-Acess, se você quiser definir um gatilho como parte de uma esquema, coloque a declaração CREATE TRIGGER dentro de uma declaração CREATE SCHEMA.



Se você estiver incorporando uma instrução CREATE TRIGGER em um programa de ESQL/C, não se pode utilizar uma variável na definição da trigger.



Não pode usar a declaração DROP TRIGGER para remover uma trigger existente. Se você usar DROP TABLE ou DROP VIEW para remover gatilhos em tabelas ou view do banco de dados, todas as triggers nessa tabela ou view serão dropadas.