Baixe o app para aproveitar ainda mais
Prévia do material em texto
Objetivos Entender a arquitetura de instância única; Conhecer as estruturas de memória; Conhecer as estruturas de processos; Resumir as estruturas de armazenamento. Introdução Um servidor Oracle é composto de duas entidades: a instância e o banco de dados. A instância são as estruturas de memória e os processos. O banco de dados são os arquivos no disco. Eles são separados, mas conectados. Durante o processo de criação, a instância é criada primeiro e, depois, o banco de dados. Durante o processo de inicialização, a instância é inicializada primeiro e, depois, o banco de dados é aberto. Em um ambiente típico de instância única, o relacionamento da instância com o banco de dados é de um-para-um, uma única instância conectada a um único banco de dados. No entanto, lembre-se sempre de que existem possibilidades mais complexas para ambientes distribuídos. No servidor Oracle, há uma abstração completa entre o armazenamento lógico e o armazenamento físico. As estruturas lógicas que os programadores veem (como as tabelas) não estão diretamente relacionadas às estruturas físicas (arquivos de dados) que os administradores de sistema veem. O relacionamento entre as duas é mantida por estruturas no arquivo de controle e no dicionário de dados. Arquitetura de instância única O ambiente de banco de dados mais comum: uma instância em um computador, abrindo um banco de dados armazenado em discos locais. As arquiteturas distribuídas mais complexas, que envolvem várias instâncias e vários bancos de dados, estão além do escopo do exame de OCP (embora não da qualificação de OCM). Arquitetura de banco de dados de instância única A instância é composta de estrutura de memória e processos. Sua existência é temporária, na memória RAM e na (s) CPU (s). Quando você desliga a instância em execução, todos os vestígios da sua existência desaparecem. O banco de dados é composto de arquivos físicos no disco. Esteja ele em execução ou parado, os arquivos permanecem. Assim, o tempo de vida da instância é apenas o período de sua permanência na memória: ela pode ser iniciada e parada. Por outro lado, o banco de dados, uma vez criado, persiste indefinidamente – até que você deliberadamente exclua os arquivos que estão associados ao banco de dados. Os processos que compõem a instância são conhecidos como processos de segundo plano (ou processos background), porque estão presentes e em execução o tempo todo enquanto a instância está ativa. Esses processos são, em grande parte, completamente auto administrados, embora, em alguns casos, o DBA possa influenciar alguns deles e suas operações. As estruturas de memória, implementadas em segmentos de memória compartilhados fornecidos pelo sistema operacional, são conhecidos como a área de sistema global ou SGA (System Global Área). Essa área é alocada na inicialização da instância e liberada no desligamento. Dentro de certos limites, a SGA e seus componentes na instância do 12c podem ser redimensionados enquanto a instância está em execução, tanto automaticamente quanto em resposta às instruções do DBA. As sessões de usuários são compostas de um processo de usuário executando localmente na máquina do usuário, conectando a um processo de servidor executando localmente na máquina do servidor. A conexão entre o processo de usuário e o processo do servidor é feita, em geral, por meio de uma rede local e usa o protocolo Oracle Net proprietário da Oracle sobre um protocolo padrão de mercado (normalmente, o TCP). A divisão do processo de usuário processo para servidor implementa a arquitetura cliente-servidor: os processos de usuário geram as instruções SQL, que serão executadas pelos processos de servidor. Os processos do servidor são, às vezes, referenciados como processos em primeiro plano (foreground processes), contrastando com os processos em segundo plano que fazem parte da instância. Associada a cada processo do servidor está uma área da memória não compartilhável, denominada área global de programa (program global area) ou PGA. Essa é uma área privada para a sessão, ao contrário da área global de sistema, que está disponível para todos os processos em primeiro e segundo planos. Observe que os processos em segundo plano também têm uma PGA. O tamanho da PGA de qualquer sessão irá variar de acordo com as necessidades de memória da sessão em um dado momento. O DBA pode definir um limite superior para o total de todas as PGAs, e o Oracle gerencia dinamicamente a alocação dessas áreas para as sessões. O gerenciamento de memória no 12c pode ser totalmente automático: o DBA não precisa fazer nada mais do que especificar uma alocação de memória global tanto para a SGA quanto para a PGA e deixar que o Oracle gerencie essa memória como ele achar melhor. Como alternativa, o DBA pode controlar diretamente as alocações de memória. Há uma técnica intermediária, na qual o DBA define certos limites sobre o que o gerenciamento automático pode fazer. As estruturas físicas que compõem um banco de dados Oracle são os arquivos de dados, os arquivos de redo log e o arquivo de controle (controlfile). Dentro das estruturas físicas do banco de dados, que nossos administradores de sistema veem, estão as estruturas lógicas que nossos usuários finais (desenvolvedores, analistas de negócios, arquitetos de data warehouse e assim por diante) veem. A arquitetura do Oracle garante a abstração da estrutura lógica da física: não há como um programador determinar onde, fisicamente, determinado dado está localizado. Ele lida somente com as estruturas lógicas, como tabelas. Da mesma maneira, é impossível um administrador de sistemas saber quais dados estão em qualquer estrutura física: tudo o que ele pode ver são os arquivos do sistema operacional, não o que eles contêm. Só você, o administrador do banco de dados, pode (e precisa) ver os dois lados da história. A abstração do armazenamento lógico para o armazenamento físico faz parte do padrão RDBMS. Se um programador pudesse determinar o local físico de uma linha, o sucesso da execução do código seria totalmente dependente do ambiente para o qual ele foi criado. Fazer qualquer alteração na plataforma, movimentar arquivos de dados ou mesmo renomear um arquivo causaria uma falha na aplicação. Na verdade, é possível determinar o local físico de uma tabela (e até mesmo o local físico de uma linha dentro de uma tabela), mas não por SQL. A linguagem não permite. Existem ferramentas que o administrador de banco de dados pode usar para fazer isso, caso seja necessário. Os dados são armazenados em arquivos de dados. A abstração do armazenamento lógico para o armazenamento físico significa que os arquivos de dados podem ser movidos ou redimensionados, e que mais arquivos de dados podem ser adicionados sem que os desenvolvedores das aplicações tenham conhecimento disso. O relacionamento entre as estruturas físicas e lógicas é mantido e documentado no dicionário de dados, que contém os metadados que descrevem o banco de dados inteiro. Por meio de consultas a certas visões no dicionário de dados, o DBA pode determinar precisamente onde está cada parte de cada tabela. O dicionário de dados é um conjunto de tabelas armazenado no banco de dados. Um requisito do padrão RDBMS é que o banco de dados não deve perder dados. Isso significa que deve passar pelo processo de backup e, além disso, que quaisquer alterações feitas aos dados entre os backups devem ser capturadas de maneira que possam ser aplicadas a um backup restaurado. Esse é o processo de Recuperação Avançada Dica de Exame A memória SGA é compartilhada entre todos os processos de segundo e primeiro planos. A memória PGA só pode ser acessada pelo processo de primeiro plano da sessão para a qual ela foi alocada. Tanto a memória SGA quanto a PGA podem ser gerenciadasautomaticamente. (forward recovery process). O Oracle implementa a captura das alterações por meio do redo log. O redo log é um registro sequencial de todos os vetores de alteração (change vectors) aplicados aos dados. Um vetor de alteração é a alteração feita por uma instrução DML (Data Manipulation Language: INSERT, UPDATE ou DELETE). Sempre que uma sessão de usuário faz algumas alterações, os dados no bloco de dados são alterados, e o vetor de alteração é escrito em paralelo no redo log, de forma que o torna repetível. Assim, caso ocorra um dano a um arquivo de dados, um backup do arquivo pode ser restaurado e o Oracle extrairá os vetores de alteração relevantes do redo log e os aplicará aos blocos de dados dentro do arquivo. Isso assegura que o trabalho nunca será perdido – a menos que o dano causado ao banco de dados seja tão grande que provoque a perda não apenas de um ou mais arquivos de dados, mas também de seus backups ou do redo log. O arquivo de controle armazena os detalhes das estruturas físicas do banco de dados e é o ponto de partida para o link para as estruturas lógicas. Ao abrir um banco de dados, a instância primeiro lê o arquivo de controle. No arquivo de controle estão às informações que a instância pode usar para se conectar ao restante do banco de dados e ao dicionário de dados dentro dele. Obs.: Não existe um limite prático para a capacidade de armazenamento do banco de dados Oracle. A título de informação, a capacidade total de armazenamento de um banco de dados Oracle 12c chega aos 8 EX (exabytes). Esse limite deve-se ao fato de que o banco de dados Oracle 12c suporta até 65.536 tablespaces, cada uma com um arquivo de dados de até 128TB de tamanho, logo, 64k * 128T = 8EX. Confira na documentação da Oracle os limites do banco de dados: http://docs.oracle.com/database/121/REFRN/GUID-ED26F826-DB40-433F- 9C2C-8C63A46A3BFE.htm. A arquitetura de um banco de dados de instância única pode ser resumida como composta de quatro componentes interagentes: Um usuário interage com um processo de usuário. Um processo de usuário interage com um processo de servidor. Um processo de servidor interage com uma instância. Uma instância interage com um banco de dados. É impossível que um processo do lado do cliente tenha algum contato com o banco de dados: todos os acessos devem ser realizados pelos processos do lado do servidor. A divisão cliente-servidor está entre o processo de usuário (que gera o SQL) e o processo de servidor (que o executa). Arquitetura de sistemas distribuídos No ambiente de instância única, uma instância abre um banco de dados. Em um ambiente distribuído, existem várias possibilidades para agrupar instâncias e bancos de dados. Principalmente: Real Application Clusters (RAC), onde várias instâncias abrem um banco de dados Streams (fluxos de gravação), onde vários servidores Oracle propagam as transações entre si Data guard, em que o banco de dados primário atualiza um banco de dados standby As combinações dessas opções podem (de acordo com as informações divulgadas pela Oracle) resultar em um sistema que pode alcançar as metas de 100% de tempo de atividade e 0% de perda de dados, com desempenho e escalabilidade ilimitados. Real Application Clusters (RAC) O RAC fornece capacidades surpreendentes de desempenho, tolerância a falha e escalabilidade (e, possivelmente, economia) e é essencial ao conceito de Grid da Oracle. Com as versões anteriores, o RAC (ou seu precursor, o Oracle Parallel Server) era uma opção adicional cara, mas a partir do banco de dados versão 10g em diante, o RAC está incluído no pacote com a licença da edição Standard. Essa é uma indicação do quanto a Oracle Corporation deseja levar os usuários para o ambiente RAC. A edição Standard do Banco de Dados com RAC está limitada a certo número de computadores e certo número de CPUs e núcleos por computador, mas, mesmo com essas limitações, ela fornece acesso a um ambiente maravilhosamente poderoso. O RAC é uma opção de custo adicional para edição Enterprise do Banco de Dados Oracle, onde a escalabilidade torna-se efetivamente ilimitada: delimitada apenas pela capacidade de clusterização do sistema operacional e hardware subjacentes. Um banco de dados em RAC pode ser configurado para um tempo de atividade de 100%. Uma instância pode ser desativada (para manutenção planejada ou, talvez, porque o computador no qual ela está executando entrou em pane) e o banco de dados permanecerá acessível por meio de uma instância sobrevivente em outra máquina. As sessões na instância com falha podem ser migradas para uma instância sobrevivente sem que o usuário tome conhecimento de nenhuma interrupção. A escalabilidade transparente é proveniente da habilidade de adicionar instâncias, executando em diferentes máquinas, a um RAC, de forma dinâmica. Elas assumem automaticamente uma parte da carga de trabalho sem que os usuários precisem tomar conhecimento do fato de que agora mais instâncias estão acessíveis. Algumas aplicações terão uma vantagem de desempenho por serem executadas em um RAC, mas nem todas. O processamento paralelo pode melhorar o desempenho de alguns trabalhos, como consultas de longa duração e grandes atualizações de lote. Em um banco de dados de instância única, atribuir vários servidores de execução paralela a tais tarefas ajudará – mas eles estarão executando em uma instância em uma máquina. Em um banco de dados RAC, os servidores de execução paralela podem executar em diferentes instâncias, o que pode evitar alguns gargalos inerentes a uma arquitetura de instância única. Outros trabalhos, como processar uma grande quantidade de transações pequenas normalmente encontradas em um sistema OLTP (Online Transaction Processing), não obterão vantagem no desempenho. Obs.: A edição Standard do Banco de Dados Oracle pode ser licenciada para servidores com até quatro CPUs. Como comentado, o Real Application Clusters está incluso nessa licença sem custos adicionais. No caso de ambientes de cluster, a edição Standard do Oracle só poderá ser licenciada para um cluster com até quatro CPUs (ou seja, dois servidores com duas CPUs cada ou quatro servidores com uma CPU cada). Streams (fluxos de gravação) Existem várias circunstâncias que tornam desejável a transferência de dados de um banco de dados para outro. A tolerância a falhas é uma delas: se uma organização tem dois (ou mais) bancos de dados separados geograficamente, ambos contendo dados idênticos e disponíveis o tempo todo para que os usuários possam trabalhar, independentemente do que possa estar errado em um site, o trabalho deve ser capaz de continuar de modo interrupto no outro. Outra razão é o ajuste de desempenho: os dois podem ser configurados para diferentes tipos de trabalho, como um banco de dados de processamento de transações e um data warehouse. Manter os bancos de dados sincronizados terá de ser um procedimento completamente automático e todas as alterações feitas em qualquer um dos sites precisará ser propagado em tempo real, ou quase real, para o outro site. Outra razão poderia ser a manutenção de um data warehouse. Os conjuntos de dados mantidos por um banco de dados OLTP precisarão ser propagados para o banco de dados warehouse e, subsequentemente, essas cópias deverão ser periodicamente atualizadas com as alterações. Os dados também seriam introduzidos, talvez, em uma série de data marts cada um deles sendo um subconjunto do warehouse. O Oracle Streams é um recurso para capturar as alterações feitas às tabelas e aplicá-las às cópias remotas das tabelas que preencham ambos os requisitos. O fluxo de gravação pode ser bidirecional: tabelas idênticas em dois ou mais sites, com todas as transações de usuários executadas em um transmitido e aplicado aoutros sites. Esse é o modelo de fluxo de dados necessário para a tolerância a falhas. Um modelo alternativo é usado no exemplo do data warehouse, onde os conjuntos de dados (e, consequentemente, as alterações feitas a eles) são extraídos das tabelas em um banco de dados e introduzidos em tabelas de outro. Nesse modelo, o fluxo da informação é unidirecional, e as estruturas de tabela podem não ser idênticas aos locais de destino do Streams. O Streams também pode ser usado para tolerância a falhas. Não é incomum fazer fluxos de gravação de um banco de dados inteiro entre várias instâncias, com os usuários finais trabalhando em ambos os lados. O Streams propagará as alterações entre as instâncias, bidirecionalmente, para manter os dois bancos de dados sincronizados. Se um servidor de banco de dados falhar, o trabalho poderá continuar no servidor sobrevivente. Quando o servidor com falha for colocado de volta online, ele será atualizado com todas as alterações feitas no seu parceiro enquanto estava indisponível. Uma sessão em uma instância também pode se conectar a vários bancos de dados programaticamente por meio de links de bancos de dados. Os programadores podem escrever um código que permita que uma sessão em um servidor leia e atualize os dados em outro servidor por um link de banco de dados. Existe um mecanismo de commit em duas fases totalmente automatizado para garantir a consistência transacional nessas circunstâncias. Data Guard Os sistemas com Data Guard têm um banco de dados primário no qual as transações são executadas, e um ou mais bancos de dados standby usados para tolerância a falhas ou para processamento de consultas. Os standbys são instanciados a partir de um backup do primário e atualizados (possivelmente em tempo real) com todas as alterações aplicadas ao primário. Os standbys vêm em dois formatos. Um standby físico é idêntico byte- por-byte ao primário para atender à meta de zero perda de dados. Mesmo se o primário for totalmente destruído, todos os dados estarão disponíveis no standby. Os vetores de alteração aplicados ao primário são propagados para o standby físico na forma de registros de redo e aplicados como se um banco de dados de backup estivesse sendo recuperado. Um standby lógico contém os mesmos dados do banco primário, mas possivelmente com estruturas de dados diferentes. Esse ambiente visa ao processamento de consultas: o banco de dados primário terá estruturas de dados otimizadas para o processamento de transações; o standby lógico terá estruturas otimizadas para data warehousing. As diferenças típicas seriam nos índices. Os vetores de alteração são propagados na forma de instruções SQL, usando o mecanismo de Streams. Exemplo prático 1. Determine se a instância é parte de um banco de dados RAC: SQL> select parallel from v$instance; Resposta: NO se for um banco de dados de instância única. 2. Determine se o recurso Streams foi configurado no banco de dados: SQL> select * from dba_streams_administrator; Resposta: Essa instrução não retornará nenhuma linha se o Streams não tiver sido configurado. Conhecer as estruturas de memória Uma instância do Oracle é composta por um bloco de memória compartilhada conhecida como área global de sistema, ou SGA, e vários processos em segundo plano. No mínimo, a SGA conterá três estruturas de dados: O cache de buffer do banco de dados O buffer de log O shared pool Opcionalmente, ela também pode conter: Um large pool Um Java pool Um Strems pool As sessões de usuário também precisam de memória no servidor. Essa memória não compartilhável é conhecida como a área global de programa, ou PGA. Cada sessão terá sua própria PGA privada. O gerenciamento do tamanho dessas estruturas pode ser automático ou o próprio DBA pode controlar o dimensionamento. Em geral, é uma boa prática usar o gerenciamento automático. Cache de buffer do banco de dados O cache de buffer do banco de dados é a área de trabalho do Oracle para execução de SQL. Ao atualizar os dados, as sessões dos usuários não atualizam diretamente no disco. Os blocos que contêm os dados de interesse são primeiramente copiados no cache de buffer do banco de dados. As alterações (como inserção de novas linhas e exclusão ou modificação de linhas existentes) são aplicadas a essas cópias dos blocos de dados no cache de buffer do banco de dados. Os blocos Dica de Exame Quais estruturas da SGA são obrigatórias e quais são opcionais? O cache de buffer do banco de dados, o buffer de log e o shared pool são obrigatórios. O large pool, o Java pool e o Streams pool são opcionais. permanecerão no cache por algum tempo, até que o buffer que eles estão ocupando seja requisitado para armazenar outro bloco em cache. Durante uma consulta, os dados também utilizam o cache. A sessão calcula quais blocos contêm as linhas de interesse e as copia no cache de buffer do banco de dados. As linhas relevantes são então transferidas para a PGA da sessão para processamento posterior. E, novamente, os blocos permanecem no cache de buffer do banco de dados por algum tempo subsequente. Os arquivos de dados são formatados em blocos de tamanho fixo. As linhas da tabela e outros objetos de dados, como chaves de índice, são armazenadas nesses blocos. O cache de buffer do banco de dados é formatado em buffers de memória, cada um dimensionado para armazenar um bloco. Ao contrário dos blocos, as linhas são de comprimento variável. O comprimento de uma linha dependerá do número de colunas definido para a tabela, se as colunas contiverem realmente alguma informação, e se contiverem, que tipo de informação. Dependendo do tamanho dos blocos (que é definido pelo DBA) e do tamanho de linhas (que depende do projeto e do uso da tabela), pode haver várias linhas por bloco ou uma linha pode se estender por vários blocos. A estrutura de um bloco de dados será descrita na seção “Os arquivos de dados” mais tarde neste capítulo. Teoricamente, todos os blocos que contêm dados acessados com frequência estarão no cache de buffer do banco de dados, minimizando a necessidade de I/O de disco. Como uma utilização típica do cache de buffer do banco de dados, considere um usuário final recuperando um registro de funcionário e atualizando-o, com estas instruções: SQL> select id, nome, preco from tcursos where id=50; SQL> update tcursos set preco = preco * 1.2 where id = 50; SQL> commit; O processo de usuário pediu o id do curso e construiu a instrução SELECT. A instrução SELECT recupera alguns detalhes a serem enviados ao processo de usuário, onde eles serão formatados para exibição. Para executar essa instrução, o processo de servidor da sessão lerá o bloco de dados que contém a linha relevante em um arquivo de dados de um buffer. O processo de usuário iniciará então um diálogo na tela para solicitar alguma alteração a ser feita e verificada. Depois, a instrução UPDATE e a instrução COMMIT serão construídas e enviadas para o processo de servidor para execução. Desde que não tenha sido transcorrido um período de tempo excessivo, o bloco com a linha ainda estará disponível no cache quando a instrução UPDATE for executada. Neste exemplo, a taxa de acesso ao cache de buffer será de 50%: dois acessos a um bloco no cache, mas somente uma leitura do bloco no disco. Um cache de buffer do banco de dados bem ajustado pode resultar em uma taxa de acesso ao cache superior a 90%. Um buffer que armazena um bloco, cuja imagem no cache não é a mesma no disco, é referenciado como um buffer sujo. Um buffer será limpo quando um bloco for inicialmente copiado para ele: nesse ponto, a imagem do bloco no buffer será igual à do bloco no disco. O buffer se tornará sujo quando o bloco que estiver nele for atualizado.Eventualmente, os buffers sujos devem ser gravados de volta no arquivo de dados, quando o buffer ficará limpo novamente. Mesmo depois de gravado no disco, o bloco permanece na memória. É possível que o buffer fique um tempo sem ser sobrescrito por outro bloco. Observe que não há correlação entre a frequência de atualizações de um buffer (ou o número de instruções COMMIT) e quando ele tem de ser gravado de volta nos arquivos de dados. A gravação nos arquivos é feita pelo processo em segundo plano database writer. O tamanho do cache de buffer do banco de dados é crucial para o desempenho. O cache deve ser dimensionado adequadamente para armazenar todos os blocos frequentemente acessados (sejam eles limpos ou sujos), mas não tão grande que possa armazenar blocos raramente necessários. Um cache subdimensionado resultará em uma atividade em disco excessiva, à medida que os blocos frequentemente acessados são lidos continuamente no disco, usados e sobrescritos por outros blocos e, em seguida, lidos no disco de novo. Um cache superdimensionado não é tão ruim (desde que ele não seja tão grande que o sistema operacional tenha de fazer swap de páginas da memória virtual com a memória real), mas pode causar problemas. Por exemplo, a inicialização de uma instância fica mais lenta se ela envolve a formatação de um cache de buffer do banco de dados muito grande. O cache de buffer do banco de dados é alocado na hora da inicialização da instância. Antes da versão 9i do banco de dados, não era possível redimensionar o cache de buffer do banco de dados após o startup sem reiniciar a instância do banco de dados, mas, da versão 9i em diante, ele pode ser redimensionado a qualquer hora. Esse redimensionamento pode ser manual ou (da versão 10g em diante) automático de acordo com a carga de trabalho, se o mecanismo automático tiver sido ativado. Buffer de log O buffer de log é uma área de preparação pequena e de curto prazo para os vetores de alteração antes que eles sejam gravados no redo log no disco. Um vetor de alteração é uma modificação aplicada a algo; a execução de instruções DML gera vetores de alteração aplicados aos dados. O redo log é a garantia do banco de dados de que os dados nunca serão perdidos: sempre que um bloco de dados é alterado, os vetores de alteração aplicados ao bloco são gravados no arquivo de redo log, de onde são extraídos e aplicados aos backups de arquivos de dados, se for necessário restaurar um arquivo de dados. As informações de redo não são gravadas diretamente nos arquivos de redo log pelos processos de servidor de sessão. Se fossem, as sessões teriam de esperar as operações de I/O de disco serem completadas sempre que elas executassem uma instrução DML. Em vez disso, as sessões gravam o redo no buffer de log na memória. Isso é muito mais rápido do que gravar no disco. O buffer de log (que pode conter vetores de alteração de muitas sessões, intercalados entre si) é então gravado no arquivo de redo log. Uma gravação do buffer de log no disco pode ser Dica de Exame O tamanho de cache de buffer do banco de dados pode ser ajustado dinamicamente e pode ser gerenciado automaticamente. um lote de muitos vetores de alteração provenientes de muitas transações. Mesmo assim, os vetores de alteração do buffer de log são gravados no disco praticamente em tempo real – e quando uma sessão emite uma instrução COMMIT, a gravação do buffer de log realmente acontece em tempo real. As gravações são feitas pelo processo em segundo plano gravador de logs, o LGWR. O buffer de log é pequeno (em comparação com outras estruturas de memória) porque ele é uma área de armazenamento de curto prazo. Ele não precisa ter mais do que alguns megabytes, e criá-lo muito maior do que o valor padrão pode prejudicar seriamente o desempenho. O padrão é determinado pelo servidor Oracle e é baseado no número de CPUs do servidor. Não é possível criar um buffer de log menor do que o padrão. Se você tentar, ele será configurado com o tamanho padrão de qualquer jeito. É possível criar um buffer de log maior do que o padrão, mas não é uma boa ideia. O problema é que, quando uma instrução COMMIT é emitida, parte do processo de commit envolve gravar o conteúdo do buffer de log dos arquivos de redo log no disco. Essa gravação ocorre em tempo real e, enquanto estiver sendo processada, a sessão que emitiu a instrução COMMIT ficará suspensa. O processamento da instrução COMMIT é uma parte crítica da arquitetura do Oracle. A garantia de que uma transação que sofreu commit nunca será perdida tem como base o seguinte: a mensagem commit-complete não é retornada para a sessão até que os blocos de dados no cache tenham sido alterados (o que significa que a transação foi concluída) e os vetores de alteração forem gravados no redo log no disco (e, assim, a transação poderá ser recuperada, se necessário). Um buffer de log grande pode significar potencialmente que há mais dados a serem gravados quando uma instrução COMMIT é emitida e, portanto, pode demorar mais tempo para que a mensagem commit-complete seja enviada e a sessão possa continuar o trabalho. O buffer de log é alocado na inicialização da instância e não pode ser redimensionado subsequentemente sem reiniciar a instância. Ele é um buffer circular. À medida que os processos de servidor gravam os vetores de alteração, o endereço de gravação atual muda. O processo log writer grava os vetores em lotes e, à medida que isso é feito, o espaço que ocupam torna-se disponível e pode ser sobrescrito por mais vetores de alteração. É possível que, na hora de pico de atividade, os vetores de alteração sejam gerados mais rapidamente do que o processo log writer possa gravá-los. Caso isso aconteça, toda a atividade DML cessará (por alguns milissegundos) enquanto o log writer limpa o buffer. O processo de flush do buffer de log para o disco é um dos derradeiros gargalos da arquitetura Oracle. Você não pode fazer DML mais rápido do que o LGWR consegue fazer flush dos vetores de alteração para os arquivos de redo log online. Dica de Exame O tamanho do buffer de log é estático, fixado na inicialização da instância. Ele não pode ser gerenciado automaticamente. Shared Pool O shared pool é a mais complexa das estruturas da SGA. Ele é dividido em dezenas de subestruturas, todas gerenciadas internamente pelo servidor Oracle. Esta discussão da arquitetura mencionará apenas quatro componentes do shared pool, resumidamente: O cache de biblioteca O cache de dicionário de dados A área PL/SQL O cache de resultados de funções PL/SQL e consultas SQL Algumas outras estruturas serão descritas nos capítulos posteriores. Todas as estruturas existentes em um shared pool são gerenciadas automaticamente. Seus tamanhos irão variar de acordo com o padrão de atividade na instância, dentro do tamanho global do shared pool. O shared pool pode ser redimensionado dinamicamente, como resposta às instruções do DBA ou por meio de gerenciamento automático. Cache de biblioteca O cache de biblioteca (library cache) é uma área da memória usada para armazenar o código executado recentemente, na sua forma analisada por parse. A análise por parse é a conversão do código escrito pelos programadores em algo executável e é um processo que o Oracle faz por demanda. Armazenar em cache o código analisado por parse no shared pool, para que ele possa ser reutilizado sem a necessidade de ser reanalisado, melhora muito o desempenho. A análise por parse do código SQL é demorada. Considere uma instrução SQL simples: SQL> select * from tclientes where nome = 'Nadia Velasques'; Dica de Exame O tamanho do shared pool é dinâmico e pode ser gerenciado automaticamente. Para que essa instrução seja executada, o servidor Oracle tem de verificaro que ela significa e como executá-la. Para começar, o que é tclientes? É uma tabela, um sinônimo ou uma visão? Ela sequer existe? Depois o “*”_ quais são as colunas que compõem a tabela tclientes (se for uma tabela)? O usuário tem permissão para ver a tabela? As respostas para essas perguntas e muitas outras têm de ser encontradas por meio da consulta ao dicionário de dados. Tendo resolvido o que a instrução realmente significa, o servidor decide a melhor maneira de executá-la. Há um índice na coluna nome? Se houver, seria mais rápido usar o índice para localizar a linha ou fazer uma varredura integral da tabela? Mais consultas ao dicionário de dados.... É muito possível que uma simples consulta de uma linha em uma tabela do usuário gere dezenas de consultas ao dicionário de dados e que analisar uma instrução demore muito mais do que eventualmente executá-la. O objetivo do cache de biblioteca do shared pool é armazenar instruções na sua forma analisada por parse, pronta para execução. Na primeira vez em que uma instrução é emitida, ela tem de ser analisada por parse antes da execução – na segunda vez, ela pode ser executada imediatamente. Em uma aplicação bem projetada, é possível que as instruções possam ser analisadas uma vez e executada milhões de vezes. Isso economiza tempo. Obs.: O algoritmo usado para localizar o SQL no cache de biblioteca é baseado nos valores ASCII dos caracteres que compõem a instrução. A menor diferença (mesmo algo trivial como SELECT em vez de select) significa que a instrução não correspondente e será analisada por parse novamente. Cache de dicionário de dados O cache de dicionário de dados às vezes é chamado cache de linhas. Independentemente do termo empregado, ele armazena as definições de objetos usados recentemente: descrições de tabelas, índices, usuários e outras definições de metadados. Manter essas definições na memória da SGA, onde elas podem ser imediatamente acessadas por todas as sessões, em vez de cada sessão ter de lê-las repetidamente no dicionário de dados no disco, melhora o desempenho da análise. O cache de dicionário de dados armazena definições de objetos para que as instruções possam ser analisadas por parse rapidamente sempre que necessário – sem ter de consultar o dicionário de dados. Considere o que acontece se estas instruções forem emitidas consecutivamente: SQL> select sum (preco) from tcursos; SQL> select * from tcursos where id = 70 ; Ambas devem ser analisadas por parse porque são instruções diferentes – mas a análise da primeira instrução SELECT terá carregado a definição da tabela tcursos e suas colunas para o cache de dicionário de dados. A análise da segunda instrução será mais rápida porque não será preciso mais nenhum acesso ao dicionário de dados. Obs.: O ajuste do shared pool é, em geral, orientado no sentido de garantir que o cache de biblioteca esteja com o tamanho correto. Isso porque os algoritmos que o Oracle usa para alocar memória na SGA são projetados para preferir o cache de dicionário. Portanto, se o cache de biblioteca estiver correto, o cache de dicionário já estará correto. Área PL/SQL Os objetos PL/SQL armazenados são procedures, funções, procedures e funções empacotadas, definições de tipo de objeto e triggers. Todos estão armazenados no dicionário de dados como código-fonte e na sua forma compilada. Quando um objeto PL/SQL armazenado é chamado por uma sessão, ele deve ser lido a partir do dicionário de dados. Para impedir a leitura repetida, os objetos são, então, armazenados em cache na área PL/SQL do shared pool. Na primeira vez em que um objeto PL/SQL é usado, ele deve ser lido a partir das tabelas do dicionário de dados no disco, mas as chamadas subsequentes serão muito mais rápidas, porque o objeto já estará disponível na área PL/SQL do shared pool. Obs.: Rotinas PL/SQL podem ser emitidas a partir dos processos de usuário, em vez de serem armazenadas no dicionário de dados. Elas são conhecidas como PL/SQL anônimo. O PL/SQL anônimo não pode ser armazenado em cache e reutilizado e deve ser compilado dinamicamente. Portanto, sua execução é sempre pior do que a de PL/SQL armazenado. Os desenvolvedores devem ser estimulados a converter todo o PL/SQL anônimo em PL/SQL armazenado. Cache de resultados de funções PL/SQL e consultas SQL O cache de resultados é um recurso novo da versão 12c. Em muitas aplicações, a mesma consulta é executada muitas vezes, pela mesma sessão ou por sessões diferentes. A criação de um cache de resultados permite que o servidor Oracle armazene os resultados de tais consultas na memória. A próxima vez em que a consulta for emitida, em vez de executá-la, o servidor pode recuperar o resultado armazenado em cache. O mecanismo de cache de resultados é inteligente o bastante para controlar se as tabelas nas quais a consulta foi executada foram atualizadas. Se isso tiver acontecido, os resultados da consulta serão invalidados e, na próxima vez em que a consulta for emitida, ela será reexecutada. Portanto, não há perigo de receber um resultado desatualizado do cache. O cache de resultados PL/SQL usa um mecanismo similar. Quando uma função PL/SQL é executada, seu valor de retorno pode ser armazenado em cache pronto para a próxima vez em que a função for executada. Se os parâmetros passados para a função, ou as tabelas que a função consulta, forem diferentes, a função será reavaliada – mas, do contrário, o valor em cache será retornado. Por padrão, o uso do cache de resultados PL/SQL e consultas SQL está desativado, mas, se ativado programaticamente, poderá melhorar muito o desempenho. O cache fica dentro do shared pool e, ao contrário de outras áreas de memória descritas anteriormente, ele proporciona algum controle para o DBA: é possível especificar um tamanho máximo. Dimensionando o shared pool O dimensionamento do shared pool é crítico para o desempenho. Ele deve ser suficientemente grande para armazenar em cache todos os códigos executados com frequência e as definições de objetos necessários (nos caches de biblioteca e de dicionário de dados), mas não tão grande que possa armazenar instruções que são executadas apenas uma vez. Um shared pool subdimensionado diminui o desempenho, porque as sessões do servidor precisam repetidamente alocar espaço nele para analisar as instruções, que são então sobrescritas por outras instruções que precisam ser analisadas novamente quando são reexecutadas. Um shared pool superdimensionado causa um impacto ruim no desempenho, porque é muito demorado pesquisá-lo. Se o shared pool for menor do que o tamanho, ótimo – o desempenho diminuirá. Mas há um tamanho mínimo abaixo do qual as instruções falharão. A memória no shared pool é alocada de acordo com um algoritmo LRU (menos usado recentemente). Quando o servidor Oracle precisar de espaço no shared pool, ele sobrescreverá o objeto que não está sendo usado há mais tempo. Se o objeto for novamente necessário mais tarde, ele terá de ser recarregado – possivelmente, sobrescrevendo outro objeto. O shared pool é alocado na hora da inicialização da instância. Antes da versão 9i do banco de dados, não era possível redimensionar o shared pool após o startup sem reiniciar a instância do banco de dados. Mas, a partir da versão 9i em diante, ele pode ser redimensionado para mais ou para menos a qualquer hora. Esse redimensionamento pode ser manual ou (a partir da versão 10g) automático, de acordo com a carga de trabalho, se o mecanismo automático estiver ativado. Dica de Exame O tamanho do shared pool é dinâmico e pode ser gerenciado automaticamente. Large pool O large pool é uma área opcional que, se criada, será usada automaticamente por vários processos que ocupariam a memória do shared pool. Um uso importantedo large pool é pelos processos de servidores compartilhados, descritos no Capítulo 6 na discussão sobre servidor compartilhado (ou multithreaded). Os servidores de execução paralela também usarão o large pool, se houver. Na ausência de um large pool, esses processos usarão a memória do shared pool. Isso pode provocar uma disputa ruim pela memória do shared pool: se os servidores compartilhados ou servidores paralelos estiverem sendo usados, um large pool sempre deve ser criado. Alguns processos de I/O também podem fazer uso do large pool, como os processos usados pelo Recovery Manager durante a execução de backup para um dispositivo de fita. O dimensionamento do large pool não é uma questão de desempenho. Se um processo precisa de uma grande quantidade de memória, ele falhará com um erro se essa memória não estiver disponível. Alocar mais memória do que o necessário não fará com que as instruções sejam executadas mais rapidamente. E, se houver um large pool, ele será usado: não é possível uma instrução iniciar usando o large pool e, em seguida, reverter para o shared pool se o large pool for muito pequeno. A partir do 9i release 2, é possível criar e redimensionar um large pool após a inicialização da instância. Com as versões anteriores, ele tinha de ser definido na inicialização e tinha um tamanho fixo. A partir da versão 10g, a criação e o dimensionamento do large pool podem ser completamente automáticos. Dica de Exame O tamanho do large pool é dinâmico e pode ser gerenciado automaticamente. Java pool O Java pool só é necessário se sua aplicação for executar procedures Java armazenadas no banco de dados: ele é usado para o espaço de heap necessário para instanciar os objetos Java. Entretanto, vários componentes opcionais do Oracle são escritos em Java, portanto, o Java pool é considerado padrão hoje. Observe que o código Java não é armazenado em cache no Java pool: ele é armazenado em cache no shared pool, da mesma maneira que o código PL/SQL. O tamanho otimizado do Java pool depende da aplicação Java e da quantidade de sessões em execução. Cada sessão exigirá um espaço de heap para seus objetos. Se o Java pool estiver subdimensionado, o desempenho poderá diminuir devido à necessidade de exigir espaço continuamente. Em uma aplicação EJB (Enterprise JavaBean), um objeto, como um bean de sessão stateless, pode ser instanciado e usado e, em seguida, permanecer na memória no caso de ser necessário novamente, tal objeto pode ser reutilizado imediatamente. Mas, se o servidor Oracle tiver de destruir o bean para criar espaço para outro, então, ele terá de ser reinstanciado na próxima vez em que for necessário. Se o Java pool for muito subdimensionado, as aplicações podem falhar. A partir da versão 10g, é possível criar e redimensionar um large pool após a inicialização da instância. A criação e o dimensionamento do large pool podem ser completamente automáticos. Com as versões anteriores, eles precisavam ser definidos na inicialização e tinham tamanho fixo. Streams pool O Streams pool é usado pelo Oracle Streams. Essa é uma ferramenta avançada que está além do escopo dos exames OCP, mas a seguir está uma breve descrição. O mecanismo usado pelo Streams extrai vetores de alteração do redo log e, a partir deles, reconstrói as instruções que foram executadas – ou instruções que teriam o mesmo efeito. Essas instruções são executadas Dica de Exame O tamanho do Java pool é dinâmico e pode ser gerenciado automaticamente. no banco de dados remoto. Os processos que extraem alterações do redo e os que aplicam as alterações precisam de memória: essa memória é o Streams pool. No banco de dados versão 10g, é possível criar e redimensionar o Streams pool após a inicialização da instância; essa criação e dimensionamento podem ser completamente automáticos. Com as versões anteriores, ele tinha de ser definido na inicialização e tinha um tamanho fixo. Dica de Exame O tamanho do Streams pool é dinâmico e pode ser gerenciado automaticamente. Exemplo Prático 1. Mostre os tamanhos atual, máximo e mínimo dos componentes da SGA que podem ser redimensionados dinamicamente: SQL> select COMPONENT, CURRENT_SIZE, MIN_SIZE, MAX_SIZE from v$sga_dynamic_components; 2. Determine a quantidade de memória que foi alocada e a que está atualmente alocada para as áreas globais de programa: SQL> select name, value from v$pgastat where name in ('maximum PGA allocated' , 'total PGA allocated') ; 3. Consulte informações detalhadas sobre a SGA SQL> select * from v$sgainfo; Descrever as estruturas de processos Os processos em segundo plano da instância são os processos iniciados quando a instância é iniciada e executados até que ela termine. Existem cinco processos em segundo plano que têm uma longa história com o Oracle. Estes são os primeiros cinco descritos nas seções a seguir: System Monitor (SMON), Process Monitor (PMON), Database Writer (DBWn), Log Writer (LGWR) e Checkpoint Process (CKPT). Vários outros foram introduzidos com os releases mais recentes; destacam-se entre esses o Manageability Monitor (MMON) e o Memory Manager (MMAN). Existem também alguns que não são essenciais, mas existirão na maioria das instâncias. Esses são o Archiver (ARCn) e o Recoverer (RECO). Outros só existirão se certas opções tiverem sido ativadas. Esse último grupo inclui os processos necessários para o RAC e o Streams. Além disso, existem alguns processos que não são documentados adequadamente (ou nem são documentados). Existe uma variação de plataforma que deve ser explicada antes de discutir os processos. No Linux e no Unix, todos os processos do Oracle são processos de sistema operacional separados, cada um deles com um número de processos único. No Windows, existe um processo de sistema operacional (denominado ORACLE.EXE) para a instância inteira: os processos do Oracle são executados como threads separadas dentro desse processo. SMON, o System Monitor O SMON inicialmente tem a tarefa de montar e abrir um banco de dados. As etapas envolvidas nesse procedimento são descritas detalhadamente no Capítulo 5. Em resumo, o SMON monta um banco de dados localizando e validando o arquivo de controle do banco de dados. Depois, ele abre um banco de dados localizando e validando todos os arquivos de dados e os arquivos de log online. Uma vez que o banco de dados esteja aberto e em uso, o SMON é responsável por várias tarefas domésticas, como organizar o espaço livre no arquivo de dados. PMON, o Process Monitor Uma sessão de usuário é um processo de usuário que é conectado a um processo de servidor. O processo de servidor é iniciado quando a sessão for criada e destruído quando a sessão termina. Uma saída ordenada de uma sessão envolve o logoff do usuário. Quando isso ocorre, qualquer trabalho que ele esteja fazendo será concluído de modo ordenado, e seu processo de servidor será terminado. Se a sessão for terminada desordenadamente (talvez porque o PC do usuário tenha reiniciado), a sessão será deixada em um estado que indica que ela deve ser excluída. O PMON monitora todos os processos de servidor e detecta os problemas com as sessões. Se uma sessão termina de modo anormal, o PMON destruirá o processo de servidor, retornará sua memória ao pool de memória livre do sistema operacional e executará rollback de todas as transações incompletas que possam estar em andamento. DBWn, o Database Writer As sessões não têm como regra geral gravar no disco. Elas gravam os dados (ou as alterações feitas aos dados existentes) em buffers no cache de buffer do banco de dados. É o database writer (gravador de banco de dados) que, subsequentemente, grava os buffers no disco. Uma instância pode ter vários database writers (atéum máximo de 20), que serão denominados DBW0, DBW1 e assim por diante: daqui por diante, o termo DBWn fará referência “ao” database writer. O número padrão arredondado é um database writer para cada oito CPUs. Obs.: adicionar mais database writers pode ajustar o desempenho, mas, em geral, você deve examinar primeiramente o ajuste da memória. Como regra, antes de otimizar a I/O em disco, pergunte-se por que existe alguma necessidade de I/O em disco. Dica de Exame Se uma sessão terminar de modo anormal, o que acontecerá com uma transação ativa? O processo PMON em segundo plano executará o rollback na transação ativa. O DBWn grava buffers sujos do cache de buffer do banco de dados nos arquivos de dados – mas ele não grava os buffers à medida que eles se tornam sujos. Pelo contrário: ele grava o menor número de buffers possível, o suficiente para resolver o problema. A ideia geral é que o I/O de disco prejudica o desempenho, portanto não o utilize a menos que seja realmente necessário. Se um bloco em um buffer foi gravado por uma sessão, existe uma possibilidade razoável de que ele seja gravado novamente – por essa sessão ou por uma sessão diferente. Por que gravar o buffer no disco, se ele poderá tornar-se sujo novamente? O algoritmo que o DBWn usa para selecionar buffers sujos para gravar no disco (que os limpará) seleciona apenas os buffers que não foram usados recentemente. Portanto, se um buffer estiver muito ocupado, porque as sessões o estão lendo ou gravando repetidamente, o DBWn não gravará no disco. Poderá haver centenas ou milhares de gravações em um buffer antes que o DBWn o limpe. Pode ser que um cache de buffer com um milhão de buffers, uma centena de milhares deles estejam sujos – mas o DBWn poderá gravar apenas algumas centenas deles no disco ao mesmo tempo. Esses serão apenas os buffers pelos quais nenhuma sessão esteve interessada por algum tempo. O DBWn grava de acordo com um algoritmo muito preguiçoso: a menor quantidade possível, o mais raramente possível. Existem quatro circunstâncias que farão o DBWn gravar: ausência de buffers livres, excesso de buffers sujos, um tempo limite de três segundos e quando há um checkpoint. Primeiro, quando não há mais buffers livres. Se um processo de servidor precisa copiar um bloco no cache de buffer do banco de dados, ele deve encontrar um buffer livre. Um buffer livre é um buffer que não está sujo (atualizado e ainda não gravado no disco) nem retido (um buffer retido é aquele que está sendo usado por outra sessão nesse momento). Um buffer sujo não deve ser gravado porque, se ele tiver de ser alterado, os dados serão perdidos e um buffer retido não pode ser sobrescrito porque os mecanismos de proteção de memória do sistema operacional não permitirão. Se um processo de servidor demorar muito tempo (Isso é determinado internamente pelo Oracle) para encontrar um buffer livre, ele avisa o DBWn para gravar alguns buffers sujos no disco. Uma vez que isso é feito, eles estão limpos – portanto, livres e disponíveis para uso. Segundo, pode haver muitos buffers sujos (outro limite interno). Os processos de servidor não têm problemas para encontrar um buffer livre, mas pode haver um grande número de buffers sujos: isso fará com que o DBWn grave alguns deles no disco. Terceiro, há um tempo limite de três segundos: a cada três segundos, o DBWn limpará alguns buffers. Na prática, esse evento pode não ser significativo sem um sistema de produção, porque as duas circunstâncias descritas anteriormente forçarão as gravações, mas o tempo limite significa que, mesmo que o sistema esteja ocioso, o cache de buffer do banco de dados eventualmente será limpo. Quarto, pode haver um checkpoint solicitado. As três razões já vistas farão com que o DBWn grave um número limitado de buffers sujos nos arquivos de dados. Quando ocorre um checkpoint, todos os buffers sujos são gravados. Isso pode acontecer com centenas de milhares deles. Durante um checkpoint, as taxas de I/O de disco serão exasperantes, o uso da CPU poderá chegar a 100%, as sessões de usuário final experimentarão um desempenho reduzido e as pessoas começarão a reclamar. Depois, quando o checkpoint estiver completo (o que pode demorar alguns minutos), o desempenho voltará ao normal. Por que ter checkpoints? A resposta curta é: não os tenha, a menos que seja necessário. Dica de Exame O que faz o DBWn quando uma transação sofre commit? Ele não faz absolutamente nada. Checkpoints completo O único momento em que um checkpoint é absolutamente necessário é quando o banco de dados é fechado e a instância é desligada. Um checkpoint grava todos os buffers sujos no disco: isso sincroniza o cache de buffer com os arquivos de dados, a instância com o banco de dados. Na execução normal, os arquivos de dados estão sempre desatualizados: podem estar faltando as alterações (que sofreram commit ou não). Isso não tem importância, porque as cópias dos blocos no cache de buffer estão atualizadas, e são com essas cópias que as sessões trabalham. Mas, no shutdown, é necessário gravar tudo no disco. Os checkpoints automáticos só ocorrem no shutdown, mas um checkpoint pode ser forçado a qualquer momento com esta instrução: SQL> alter system checkpoint; O checkpoint descrito até aqui é um checkpoint completo. Checkpoints parciais Os checkpoints parciais que forçam o DBWn a gravar todos os buffers sujos que contêm blocos apenas de um ou mais arquivos de dados em vez de o banco de dados inteiro, ocorrem com mais frequência: quando um arquivo de dados ou tablespace é colocado off-line, quando um tablespace é colocado no modo backup, quando um tablespace é configurado para somente leitura. Esses são menos drásticos do que os checkpoints completos e ocorrem automaticamente sempre que o evento relevante acontece. Para concluir, o DBWn grava com um algoritmo muito preguiçoso: a menor quantidade possível, o mais raramente possível – exceto quando ocorre um checkpoint, quando todos os buffers sujos são gravados no disco, o mais rápido possível. Obs.: O que fará o DBWR gravar? Nenhum buffer livre, muitos buffers sujos, um timeout de três segundos ou um checkpoint. A partir da versão 8i, os checkpoints não ocorrem na alternância de log. LGWR, o Log Writer O LGWR grava o conteúdo do buffer de log nos arquivos de log no disco. Uma gravação do buffer de log nos arquivos de redo log online frequentemente é referenciada como fazer flush do buffer de log. Quando uma sessão faz alguma alteração (executando os comandos INSERT, UPDATE ou DELETE) aos blocos no cache de buffer do banco de dados, antes de aplicar a alteração ao bloco, ele grava o vetor de alteração que será aplicado ao buffer de log. Para que nenhum trabalho seja perdido, esses vetores de alteração devem ser gravados no disco o mais rápido possível. Para esse fim, o LGWR gera um fluxo de gravação do conteúdo do buffer de log para os arquivos de redo log online no disco praticamente em tempo real. E, quando uma sessão emite uma instrução COMMIT, o LGWR grava em tempo real: a sessão é suspensa, enquanto o LGWR grava o buffer no disco. Somente então é que o commit é confirmado e a transação se torna, portando, irreversível. O LGWR é um dos principais gargalos na arquitetura Oracle. É impossível executar comandos DML mais rápido do que o LGWR pode gravar os vetores de alteração no disco. Existem três circunstâncias que obrigarão o LGWR a fazer flush para o buffer de log: se uma sessão emitir um comando COMMIT, se o buffer de log estiver um terço completo e se o DBWn estiver para gravar buffers sujos. Primeiro, a gravação do commit. Para processar um COMMIT, o processo de servidor insere um registro de commit no buffer de log. Ele, então, será suspenso enquantoo LGWR faz flush do buffer de log para o disco. Apenas quando essa gravação estiver concluída é que uma mensagem de confirmação de commit retorna à sessão e o processo de servidor pode, então, continuar trabalhando. Isso é a garantia de que as transações nunca serão perdidas: cada vetor de alteração para uma transação que sofreu commit estará disponível no redo log no disco e poderá, então, ser aplicada aos backups do arquivo de dados. Assim, se o banco de dados for danificado, ele poderá ser restaurado a partir do backup e todo o trabalho desde que o backup foi feito pode ser refeito. Segundo, quando o buffer de log estiver um terço cheio, o LGWR fará flush do buffer para o disco. Isso tem a ver com o desempenho. Se o buffer de log for pequeno (como normalmente deveria ser), esse trigger que disparará quando o buffer de log estiver um terço cheio irá forçar o LGWR a gravar o buffer no disco praticamente em tempo real, mesmo que nenhum usuário esteja executando commit nas transações. O buffer de log para muitas aplicações será dimensionado de forma otimizada com apenas alguns megabytes. A aplicação irá gerar informações de redo em quantidade suficiente para preencher um terço dele em uma fração de segundo, o que irá forçar o LGWR a gerar um fluxo de gravação contínuo dos vetores de alteração para o disco praticamente em tempo real. Então, quando uma sessão executar o COMMIT, não haverá quase nada para gravar: portanto o COMMIT será concluído quase que instantaneamente. Terceiro, quando o DBWn precisar gravar os buffers sujos do cache de buffer do banco de dados nos arquivos de dados, antes ele sinalizará para o LGWR fazer flush do buffer de log para os arquivos de redo log online. Isso é feito para garantir que sempre será possível reverter uma transação que não sofreu commit. Os mecanismos de rollback de transação serão detalhadamente explicados nos capítulos a seguir. Por enquanto, basta saber que, para o DBWn, é perfeitamente possível gravar uma transação que não sofreu commit nos arquivos de dados. Isso é bom, desde que os dados de undo necessários para reverter a transação estejam disponíveis. A geração de dados de undo também gera vetores de alteração: como eles estarão nos arquivos de redo log antes dos arquivos de dados serem atualizados, os dados de undo necessários para reverter uma transação (caso seja preciso) podem ser reconstruídos, se necessário. Dica de Exame Quando o LGWR fará flush do buffer de log para o disco? Durante um COMMIT; quando o buffer estiver um terço cheio; antes de o DBWn gravar. Obs.: Pode-se dizer que há um tempo limite de três segundos que faz o LGWR gravar. De fato, o tempo limite está no DBWR – mas como o LGWR sempre grava exatamente antes do DBWn, na verdade há um tempo limite de três segundos também no LGWR. É possível evitar que o LGWR trabalhe com confirmação do commit. Se isso for feito, as sessões não precisarão esperar pelo LGWR quando um COMMIT for executado: elas emitirão o comando e, em seguida, continuarão a trabalhar. Isso melhorará o desempenho, mas pode também significar que o trabalho será perdido. Pode ser que uma sessão emita um COMMIT e, em seguida, a instância trave antes que o LGWR tenha salvado os vetores de alteração. Ative esse recurso com cuidado! Ele é preguiçoso e raramente necessário. Existem apenas algumas aplicações onde o desempenho é mais importante do que a perda de dados. CKPT, o Checkpoint Process A finalidade do CKPT mudou muito entre as versões 8 e 8i do banco de dados Oracle. Na versão 8 e anteriores, os checkpoints eram necessários em intervalos regulares para garantir que, no caso de uma falha da instância (por exemplo, se a máquina do servidor for reiniciada), o banco de dados pudesse ser recuperado rapidamente. Esses checkpoints eram iniciados pelo CKPT. O processo de recuperação repara o dano causado por uma falha na instância que será descrito nos capítulos a seguir. Após uma falha, todos os vetores de alteração que fazem referência aos buffers sujos (buffers que não foram gravados no disco pelo DBWn na hora da falha) devem ser retirados do redo log e aplicados aos blocos de dados. Esse é o processo de recuperação. Checkpoints frequentes garantiriam que os buffers sujos fossem gravados no disco rapidamente, minimizando a quantidade de informações de redo que teriam de ser aplicadas após uma falha e, portanto, minimizando o tempo necessário para recuperar o banco de dados. O CKPT era responsável por sinalizar os checkpoints regulares. A partir da versão 8i, o mecanismo de checkpoint mudou. Em vez de permitir que o DBWn se atrase e, em seguida, sinalize um checkpoint (que força o DBWn a compensar o atraso existente e se manter atualizado, com uma queda no desempenho enquanto isso acontece), do 8i em diante o DBWn faz checkpoints incrementais em vez de checkpoints completos. O mecanismo de checkpoint incremental instrui o DBWn a gravar os buffers sujos a uma taxa constante, para que haja sempre um intervalo previsível entre o DBWn (que grava os blocos usando um algoritmo preguiçoso) e o LGWR (que grava os vetores de alteração praticamente em tempo real). Os checkpoints incrementais resultam em um desempenho muito mais suave e tempos de recuperação mais previsíveis do que o mecanismo de checkpoint completo mais antigo. O CKPT não tem mais de sinalizar checkpoints completos, mas tem de controlar onde, no fluxo de gravação de informações de redo, está a posição do checkpoint incremental e, se necessário, instruir o DBWn para gravar alguns buffers sujos para posicionar o checkpoint mais à frente. A posição do checkpoint atual, também conhecida como RBA (o endereço do byte de redo), é o ponto no fluxo de gravação de informações de redo no qual a recuperação começará no caso de uma falha na instância. O CKPT atualiza continuamente o arquivo de controle com a posição do checkpoint atual. Obs.: Quanto mais rápido o checkpoint incremental avançar, mais rápida será a recuperação após uma falha. Mas o desempenho ficará deteriorado devido ao I/O de disco adicional, à medida que o DBWn grava os buffers sujos mais rapidamente. Isso causa um conflito entre minimizar o tempo ocioso e maximizar o desempenho. Dica de Exame Quando os checkpoints completos ocorrem? Somente por solicitação do DBA ou como parte de um shutdown ordenado do banco de dados. MMON, o Manageability Monitor MMON é um processo que foi introduzido com o banco de dados versão 10g e é o processo de ativação de grande parte dos recursos de auto monitoramento e auto ajuste do banco de dados. A instância do banco de dados reúne um grande número de estatísticas sobre atividade e desempenho. Essas estatísticas são acumuladas na SGA, e seus valores atuais podem ser apurados emitindo consultas SQL. Para ajuste de desempenho e análise de tendências e relatório de histórico, é necessário salvar essas estatísticas para armazenamento em longo prazo. O MMON regularmente (por padrão, a cada hora) captura as estatísticas da SGA e as grava no dicionário de dados, onde podem ser armazenadas indefinidamente (embora, por padrão, elas sejam mantidas por oito dias). Cada vez que o MMON reúne um conjunto de estatísticas (conhecido como snapshot), ele também inicia o Automatic Database Diagnostic Monitor, o ADDM. O ADDM é uma ferramenta que analisa a atividade do banco de dados usando um sistema experiente desenvolvido ao longo de muitos anos por muitos DBAs. Ele observa dois snapshots (por padrão, os snapshots atual e anterior) e faz observações e recomendações em relação ao desempenho. Além de coletar snapshots, o MMON monitora continuamente o banco de dados e a instância para verificar se alguns alertas devem ser disparados. Algumas condições de alerta (como avisos quando os limitesno espaço de armazenamento são alcançados) são ativados por padrão; outros podem ser configurados pelo DBA. Dica de Exame Por padrão, o MMON reúne um snapshot e inicia o ADDM a cada hora. MMNL, o Manageability Monitor Light O MMNL é um processo que auxilia o MMON. Há ocasiões em que a atividade agendada no MMON não é suficiente. Por exemplo, o MMON faz flush das informações estatísticas acumuladas na SGA para o banco de dados de acordo com um agendamento: por padrão, a cada hora. Se os buffers de memória usados para acumular essas informações ficarem cheios antes do MMON fazer flush, o MMNL assumirá a responsabilidade pelo flush de dados. MMAN, o Memory Manager O MMAN é um processo que foi introduzido com o banco de dados versão 10g. Ele permite o gerenciamento automático de alocações de memória. Antes da versão 9i do banco de dados, o gerenciamento de memória no ambiente Oracle estava longe de ser satisfatório. A memória PGA associada aos processos de servidor de sessão era não transferível: o processo de servidor ocupava a memória do pool de memória livre do sistema operacional e nunca a retornava – mesmo que ela só fosse necessária por um curto período de tempo. As estruturas da memória SGA eram estáticas: definidas na hora da inicialização da instância e inalteráveis a menos que a instância fosse desligada e reiniciada. A versão 9i mudou isso: as PGAs podem crescer e encolher, com o servidor passando memória para as sessões sob demanda, ao mesmo tempo garantindo que a memória PGA total alocada permaneça dentro de certos limites. A SGA e seus componentes (com a notável exceção do buffer de log) também pode ser redimensionada. A versão 10g automatizou o redimensionamento da SGA: o MMAN monitora a demanda por estruturas de memória SGA e pode redimensioná-las conforme o necessário. A versão 12c leva o gerenciamento de memória mais adiante: tudo o que o DBA precisa é definir um objetivo global para o uso da memória e o MMAN observará a demanda pela memória PGA e a memória SGA e alocará a memória para as sessões e para as estruturas SGA conforme o necessário, mantendo o total de memória alocada dentro de um limite definido pelo DBA. Obs.: A automação do gerenciamento de memória é um dos avanços técnicos principais dos releases mais recentes, automatizando uma grande parte do trabalho do DBA e fornecendo grandes benefícios no desempenho e na utilização de recursos. O MMAN gerencia a memória melhor do que o DBA. ARCn, o Archiver Esse é um processo opcional no que diz respeito ao banco de dados, mas, em geral, é um processo obrigatório para a empresa. Sem um ou mais processos ARCn (pode haver de um a 30, denominados ARC0, ARC1 e assim por diante), é possível que haja perda de dados. Todos os vetores de alteração aplicados aos blocos de dados são gravados no buffer de log (pelas sessões que fazem as alterações) e, em seguida, no arquivo de redo log online (pelo LGWR). Os arquivos de redo log online são de número e tamanho fixos: uma vez que tenham sido preenchidos, o LGWR os sobrescreverá com mais dados de redo. O tempo decorrido antes que isso aconteça depende do tamanho e do número de arquivos de log online e da quantidade de atividade DML (e, portanto, a quantidade de informações de redo gerada) no banco de dados. Isso significa que o redo log online só armazena vetores de alteração de atividade recente. Para preservar um histórico completo de todas as alterações, os arquivos de log online devem ser copiados à medida que forem preenchidos e antes de serem reutilizados. O ARCn é responsável por isso. Desde que essas cópias, conhecidas como arquivos de redo log arquivados, estejam disponíveis, será sempre possível recuperar o banco de dados de qualquer dano restaurando os backups do arquivo de dados e aplicando neles os vetores de alteração extraídos de todos os arquivos de redo log arquivados gerados desde que os backups foram criados. Então, a recuperação final, que irá recuperar o backup atualizado, virá dos arquivos de redo log online. A maioria dos bancos de dados transacionais de produção executarão no modo archive log, o que significa que o ARCn é iniciado automaticamente e que o LGWR não pode sobrescrever um arquivo de log online até que o ARCn o tenha arquivado com êxito em um arquivo de log arquivado. Obs.: O progresso dos processos ARCn e o estado dos destinos nos quais eles serão gravados devem ser monitorados. Se o arquivamento falhar, o banco de dados eventualmente ficará suspenso. Esse monitoramento pode ser feito por meio do sistema de alerta. RECO, o Recoverer Process Uma transação distribuída é uma transação que envolve atualizações a dois ou mais bancos de dados, é projetada por programadores e opera por meio de links de bancos de dados. Considere este exemplo: SQL> update tcursos set preco= preco * 1.2 where id=20 ; SQL> update tcursos@matriz set preco= preco * 1.2 where id=20 ; SQL> commit ; A primeira atualização é aplicada a uma linha no banco de dados local. A segunda, a uma linha em um banco de dados remoto identificado pelo link de banco de dados MATRIZ. O comando COMMIT instrui os dois bancos de dados a confirmar a transação, que consiste em ambas as instruções. As transações distribuídas requerem um commit de duas fases (two-phase commit). O Dica de Exame O LGWR grava os arquivos de log online; o ARCn os lê. Na execução normal, eles não são manipulados por outro processo. commit em cada banco de dados deve ser coordenado: se um falhar e o outro for bem-sucedido, os dados globais estariam em um estado inconsistente. Um commit de duas fases prepara cada banco de dados instruindo seus LGWRs para fazer flush do buffer de log para o disco (a primeira fase) e uma vez que isso é confirmado, a transação é marcada como confirmada em todos os lugares (a segunda fase). Se algo sair errado em algum lugar entre as duas fases, o RECO assume o controle para cancelar o commit e fazer um rollback do trabalho em todos os bancos de dados. Alguns outros processos de segundo plano Os processos não descritos nas seções anteriores são: CJQ0, J000: gerenciam os jobs agendados para executarem periodicamente. O coordenador da fila de jobs, CJQn, monitora e envia para um dos vários processos da fila de jobs, Jnnn, para execução. D000: é um processo dispatcher que enviará chamadas SQL para os processos de servidores compartilhados, Snnn, se o mecanismo de servidores compartilhados estiver ativado. DBRM: O Database resource manager (gerenciador de recursos de banco de dados) é responsável pela configuração dos planos de recursos e outras tarefas relacionadas ao Resource Manager. DIA0: O diagnosability process zero (processo de diagnosticabilidade número zero) é responsável pela detecção de travamento e resolução de deadlock. DIAG: O diagnosability process (processo de diagnosticabilidade – sem número zero) executa dumps de diagnósticos e comandos oradebug (oradebug é uma ferramenta para investigar problemas em uma instância). FBAR: O flashback data archiver process (processo de arquivamento de dados de flashback) arquiva as linhas de histórico de tabelas rastreadas em arquivos de dados de flashback. Esse é um recurso para garantir que sempre seja possível consultar dados como eram em algum momento no passado. PSP0: O process spawner (gerador de processos) tem a tarefa de criar e gerenciar outros processos do Oracle e não é documentado. QMNC, Q000: O queue manager coordinator (coordenador do gerenciador de filas) monitora as filas no banco de dados e comanda os processos Qnnn a incluir e excluir mensagens nessas filas e a partir delas. As filas podem ser criadas por programadores (talvez como um meio dassessões se comunicarem) e também são usadas internamente. O Streams, por exemplo, usa filas para armazenar transações que precisam ser propagadas para bancos de dados remotos. SHAD: esse processo será denominado TNS V1-V3 em um sistema Linux. São os processos de servidor que dão suporte às sessões de usuário. SMCO, W000: O space management coordinator process (processo coordenador de gerenciamento de espaço) coordena a execução várias tarefas relacionadas ao gerenciamento de espaço, como alocação de espaço pró-ativo e reclamação de espaço. Ele cria dinamicamente processos slaves (Wnnn) para implementar a tarefa. VKTM: O virtual keeper off time (administrador virtual de tempo) é responsável pelo controle de tempo. Mais complicado do que se poderia pensar – especialmente em um ambiente clusterizado. Consultando os processos background: SQL> select program from v$process where background is not null order by program; ou SQL> select name, description from v$bgprocess; Exemplo prático 1. Determine quais processos estão em execução: SQL> select program from v$process order by program ; 2. Determine quais sessões estão em execução: SQL> select * from v$session; Cada processo deve ter uma sessão (mesmo os em segundo plano) e cada sessão deve ter um processo. Os processos que podem ocorrer várias vezes terão um sufixo numérico, exceto para os que dão suporte às sessões de usuário: esses terão o mesmo nome. 3. Demonstre a inicialização dos processos de servidor à medida que as sessões são criadas, contando o número de processos de servidor (no Linux ou em qualquer plataforma Unix) ou o número de threads do Oracle (no Windows). A técnica é diferente nas duas plataformas, porque no Linux/Unix, os processos do Oracle são de sistema operacional separados, mas no Windows eles são threads dentro do processo do sistema operacional. 3.1 No Linux, execute este comando a partir de um prompt do sistema operacional: $ ps -ef | grep oracle |wc -l 75 Esse comando contará o número de processos em execução que têm a string oracle em seus nomes e incluirá todos os processos de servidor da sessão (e possivelmente alguns outros). 3.2 inicie uma sessão do SQL*Plus e execute novamente o comando anterior: use o comando host para iniciar um prompt de comando a partir da sessão do SQL*Plus. Você verá que o número de processos aumentou. Saia da sessão e você verá que o número diminuiu novamente. Esta figura mostra esse fato: $ sqlplus sys/oracle@db12c as sysdba SQL> host $ ps -ef | grep oracle |wc -l 76 3.3 No Windows, inicie o gerenciador de tarefas. Configure-o para mostrar o número de threads em cada processo: na guia View, selecione “Select Columns” e marque a caixa de seleção Thread Count. Procure o processo ORACLE.EXE e anote o número de threads. Estruturas de armazenamento O banco de dados Oracle proporciona uma completa abstração entre o armazenamento lógico e o físico. O armazenamento de dados lógicos é feito nos segmentos. Existem vários tipos de segmentos – um segmento típico é uma tabela. Os segmentos são armazenados fisicamente em arquivos de dados. A abstração do armazenamento lógico para o armazenamento físico é realizada por meio de tablespace. Os relacionamentos entre as estruturas lógicas e físicas, assim como suas definições, são mantidos no dicionário de dados. Estruturas físicas de banco de dados Existem três tipos de arquivo que compõem um banco de dados Oracle, mais alguns que existem externamente ao banco de dados e são, estritamente falando, opcionais. Os arquivos obrigatórios são o arquivo de controle (controlfile), os arquivos de redo log online (redo logfiles) e os arquivos de dados (datafiles). Os arquivos externos que normalmente estarão presentes (existem outros, necessários para opções avançadas) são o arquivo de parâmetros de inicialização, o arquivo de senhas e os arquivos de redo log arquivados, além dos arquivos de log e de rastreamento (trace). Arquivo de controle Um banco de dados pode ter um arquivo de controle, do qual podem existir várias cópias (multiplexando o arquivo de controle). O arquivo de controle é pequeno, mas vital. Ele contém ponteiros para o restante do banco de dados: os locais dos arquivos de redo log online e dos arquivos de dados, e dos arquivos de redo log arquivados mais recentes se o banco de dados estiver no modo archivelog. Ele Dica de Exame Arquivos obrigatórios em um banco de dados? O arquivo de controle, os arquivos de redo log online e arquivos de dados. também armazena informações necessárias para manter a integridade do banco de dados: timestamps diversos, e números sequenciais críticos, por exemplo. Se a ferramenta Recovery Manager estiver sendo usada para backups, os detalhes desses backups também serão armazenados no arquivo de controle. O arquivo de controle normalmente não terá mais que alguns megabytes de tamanho, mas você não pode viver sem ele. Cada banco de dados tem um arquivo de controle, mas um bom DBA sempre criará várias cópias dele para que o banco de dados possa sobreviver caso alguma cópia seja danificada. Se todas as cópias do arquivo de controle forem perdidas, é possível (embora talvez complicado) recuperar, mas você nunca deve ficar nessa situação. Você não tem de se preocupar em manter cópias multiplexadas do arquivo de controle sincronizado – o Oracle cuidará disso. Sua manutenção é automática – seu único controle é o de quantas cópias existem e onde colocá-las. Se você definir o número de cópias, ou sua localização, de forma incorreta na hora da criação do banco de dados, é possível adicionar ou remover as cópias posteriormente, ou movê-las – mas lembre-se de que qualquer operação desse tipo exigirá um tempo de inatividade, portanto é sempre bom definir essas informações corretas desde o início. Não há um número de cópias determinado como certo ou errado. O mínimo é uma e o máximo possível é oito. Qualquer dano que ocorra a alguma cópia do arquivo de controle fará com que a instância termine imediatamente. Arquivos de redo log online O redo log armazena uma cadeia contínua em ordem cronológica de cada vetor de alteração aplicado ao banco de dados. Esse será o mínimo de informação necessária para reconstruir, ou refazer, todo trabalho. Se um arquivo de dados (ou o banco de dados inteiro) for danificado ou destruído, esses vetores de alteração poderão ser aplicados aos backups de arquivos de dados para refazer o trabalho, adiantando-os no tempo até o momento em que o dano ocorreu. O redo log é composto de dois tipos de arquivos: os arquivos de redo log online (que são obrigatórios) e os arquivos de redo log arquivados (que são opcionais). Cada banco de dados tem ao menos dois arquivos de redo log online, mas, como no arquivo de controle, um bom DBA cria várias cópias de cada arquivo de redo log online. O redo log online é composto de grupos de arquivos, com cada um sendo conhecido como um membro. Um banco de dados Oracle requer ao menos dois grupos de ao menos um membro para funcionar. Você pode criar mais de dois grupos por razões de desempenho e mais de um membro por grupo por questão de segurança. O requisito de um mínimo de dois grupos é para que um possa aceitar as alterações atuais, enquanto o outro está sendo arquivado. Um dos grupos é atual (current): as alterações são gravadas no grupo de arquivo de redo log online pelo LGWR. À medida que as sessões de usuário atualizam os dados no cache de buffer do banco de dados, elas também gravam vetores de alteração mínimos no buffer de redo log. O LGWR continuamente grava os dados desse buffer para os arquivos que compõem o grupo de arquivos
Compartilhar