Baixe o app para aproveitar ainda mais
Prévia do material em texto
Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 1 de 41 AULA 03: Transações e log de transações Sumário Transações .......................................................................................................................................... 1 1. Introdução ........................................................................................................................... 1 1.1. O problema ..................................................................................................................... 1 2. O que é uma transação .................................................................................................. 2 2.1. Fluxo de uma transação ............................................................................................ 3 2.2. O Log do sistema .......................................................................................................... 5 2.3. Ponto de efetivação ..................................................................................................... 7 2.4. Plano de execução ....................................................................................................... 8 2.5. Serialidade (Serializability) ....................................................................................... 9 2.5.1. Equivalência de planos ......................................................................................... 10 2.6. Suporte a transação em SQL ................................................................................. 12 Controle de concorrência............................................................................................................. 14 3. A importância do controle de concorrência .......................................................... 14 3.1. Por que o controle de concorrência? ................................................................... 15 3.2. Técnicas de bloqueio ................................................................................................. 15 3.3. Protocolo de bloqueio em duas fases ................................................................. 17 3.4. Protocolo com base em Grafos ............................................................................. 20 3.5. Ordenação por Timestamp ..................................................................................... 20 Recuperação após falha ............................................................................................................... 22 4. Recuperação após falha ............................................................................................... 22 4.1. Classificação das falhas............................................................................................ 22 4.2. Estrutura de armazenamento ................................................................................ 23 4.3. O uso dos arquivos de log ...................................................................................... 24 4.4. Modificações adiadas e imediatas ........................................................................ 24 4.5. Checkpoint .................................................................................................................... 26 4.6. Paginação Shadow ..................................................................................................... 26 4.7. Visão geral do algoritmo de Aries ........................................................................ 28 Questões Comentadas .............................................................................................................. 29 Considerações Finais ..................................................................................................................... 41 Transações 1. Introdução Nosso assunto hoje é transações. Vamos descrever os conceitos necessários aos sistemas de processamento de transações. Discutiremos as técnicas de controle de concorrência usadas para assegurar a propriedade de não interferência ou isolamento das transações executadas concorrentemente. A correta implementação de um mecanismo de controle de transações ajuda na proteção e na integridade dos dados. 1.1. O problema Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 2 de 41 Uma transação comercial é uma interação no mundo real, geralmente entre uma empresa e uma pessoa ou outra empresa, onde algo é trocado. Por exemplo, poderia envolver a troca de dinheiro por produtos, informações ou serviços. Normalmente algum registro é necessário para gravar o que aconteceu. Muitas vezes, este registro é feito por um sistema de computador, para uma melhor escalabilidade, confiabilidade e custo. Um sistema de processamento de transações tem que lidar com grandes volumes de forma eficiente, evitar erros devido às operações simultâneas, evitar a produção de resultados parciais, crescer de forma incremental, evitar a paralisação das operações, “nunca” perder registros, oferecer distribuição geográfica, ser personalizável, escalar de forma harmônica, e ser fácil de gerir. É uma tarefa difícil. Esta aula descreve como essa tarefa é executada. Explica os princípios subjacentes de automatizar as transações comerciais, tanto para as empresas tradicionais quanto para o ambiente de comércio eletrônico. Explora as complexidades de tecnologias fundamentais, tais como o uso de logging e bloqueio. Vamos começar então descrevendo conceitos para podermos evoluir de forma tranquila pelo conteúdo. 2. O que é uma transação? A primeira coisa que precisamos saber sobre o assunto é a definição de transação. De forma mais ampla é um programa em execução ou um processo que inclui um ou mais acessos ao banco de dados, que efetuam leitura ou atualizações de seus registros. Pode ser considerada também uma unidade atômica de trabalho que estará completa ou não será realizada. O fato de ser realizada com sucesso (ou não ser realizada) nos leva a uma das características usadas para entender o processo de execução das transações. As propriedades desejáveis, conhecidas pela sigla ACID, são as seguintes: Atomicidade: representa uma unidade atômica de processamento. Cada transação deve ser executada por completo ou não ser executada. Em outras palavras, cada operação presente dentro de uma transação deve ser executada com sucesso ou nenhuma delas será executada (sofrem rollback). Não deve existir a possibilidade de apenas parte de uma transação ser concluída com sucesso. Consistência: a correta execução de uma transação deve levar o banco de dados de um estado consistente para outro estado igualmente consistente. Desta forma, conserva-se a consistência interna do banco de dados. Dentro deste contexto, todas as restrições de integridade devem ser respeitadas. Isolamento: as atualizações não devem ser tornadas visíveis para outras transações até o commit. Uma transação não deve ter conhecimento sobre a execução das demais. Podemos dizer que um conjunto de transações é isolado entre si caso o efeito da execução delas concorrentemente seja o mesmo da execução de cada uma delas sequencialmente. Durabilidade: sempre que o banco de dados for modificado e essas mudanças forem efetivadas, elas não podem ser perdidas por causa de falhas subsequentes. Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 3 de 41 Vejamos uma primeira questão sobre o assunto. 1. Ano: 2014 Banca: IADES Orgão: TRE/PA Cargo: – Analista Judiciário: Área Apoio Especializado – Especialidadeem Análise de Sistemas QUESTÃO 48 Transação é uma sequência de operações em um banco de dados que devem ser tratadas como um bloco único e indivisível. Ela deve garantir isolamento, em caso de acessos concorrentes ao mesmo dado, e recuperação da integridade, em caso de falhas durante a operação. Assinale a alternativa que apresenta o nome do processo de recuperação de um banco de dados, que desfaz as ações de uma transação realizada em um momento de falha. (A) Atomicidade. (B) Dirty read. (C) Isolamento. (D) Rollback. (E) Read commited Comentários: O processo que desfaz uma transação que falhou é denominado rollback. Falaremos mais sobre ele logo mais. Vimos que atomicidade e isolamento são características das transações. Sobre as alternativas B e E. A primeira representa um problema que acontece quando o nível de isolamento de uma transação não é adequado. A segunda trata de um dos níveis de isolamento. Falaremos sobre ambos durante a nossa aula. Gabarito: D 2.1. Fluxo de uma transação Depois de entendermos o conceito básico, passaremos agora para analisar o fluxo de uma transação. Esse fluxo, que descreve o processo de execução, possui alguns estados e a mudança de um estado para outro acontece por meio de uma operação. Observe a figura abaixo, as elipses representam os estados, as palavras ao lado de cada seta tratam das operações, que podem ou não resultar em uma mudança de estado. Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 4 de 41 Analisando a máquina de estados da figura acima, observe que operação de Begin Transaction inicia a execução da transação, levando a mesma para o estado ATIVO. Em seguida, são executadas as operações de Read/Write, ou seja, operações de leitura ou escrita de itens no banco de dados, que são executadas como parte da transação. Essas operações fazem acesso ao banco. Após a execução de todos os comandos sobre o banco uma operação de End Transaction especifica que as operações terminaram, marca o limite final da transação e leva a transação para o estado PARCIALMENTE EFETIVADA. Nesta etapa todas as mudanças feitas pela operação estão devidamente gravadas no log, porém, em alguns casos, os dados ainda não estão efetivamente armazenados no banco de dados. A grande questão aqui é: de posse do arquivo de log podemos fazer uma recuperação do banco de dados caso o comando de efetivar (COMMIT) seja executado com erro ou uma falha aconteça durante está operação! A operação de COMMIT leva a transação para o estado de EFETIVADA. O Commit Transaction sinaliza a finalização com sucesso de uma transação, de modo que qualquer atualização executada pela transação possa ser efetivada no banco de dados. Até aqui vimos o caminho feliz, outra possibilidade é a ocorrência de uma falha durante a execução da transação, neste caso, a operação de Rollback ou abort é executada, sinaliza que a transação terminou sem sucesso e o que foi executado ou modificado deve ser desfeito. Após essa rápida descrição textual, faremos abaixo um resumo para fixarmos os estados de uma transação: • Ativa: poderá emitir operações de read e write. • Parcialmente efetivada: alguns protocolos de restauração precisam garantir que uma falha de sistema não impossibilite a gravação permanente dos dados. Uma possibilidade é a gravação das alterações nos logs. Nesta etapa são feitas algumas verificações para garantir a continuação da execução. • Efetivada (committed state): uma vez atendida todas as verificações da etapa anterior, é possível executar o commit que se encarregar de gravar os dados em um armazenamento não volátil. • Falha: se uma das verificações falhar ou se a transação for interrompida em seu estado ativo. A transação deverá ser revertida para desfazer os efeitos das operações de write já efetivadas no banco de dados. • Encerrada: Quando a transação deixa o sistema. Vamos agora fazer uma questão para fixarmos o assunto visto até aqui. 2. Ano: 2016 Banca: FCC Órgão: TRF-SP Cargo: Técnico Judiciário de TI – Questão 66 Após receber permissão para alterar os dados dos registros contidos na tabela Processo, o usuário Paulo inseriu diversos registros utilizando a instrução INSERT e em seguida constatou, por meio da instrução SELECT, que estes dados Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 5 de 41 foram inseridos adequadamente. Porém, outros usuários que acessam a tabela não visualizarão os dados inseridos por Paulo até que ele execute o comando: (A) commit (B) refresh (C) end transaction (D) endpoint (E) close section Comentário: Essa questão trata de alguns conceitos interessantes. O primeiro deles é a característica de isolamento das transações. Segundo o enunciado, podemos observar que as modificações feitas por uma transação não são vistas por outro usuário até o momento do commit. Neste momento os dados já estão devidamente armazenados em uma memória não volátil. Outro ponto interessante que podemos derivar da questão é o nível de isolamento descrito para o sistema. Neste caso podemos usar: Read committed, Repeatable read ou Serializable. Gabarito: A 2.2. O Log do sistema Já entendemos que o fluxo da transação pressupõe mecanismos de segurança para garantir a atomicidade das operações nele contidas. Um desses mecanismos é o uso do log de transações. Utilizado para permitir recuperação de falhas de transações. Também chamado de jornal, ele registra todas as operações que afetam valores de itens do banco de dados. O log fica devidamente armazenado em disco e, periodicamente, pode sofrer backup em fita ou outro dispositivo de armazenamento secundário ou terciário. O log não será afetado por nenhum tipo de falha, exceto falhas de disco ou catastrófica. A ideia é armazenar as operações executas pela transação. Podemos, por exemplo, durante uma falha desfazer as operações, por meio dos registros nos arquivos de log, das transações que não foram efetivadas. Outra utilização das informações contidas no log seria para efetivar na base de dados as transações que tenham a operação de commit ou efetivação devidamente registrada no log. Os registros no log também são conhecidos como entradas. O perfil ou os dados armazenados em cada uma dessas entradas vão depender do tipo de uso que se pretende dar ao log. Se estamos tratando de um log de redo ou de recuperação precisamos armazenar apenas dados sobre a transação, a operação, o item de dados e seus valores, antigo e novo. É importante abrir um parêntese aqui antes de continuarmos. Existe um conceito importante que permeia o uso do log que é o rollback em cascata. Nele, caso uma transação T1 tenha lido um dado escrito ou modificado por outra transação T2 e a transação T2 sofra rollback, a transação T1 também sofrerá. Vejam que nestes casos é importante armazenar no log os registros de leitura. Existem protocolos para controle de transações que evitam reversões em cascata – os quais compreendem quase todos os protocolos práticos – eles não exigem que as operações de READ sejam escritas no log do sistema. Entretanto, Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 6 de 41 se o log também for usado para outros fins, como auditoria, então esse tipo de entrada deverá ser incluído no log. Vejamos uma lista simplificada de possíveis entradas no arquivo de log: • [start_transaction, T] • [write_item, T, X, old-value, new-value] • [read_item, T, X] • [commit, T] • [abort, T] As entradas acima representamas operações que as transações podem sofrer ao longo da sua execução. Quando uma transação (T1) começa a ser executada, um registro contendo “[start_transaction, T1]” será armazenado no arquivo de log de redo. Utilizando as informações contidas no arquivo de log podemos executar algumas operações sobre o banco de dados. A operação de UNDO ou desfazer, que é similar ao Rollback, mas aplicada a uma única operação. E a operação de REDO ou refazer que especifica que certas operações de uma transação devem ser refeitas para garantir que todas as operações de uma transação efetivada (commited) foram aplicadas com sucesso ao banco de dados. Ambas as transações são consideradas idempotentes, ou seja, se aplicadas várias vezes produzem o mesmo efeito de serem executadas apenas uma vez. O exemplo do REDO é bem claro neste ponto, se quisermos atribuir um novo valor a coluna salário de um determinado funcionário. O funcionário receberá 20 mil reais ao invés de 10 mil. Contudo, durante a execução da transação que faria a alteração, ocorreu uma falha no sistema de banco de dados. Vamos então voltar o salário do funcionário para seu valor antigo, ou seja, 10 mil. Não importa se o valor atual seja igual ao valor final proposto pela transação, ao aplicarmos a operação de REDO várias vezes seguidas teremos como resultado o valor antigo. Vejamos mais uma questão sobre transações: 3. Ano: 2012 Banca: IADES Orgão: EBSERH Cargo: Analista de TI – Banco de dados Q. 39 Em relação aos conceitos de transações, assinale a alternativa correta. (A) Uma transação é considerada como terminada, somente se tiver sido confirmada (commit). (B) As transações acessam os dados, usando duas operações: read e write. (C) Quando uma transação tiver sido confirmada (commit), podemos desfazer seus efeitos, abortando-a. (D) A propriedade ATOMICIDADE diz que depois que uma transação for completada com sucesso, as mudanças persistem, ou seja, são atômicas. (E) A propriedade ISOLAMENTO diz que a execução de uma transação isolada, preserva a consistência do banco de dados. Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 7 de 41 Comentários: Vamos analisar cada uma das alternativas acima. Vimos que a máquina de estados de uma transação pode chegar ao estado final pelo caminho feliz, onde todas as operações são executadas com sucesso e a transação pode ser efetivada. Contudo, caso a transação falhe por algum motivo, é possível que a operação de rollback seja executada, levando ao termino da transação sem a execução do commit. De forma simples, como observamos na máquina de estado de uma transação, os dados são acessados por meio de operações de leitura ou escrita. Sendo assim, a alternativa B é a nossa resposta. Após uma transação ter sido confirmada não é possível desfazer seus efeitos por meio de operações de rollback. Existe uma forma de restaurar o seu banco e dados para um determinado momento do tempo, mas isso é feito por meio dos arquivos de backup e usando os dados armazenados nos arquivos de log. A definição presente na alternativa D confunde a característica de DURABILIDADE com ATOMICIDADE. A alternativa E também apresenta o conceito de CONSISTÊNCIA misturado com o de ISOLAMENTO. Gabarito: B 2.3. Ponto de efetivação Uma transação T alcança seu ponto de efetivação (commit point) quando todas as suas operações que acessam o banco de dados foram executadas com sucesso e o efeito de todas elas estiver gravado no log. Após o ponto de efetivação, a transação é dita efetivada e seu efeito será gravado de modo permanente no banco de dados. Se tivermos uma falha, todo registro de transação com [start transaction, T] e sem [commit, T] deve ser revertido. Contudo, se tivermos o registro de [commit, T] a efetivação deve ser garantida. O registro do commit no log caracteriza o ponto de efetivação, nele todas as operações que acessam o banco de dados foram executadas com sucesso e o efeito de todas as operações da transação já foi gravado no log. Outro conceito relevante é o checkpoint. Escritos no log periodicamente quando o sistema grava no disco todas as operações de escrita de transações efetivadas. O gerenciamento de recuperação do SGBD deve decidir quais os intervalos em que devem ocorrer checkpoints. Geralmente as opções são definir uma unidade de tempo ou um número de transações efetivadas após o último checkpoint. Quando o SGBD realiza a operação de checkpoint ele basicamente: suspende temporariamente a execução de transações, força a escrita de todas as operações de modificação das transações efetivadas do buffer de memória no disco, escreve um registro [checkpoint] no log, força a escrita do log no disco e finalmente volta à execução das transações. O registro de checkpoint pode conter algumas informações adicionais como a lista dos identificadores das transações ativas e os endereços do primeiro e do último registro no log, para cada uma das transações. Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 8 de 41 2.4. Plano de execução A ordem de execução das operações de transações distintas executando concorrentemente de forma intercalada é conhecida como plano de execução ou escalonamento. Um escalonamento S de ‘n’ transações T1, T2, ..., Tn é um ordenamento das operações dessas transações, sujeito à restrição de que para cada transação Ti em S, as operações de Ti em S devem aparecer na mesma ordem que ocorrem em Ti. Observe, entretanto, que operações de outras transações Tj ou Tk poderão ser intercaladas com operações de Ti em S. Para fins de restauração e controle de concorrência estamos interessados principalmente nas operações de: ler_item(r) e escrever_item(w), commit(c) e abort(a). Principalmente queremos entender os acontecimentos quando operações de diferentes transações entram em conflito. Duas operações são ditas em conflito se elas satisfazem todas as três condições seguintes: 1. Pertencerem a transações diferentes, 2. Acessarem o mesmo item X, e 3. Pelo menos uma das operações sobre o item X ser um escrever_item(X). Com base no conhecimento que vimos até aqui podemos definir o conceito de plano completo. A ideia é montar uma sequência lógica para todas as transações dentro de um determinado plano que faça algumas restrições sobre a execução das operações e seus resultados. Um plano S, com n transações T1, T2, ... ,Tn é chamado um plano completo se forem garantidas as seguintes condições: 1. As operações em S são exatamente as operações de T1, T2, ..., Tn, tendo um commit ou um abort como última operação de cada transação no plano. 2. Para quaisquer pares de operações da mesma operação Ti, sua ordem de aparecimento em S será a mesma de Ti. 3. Para quaisquer duas operações conflitantes, uma das duas precisa aparecer antes da outra no plano. A condição três permite que duas operações não conflitantes apareçam no plano sem definir qual deva aparecer primeiro, levando assim, à definição de ordenação parcial das operações das n transações. Em alguns planos é fácil a restauração de transações, enquanto em outros, o processo pode ser muito complicado. Portanto, é importante caracterizar os tipos de planos nos quais a restauração é possível, bem como aqueles para os quais a restauração é relativamente simples. Essas caracterizações, na realidade não fornecem um algoritmo de restauração, apenas tentam caracterizar teoricamente os diferentes tipos de planos. Um plano considerado restaurável é aquele no qual, para cada par de transações Ti e Tj, tal que Tj leia itens de dados previamente escritos por Ti, a operação de efetivação de Ti apareça antes da operaçãode efetivação de Tj. Isso vai evitar que Ti sofra rollback depois da efetivação de Tj. Veja a figura a seguir: Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 9 de 41 Observem a figura acima, supondo que a transação Ti do plano não restaurável falhe e que a transação Tj ainda não estivesse sido efetivada, teríamos um caso conhecido como reversão em cascata. Nele uma transação não efetivada tem de ser revertida porque leu um item de outra transação que falhou. É importante estabelecer planos livres de reversão em cascata. Uma possível solução é fazer com que uma transação somente possa ler os itens que foram gravados por transações efetivadas. 2.5. Serialidade (Serializability) Os planos de execução são considerados seriais se as operações de cada transação são executadas consecutivamente, sem intercalação das operações de outra transação. Apenas uma transação está ativa por vez, isso limita a concorrência ou intercalação de transações e são inaceitáveis na prática. Contudo não podemos simplesmente liberara geral, e deixar que os planos sejam executados na ordem que bem entenderem. É imposto, portanto, uma restrição ao plano, que ele seja serializável. O conceito de serialidade de planos é usado para identificar quais planos são corretos quando há intercalação das operações das transações na execução dos planos, ou seja, as transações não são isoladas. A teoria da seriabilidade é uma das técnicas padrão para discutir a corretude de algoritmos de controle de concorrência, tais como o protocolo de bloqueio em duas fases. Um exemplo clássico de uma execução não isolada é um sistema bancário, onde duas transações tentam retirar os últimos R$ 100,00 em uma conta. Se ambas as transações lerem o saldo da conta antes de qualquer uma deles atualizar, ambas as transações irão determinar há dinheiro suficiente para satisfazer aos pedidos, e ambas vão retirar os últimos R$ 100,00. Claramente, isto é o resultado errado. Além disso, não é um resultado serializável. Numa execução serial, apenas a primeira operação seria capaz de retirar os últimos R$ 100,00. A segunda seria encontrar uma conta vazia. Note que o isolamento é diferente de atomicidade. No exemplo, ambas as transações executadas por completo, de modo que foram atómicas. No entanto, elas não foram devidamente isoladas e, portanto, produziram um comportamento indesejável. Se cada transação preserva a consistência, então qualquer execução serial (isto é, sequência) de tais transações preserva consistência. Uma vez que cada execução serializável é equivalente a uma execução serial, uma execução serializável das transações irá preservar a consistência do banco de dados também. É a combinação de consistência das transações e do isolamento que Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 10 de 41 garante que, na execução de um conjunto de operações, seja preservada a consistência do banco de dados. O banco de dados normalmente define bloqueios em dados acessados por cada transação. O efeito da configuração dos bloqueios é fazer com que a execução pareça ser em série. Na verdade, internamente, o sistema está executando operações em paralelo, mas através deste mecanismo de bloqueio do sistema dá a ilusão de que as operações estão executando em série, uma após a outra. Um equívoco comum é que a serialização não é importante porque o sistema de banco de dados irá manter a consistência através da aplicação de restrições de integridade. No entanto, há muitas restrições de consistência que os sistemas de banco de dados não podem impor. Além disso, às vezes os usuários não dizem ao sistema de banco de dados para impor certas restrições, porque elas degradam o desempenho. A última linha de defesa é que o mecanismo de controle de concorrência em si mantenha a consistência e que o sistema garanta a execução de forma serializável. 2.5.1. Equivalência de planos Dois planos são chamados resultado equivalentes se produzirem o mesmo estado final do banco de dados. Para dois planos serem equivalentes, as operações aplicadas a cada item de dado afetado por eles devem aparecer na mesma ordem em ambos os planos. Quando temos operações em conflito precisamos que a ordem de execução destas operações seja a mesma nos dois planos de execução, isso nos leva a ideia de equivalência de conflito. Um plano de execução S com n transações é dito serializável se ele for equivalente a algum plano serial com as mesmas n transações. Dizer que um plano S não serial é serializável é o mesmo que dizer que ele é correto. Outro conceito que trata de equivalência é o da equivalência de visão. A ideia básica da equivalência de visão é a de que, enquanto cada operação de leitura de uma transação estiver lendo o resultado da mesma operação de gravação em ambos os planos, as operações de gravação de cada transação precisam produzir os mesmos resultados. Vejam a definição formal abaixo, suponha que Ri é uma operação de leitura e Wj uma operação de escrita. Diz que dois planos S e S’ são visão equivalente se: O conjunto de transações participantes em S e S’ seja o mesmo e que S e S’ contenham as mesmas operações dessas transações. Para toda operação ri(X) de Ti em S, se o valor X lido pela operação tiver sido alterado por uma operação wj(X) de Tj, a mesma condição deverá ser garantida para o valor X lido pela operação ri(X) de Ti em S’. Se a operação wk(Y) de Tk for a última operação a gravar o item Y em S, então wk(Y) de Tk também deverá ser a última operação a gravar Y em S’. A abordagem adotada na maioria dos SGBDs comerciais é definir protocolos ou um conjunto de regras que devem ser seguidos por todas as transações individualmente, ou impostos por um subsistema de controle de Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 11 de 41 concorrência do SGBD. Essas regras garantirão a serialidade de todos os planos dos quais as transações participam. Um exemplo de teste para verificar a existência de conflito serialidade é a utilização do grafo de precedência. Nele uma seta será criada caso alguma das operações de Tj apareça no plano antes de alguma operação conflitante de Tk. Veja a figura abaixo: Para a criação do gráfico de precedência devemos observas as operações de cada transação que participa do plano de execução e rodar o seguinte algoritmo: 1. Para cada transação Ti participante do plano S, criar um nó rotulado Ti no grafo de precedência. 2. Para cada caso em S em que Tj executar um ler item(X) depois que uma Ti executar um escrever item(X), criar uma seta Ti Tj no grafo de precedência. 3. Para cada caso em S em que Tj executar um escrever_item(X) depois que uma Ti executar um ler_item(X), criar uma seta Ti Tj no grafo de precedência. 4. Para cada caso em S em que Tj executar um escrever_item(X) depois que uma Ti executar um escrever_item(X), criar uma seta Ti Tj no grafo de precedência. 5. O plano S será serializável se, o grafo de precedência não contiver ciclos. Vejam a figura a seguir a construção de diferentes planos de execução a partir das mesmas transações. Vejam que alguns planos podem ser serializáveis e outros não. Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 12 de 41 2.6. Suporte a transação em SQL Uma transaction é um mecanismo que podemos utilizar para mantera integridade e a consistência dos dados. SQL nos ajuda a gerencias transações. SQL padrão definiu transações logo no início da criação do modelo e vem aprimorando o conceito durante iterações subsequentes. De acordo com a norma, uma transação é iniciada pelo SGBDR, e continua até que uma instrução de COMMIT ou ROLLBACK é emitida. Os detalhes foram deixados para o SGBD implementar. Os comandos de gerenciamento de transações do SQL padrão estão listados na tabela abaixo: Comando Descrição START (BEGIN) TRANSACTION Inicializa uma transação SQL e seta as suas características. SET TRANSACTION Determina as propriedades da próxima transação SQL para o SQL Agent SET CONSTRAINTS Se a transação SQL estiver executando, estabelece o modo de restrições para a transação SQL na sessão corrente. Se não existe nenhuma transação em andamento na sessão, determina ao SQL Agent o modo de execução para a próxima transação. SAVEPOINT Estabelece um savepoint, ponto intermediário da transação para o qual o rollback deve retornar em caso de falha. RELEASE SAVEPOINT Destrói um savepoint COMMIT Termina a transação SQL corrente com um commit ROLLBACK Termina a transação corrente com um rollback, ou desfaz todas as modificações até o último savepoint. O padrão SQL utiliza de forma implícita o START TRANSACTION, com uma instrução de COMMIT explícita, nos casos em que todas as unidades lógicas de trabalho de uma transação são concluídas com sucesso. Podemos ainda ter a instrução de ROLLBACK quando mudanças ainda não efetivadas precisam ser desfeitas devido a alguma exceção ou erro. Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 13 de 41 As implementações dos SGBDs para controle de transação são um pouco diferentes para cada um deles, contundo a análise detalhada destes comandos foge do escopo deste curso. Vamos passar agora para uma rápida explicação dos níveis de isolamento de transações. Mais detalhes sobre esse assunto serão vistos em aulas específicas sobre transações e controle de concorrência. Quando executamos várias transações de forma concorrente sobre o mesmo banco de dados podemos limitar o acesso as informações para impedir que elas sejam vistas por uma transação no momento que estão sendo usadas por outra transação. São quatro os níveis de isolamento definidos pelo SQL ANSI: READ UNCOMMITED, READ COMMITED, REPEATABLE READ e SERIALAZABLE. No primeiro caso READ UNCOMMITED é permito ler dados que ainda não sofreram o COMMIT de outra transação X que ainda está em execução. Isso acaba possibilitando a existência do problema de leitura suja ou dirty read. Esse problema ocorre se a transação X sofrer ROLLBACK. Neste caso, qualquer outra transação que tiver feito uma consulta sobre o dado modificado por X terá feito uma leitura suja. Para resolver esse problema surge o próximo nível de isolamento conhecido como READ COMMITED. Neste caso uma transação Y só pode ler os dados modificados pela transação X após o COMMIT. Agora ainda permanecemos com outro problema denominado leitura não repetível. Imagine que Y precisa ler os dados modificados por X duas vezes durante a transação. Na primeira leitura Y ler os dados modificados por X, contudo, antes da segunda leitura, outra transação Z faz uma nova modificação sobre os dados. Veja que Y faz duas leituras sobre o mesmo dado durante a transação e eles possuem valores distintos. A solução para o problema da leitura não repetível está no REPEATABLE READ. Neste caso a transação Y vai ler os mesmos dados, pois não será permito a transação Z fazer modificações sobre eles durante a execução de Y. Agora contamos com um último problema, qual seja, a possibilidade da existência de registros fantasmas. Neste caso Y faz duas leituras sobre um conjunto de dados ou tuplas de uma relação que satisfação a uma condição descrita na cláusula WHERE. Suponha que entre a primeira e a segunda leitura seja inserido um registro que também satisfaz a essa condição de busca. Esse registro é considerado um fantasma! Para resolver todos esses problemas, temos o último nível de isolamento conhecido como SERIALAZABLE. A ideia é executar concorrentemente apenas as transações que produzam o mesmo resultado caso fossem executadas em série. Além do nível de isolamento é possível determinarmos o modo de acesso de uma transação que pode ser READ ONLY ou READ WRITE e o amanho da área de diagnóstico que especifica um valor inteiro n, indicando o número de posições Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 14 de 41 que podem ser manipuladas simultaneamente na área de diagnóstico. Essas condições fornecem informações sobre as condições de execução (erros e exceções), ao usuário ou ao programa, para a maior parte das declarações SQL executadas mais recentemente. Para executar uma transação usando SQL podemos utilizar a seguinte sintaxe: Controle de concorrência 3. A importância do controle de concorrência De um modo geral, os sistemas de aplicação atuais, e, especialmente, aqueles que funcionam dentro do ambiente de banco de dados, supõe que muitas pessoas que utilizam estes sistemas e necessitem de acesso aos mesmos dados ao mesmo tempo. Um hardware moderno e sistemas de software são certamente capazes de suportar tal acesso aos dados compartilhados. Um exemplo muito comum dessa capacidade está em reservas de passagens aéreas, onde vários funcionários diferentes reservam bilhetes, bem como os clientes na Web, todos podem ter solicitações simultâneas de assentos no mesmo voo. Outro exemplo é um aplicativo de inventário ou estoque de uma indústria em que vários funcionários procuram simultaneamente para atualizar o mesmo item de estoque. Quando o acesso simultâneo envolve apenas a simples recuperação de dados, não há nenhum problema. Mas quando o acesso simultâneo requer a modificação de dados, os dois ou mais usuários que tentam atualizar os dados, simultaneamente, têm um problema desagradável por interferir uns nos outros EXEC SQL WHENEVER SQLERROR GOTO UNDO; EXEC SQL SET TRANSATION READ WRITE DIAGNOSTIC SIZE 5 ISOLATION LEVEL SERIALAZABLE EXEC SQL INSERT INTO EMPREGADO (PNOME, UNOME, SSN, DNO, SALARIO) VALUES (´Thiago´, ´Cavalcanti´, 000457878, 2, 12000); EXEC SQL UPDATE EMPREGADO SET SALARIO = SALARIO *1,1 WHERE DNO =2; EXEC COMMIT; GOTO THE_END; UNDO: EXEC SQL ROLLBACK; THE_END: ...; Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 15 de 41 que não aconteceria se eles estivessem apenas realizando consultas de dados. Este é certamente o caso das reservas de passagens aéreas e do exemplo de inventário, uma vez que a venda de assentos em voos e a manutenção de itens no inventário exigem que o número de assentos ou os itens de estoque sejam atualizados. Isto é, muitos acessos a base de dados envolvem alterações. O resultado pode ser imprecisão nos dados armazenados no banco de dados! Como controlar esse tipo de problema é o que veremos agora. 3.1. Por que o controle de concorrência? De uma forma mais sistemática existem alguns problemas que acontecem quando transações simultâneas resolvem fazer alterações sobre o mesmo conjunto de dados. O primeiro problema refere-se a atualização perdida. Se uma transação modifica um dado e antes de concluir outra transação atualiza o mesmo dado essa mudança fica perdida no tempo e no espaço. Para evitar problemas deste tipo os SGBDs implementam um subsistema de controle de concorrência. Concorrência éa propriedade de uma transação poder ser executada em paralelo com outras transações. Com a execução de várias transações ao mesmo tempo, o processador pode ser compartilhado entre elas, melhorando a eficiência global do computador, dado que uma maior quantidade de trabalho é executada em menos tempo. É necessário que o sistema monitorize a interação entre transações concorrentes, de modo a evitar que elas destruam a consistência do banco de dados e mantenham o isolamento das transações. Para isso fazemos uso de técnicas ou protocolos, por exemplo, técnica de bloqueio, timestamp e protocolos baseados em gráficos. Vamos falar um pouco sobre cada um deles. 3.2. Técnicas de bloqueio Quando começamos a estudar as técnicas de bloqueio a primeira definição que temos que ter em mente está relacionada ao LOCK. Ele é uma variável associada a um item de dados no BD que descreve o status desse item com respeito a possíveis operações a serem aplicadas a ele. Uma das taxonomias principais divide os LOCK em binários e múltiplos. O lock binário possui dois estados de valores possíveis para cada item de dados: locked (1) e unlocked (2). Um lock distinto é associado a cada item do banco de dados denotado como lock (x) para o item x. As operações incluídas nas transações, lock_item e unlock_item, são implementadas como operações indivisíveis. Um gerenciador é mantido pelo SGBD para registrar e controlar o acesso a locks. Um registro de lock descrito como <nome-do-item, LOCK> é inserido na tabela de locks que mantém o controle sobre esses registros. Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 16 de 41 Para o conjunto de operações algumas regras podem ser aplicadas. Uma transação T tem que executar uma operação lock_item(x) antes de qualquer read_item ou write_item executada por T. Uma transação T tem que executar a operação unlock_item(x) após todo read/write completados em T. Uma transação não pode executar outra operação lock_item(x) se já tem um lock sobre x. Uma transação T não pode executar um unlock_item(x) a menos que tenha um lock sobre x. Apenas uma transação pode ter um lock num dado item seja para efetuar operações de leitura ou escrita. Para resolver esse problema surge o LOCK MÚLTIPLO. O Lock múltiplo apresenta três operações indivisíveis: read_lock(x), write_lock(x) e unlock(x). Conhecidos também como bloqueio compartilhado e exclusivo, o read_lock e o write_lock, fazem o papel de efetivar bloqueio sobre os itens de dados que participarão da transação. Um registro do lock pode ser feito com as seguintes informações <nome-do-item, LOCK, (número-de-leituras) >. Veja que o número de leituras é opcional. Da mesma forma que o bloqueio binário, o LOCK MÚLTIPLO também apresenta um conjunto de regras. Muitas vezes, elas nos parecem um pouco obvias, mas ajudam a compreender o funcionamento. Vamos a elas: • Uma transação T tem que executar uma operação read_lock(x) ou write_lock(x) antes de qualquer read_item(x) em T. • Uma transação T tem que executar uma operação write_lock(x) antes de qualquer write_item(x) em T. • Uma transação tem que executar uma operação unlock(x) após todas as operações read_item(x) e write_item(x) completadas em T. • Uma transação T não executará um read_lock(x) se já tem um lock (read) compartilhado ou um lock (write) exclusivo em x, este item precisa ter seu lock relaxado, passando de write para read_lock para a execução do read_lock(x) por T. • Uma transação T não executará outro write_lock(x) se já tem um lock (write) exclusivo ou um lock (read) compartilhado em x, agora podemos incrementar o bloqueio se a transação já tiver o lock de leitura e quiser tomar para si o lock de escrita. É necessário que se verifique se nenhuma outra transação está com o lock de leitura antes de efetuar o incremento de lock sobre o item de dados. • Uma transação T não executará um unlock(x) a menos que já tenha um lock compartilhado ou exclusivo em x. Resumindo agora os conceitos de incremento, decremento e bloqueios exclusivos. O incremento de lock acontece quando uma transação após ter um read_lock(x) e sendo a única que detém x, pode posteriormente executar um Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 17 de 41 write_lock(x) sobre x. O decremento de lock, por sua vez, é feito após ter um lock exclusivo sobre um item x, uma transação T pode decrementar o lock, executando um read_lock(x). Os bloqueios exclusivos levam em consideração se uma transação T contém um bloqueio exclusivo em algum objeto, então nenhuma transação distinta T’ pode fazer bloqueio daquele objeto até que T libere o seu bloqueio. Locks binários ou múltiplos não garantem a serializabilidade de escalonamentos nos quais as transações participam. É necessário um protocolo adicional que contempla o posicionamento de locks e unlocks em cada transação, conhecidos como protocolo de bloqueio. 3.3. Protocolo de bloqueio em duas fases O protocolo de bloqueio em duas fases está baseado em duas etapas. A fase de expansão onde uma transação pode obter bloqueio, mas não pode liberar nenhum. E a fase de encolhimento nela uma transação pode liberar bloqueios, mas não consegue obter nenhum bloqueio novo. O ponto que caracteriza o fim da fase de expansão é denominado ponto de bloqueio. Veja a figura abaixo: Se não usarmos o bloqueio, ou desbloqueio, dos itens de dados, tão logo seja possível, após sua leitura ou escrita, poderemos chegar a resultados inconsistentes. Por outro lado, se não desbloquearmos um item de dados antes de solicitarmos um bloqueio a outro item de dados, o deadlock poderá ocorrer. Os protocolos de bloqueio restringem o número de escalas de execução possíveis. Existe um conjunto de variações do protocolo visto acima. Além do básico, visto na figura, temos os protocolos conservador ou estático, estrito ou severo e rigoroso. O protocolo conservador ou estático bloqueia todos os itens que acessará, antes de iniciar a execução da transação. Ele só bloqueia quando todos os dados estão disponíveis. No protocolo estrito ou severo, considerado o mais popular, não se libera os locks de escrita até o commit ou abort. Por fim temos o protocolo rigoroso que não libera os locks de escrita e leitura até o commit ou abort, e é mais fácil de implementar do que o estrito. Protocolo de bloqueio em duas fases rigoroso, que exige que todos os bloqueios sejam mantidos até que a transação seja efetivada. Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 18 de 41 Vejam de forma gráfica como cada um dos protocolos se comporta junto aos locks durante um intervalo de tempo. A sua utilização pode causar problemas de daedlock ou starvation. Deadlock é uma situação em que duas ou mais transações estão em estado simultâneo de espera, cada uma aguardando que uma das demais libere um bloqueio para ela poder prosseguir. Vejam a figura a seguir que mostra um exemplo gráfico do caso. Existem alguns protocolos que atuam na prevenção do Deadlock. O conservador, nele, se algum dos itens não pode ser bloqueado, nenhum será bloqueado. E o ordenado que tenta impor uma ordenação em todos os itens e os locks só podem ocorrer segundo esta ordem. Os principais métodos para solucionar o impasse podem resultar na repetição da transação. Quando uma transação solicita um bloqueio de um registro que já está bloqueado por outra transação, então um dos dois procedimentos é seguido: Wait-die (esperar-morer) - se a transação que solicitouo bloqueio é a mais antiga, pode aguardar. Se for a mais nova, sofre rollback e recomeça mais tarde com mesmo timestamping. Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 19 de 41 Wound-wait (ferir-esperar) – se uma transação mais nova solicitar o bloqueio e o item estiver bloqueado por uma transação mais antiga, a transação mais nova pode aguardar. Se for a mais antiga que estiver solicitando, então ela interrompe a mais nova, a qual sofre rollback e recomeça mais tarde com mesmo timestamping. Duas considerações importantes, a primeira refere-se ao fato das transações que são abortadas retornam posteriormente com o mesmo timestamp. A segunda que você pode perceber que a primeira palavra de cada um dos métodos trata do que vai acontecer ou qual a ação tomada pela transação mais antiga e a palavra seguinte trata da ação referente a transação mais nova. A ação será tomada sempre que uma transação solicitar o bloqueio de um item de dados. Essa é uma técnica de prevenção de impasses. Contudo, nem sempre é possível prever se algum conjunto de transações do banco de dados está em deadlock. Deve-se então executar ações que possam detectar a existência do problema no banco. Uma possibilidade é executar a verificação sempre que uma solicitação de bloqueio gere uma ação de espera. Permite a execução imediata de um impasse, porém tem um custo de processamento muito alto, acarretando um overhead sobre o banco de dados. Outra possibilidade seria realizar o procedimento em intervalos periódicos. Observamos de cara que isso reduz o overhead, contudo alguns deadlocks são verificados tardiamente. Não existe uma solução perfeita. Porém, alguns cuidados durante a construção dos sistemas podem reduzir substancialmente o risco de impasses. É importante criar sistemas com transações curtas e com uma pequena interferência entre as transações. O ideal é que cada transação solicite o lock de poucos itens de dados. Esse cenário cria uma carga leve com baixo risco de problemas de deadlock. Ao detectar um deadlock devemos tomar alguma ação para quebra-lo. A quebra de deadlock consiste na escolha de uma das transações para forçá-la a um rollback. A escolha pode ser feita das seguintes formas: 1. A transação que foi iniciada mais recentemente, 2. A que tiver feito o menor número de bloqueios ou 3.A que tiver feito o menor número de atualizações. Terminamos aqui nossos comentários sobre deadlock, vamos agora falar um pouco sobre livelock e starvation. No livelock a transação não pode prosseguir por um período indefinido de tempo enquanto outras transações continuam normalmente, esse fato ocorre por conta de um esquema injusto de espera por locks. Podemos resolver o problema de duas formas: associar um protocolo onde o primeira a chegar será Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 20 de 41 o primeiro a ser servido (first-come-first-serve) ou criar um esquema de incremento de prioridade baseado no timestamp da transação. Starvation é um problema similar ao livelock, ocorre se o algoritmo seleciona a mesma transação como vítima repetidamente, causando abort repetidos e nunca acabando a execução. Os protocolos wait-die e wound-wait apresentados evitam starvation. 3.4. Protocolo com base em Grafos Esse protocolo exige conhecimento anterior sobre a ordem na qual os itens de banco de dados são acessados. Um exemplo deste protocolo onde seria permitida somente a instrução de bloqueio lock-X. Cada transação Ti, pode bloquear um item de dado no máximo uma vez e deve observar as seguintes regras: 1. O primeiro bloqueio feito por Ti pode ser sobre qualquer dado 2. Subsequentemente, um item de dado Q pode ser bloqueado por Ti somente se os pais de Q estivem bloqueados por Ti 3. Itens de dados podem ser desbloqueados a qualquer momento 4. Um item de dado foi bloqueado e desbloqueado por Ti não pode ser “rebloqueado” por Ti. Vejam um exemplo de um gráfico gerado por um conjunto de transações e ao lado um plano de execução para as transações envolvidas. 3.5. Ordenação por Timestamp A cada transação Ti do sistema associamos um único timestamp fixo, denotado por TS(Ti). Esse é criado pelo SBD antes que a transação Ti inicie sua execução. Se uma transação Ti recebeu o TS(Ti) e uma nova transação Tj entra no sistema, então TS(Ti) < TS(Tj). Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 21 de 41 Existem duas formas de implementar. Usar a hora do relógio do sistema (clock) como timestamp, isto é, o timestamp de uma transação é igual à hora em que a transação entra no sistema. Usar um contador lógico que é incrementado sempre que se usa um novo timestamp, isto é, o timestamp da transação é igual ao valor do contador no momento em que a transação aparece no sistema. O protocolo que utiliza timestamp pode seguir alguns passos que dependem de tipo de bloqueio solicitado pela transação. Cada item Q tem um timestamp de escrita e outro de leitura denotado por W-timestamp(Q) e R- timestamp(Q). 1. Suponha que a transação Ti emita uma instrução read(Q) a) Se TS(Ti) < W-timestamp(Q), então Ti precisa ler um valor de Q que já foi sobreposto. Assim, a operação read é rejeitada e Ti é desfeita. Isso significa que a transação está tentando ler um dado que foi modificado por outra transação ou está bloqueado para leitura. b) Se TS(Ti) >= W-timestamp(Q), então a operação read é executada e R-timestamp(Q) recebe o maior valor entre R-timestamp(Q) e TS(Ti) 2. Suponha que a transação Ti emita uma write(Q) a) Se TS(Ti) < R-timestamp(Q), então o valor de Q que Ti está produzindo foi necessário antes e o sistema assumiu que aquele valor nunca seria produzido. Logo, a operação write é rejeitada e Ti é desfeita. b) Se TS(Ti) < W-timestamp(Q), então Ti está tentando escrever um valor obsoleto em Q. Logo, essa operação write é rejeitada e Ti é desfeita. c) De outro modo, a operação write é executada e o W-timpstamp(Q) é registrada com o valor de TS(Ti). A ideia é que utilizando esse protocolo a transação não vai ler um item se outra transação com um timestamp posterior estiver marcado o item. Neste caso ela precisa ser desfeita e reiniciar com um novo TS. A mesma ideia vale para operação de escrita, se a transação for bloquear um item para escrita o TS da transação precisa ser maior do que o TS de leitura e de escrita do item. Vamos agora tratar do contexto teórico de recuperação após falha. Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 22 de 41 Recuperação após falha 4. Recuperação após falha O termo recuperação ou restauração após falha está associado a trazer o sistema ou o banco de dados de volta a um estado consistente. A falha pode estar associada a diversos motivos: o computador ou servidor de banco de dados pode falhar, algum erro pode acontecer durante o processamento de uma transação, uma condição de exceção foi detectada, o protocolo de controle de concorrência impõe um rollback a uma transação, uma falha no disco ou, ainda, problemas físicos ou catastróficos. Todos esses problemas listados acima podem levar nosso sistema de banco de dados a usar o processo de recuperação dos dados. Vamos agora tentar explicar como esse processo acontece de fato. O modelo genérico apresentado funciona para a maioria dos SGBDs comerciais. Algoritmos de recuperaçãopodem ser divididos em duas partes: 1. Ações tomadas durante o processamento normal da transação a fim de garantir que haja informação suficiente para permitir a recuperação de falhas. 2. Ações tomadas logo após a falha, recuperando o conteúdo do banco de dados para um estado que assegure sua consistência, atomicidade da transação e durabilidade. Após uma falha na execução de uma transação, o banco de dados deve ser restaurado para um estado consistente imediatamente anterior a falha. O Sistema deve manter informações sobre as atualizações do banco de dados armazenadas separadamente em um arquivo de log. 4.1. Classificação das falhas As falhas podem ser subdivididas em falha de transação, que inclui os erros lógicos e erros de sistemas, queda de sistema e falha em disco. Vamos examinar cada uma delas para entender o seu significado. Erro lógico: A transação não pode mais continuar com sua execução normal devido a alguma condição interna, como entrada inadequada, um dado não encontrado, overflow ou limite de recurso excedido. Erro de sistema: O sistema entrou em estado inadequado (por exemplo, deadlock, livelock, starvation), com isso, uma transação não pode continuar sua execução normal. A transação pode ser reexecutada posteriormente. Queda do sistema: Há algum mau funcionamento de hardware ou um bug no software de banco de dados ou no sistema operacional que causa a perda do conteúdo no armazenamento volátil e fez o processamento da transação parar. O conteúdo de armazenamento não volátil permanece intato e não é corrompido. Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 23 de 41 Falha de disco: Um bloco de disco perde seu conteúdo em função da quebra do cabeçote ou da falha durante uma operação de transferência de dados. São usadas para recuperação do sistema após a falha, as cópias dos dados em outros discos ou backups de arquivos em meios terciários, como fitas. 4.2. Estrutura de armazenamento Para começarmos a entender a estrutura padrão de armazenamento precisamos ter em mente dois conceitos. O primeiro refere-se à volatilidade. O dado pode estar gravado na memória principal, conhecida como volátil, nela a informação permanece apenas enquanto o sistema estiver em execução. Outra possibilidade é o dado ser armazenado em um disco rígido ou outro dispositivo não volátil. Neste caso o dado possui a propriedade da durabilidade e não deve ser perdido. Outro ponto importante é a possibilidade de usar mecanismos de redundância para garantir a durabilidade da informação no caso de uma falha nos discos. Uma estrutura de RAID - redundant array of independent disks – pode garantir essa propriedade por meio da replicação da informação em diferentes discos. Vamos agora focar nossa atenção no entendimento do processo de transferência de informação da memória para o disco. Esse processo é de suma importância para a recuperação. Observem a figura abaixo: Vejam que existem na figura dois conjuntos de operações: read/write e input/output. O primeiro par é responsável pela leitura dos dados da memória principal. Cada espaço da memória é conhecido como bloco de buffer. O processador vai enviar um comando de read(A) para ler a informação na memória principal. Vejam que no exemplo o bloco de memória contendo o dado A ainda não está devidamente armazenado na memória principal. Neste momento uma operação de entrada e saída é inicializada. Os dados são encontrados num bloco físico do disco que é transferido para um bloco de buffer. A transferência de blocos entre a memória e o armazenamento de disco pode resultar em: 1. Conclusão bem-sucedida: A informação transferida chegou de forma segura a seu destino. 2. Falha parcial: Uma falha ocorreu no meio da Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 24 de 41 transferência e o bloco de destino contém informação incorreta. 3. Falha total: A falha ocorreu muito cedo, de modo que o bloco de destino permanece intacto. As operações de input e output são responsáveis por enviar e trazer os dados do disco para a memória principal. Sendo assim, o comando de Input(X) transfere o bloco físico X para a memória principal, e Output(X) transfere o bloco de buffer X para o disco e troca-o, no disco, pelo bloco físico apropriado. 4.3. O uso dos arquivos de log O que acontece quando uma transferência de dados entre a memória principal termina com falha? Sabemos que o da não foi devidamente armazenado em disco. Neste momento aparece a necessidade de um arquivo de log. Armazenada em um local diferente dos arquivos de dados, o arquivo de log deve ser afetado sempre que uma transação realiza uma escrita, é essencial que o registro de log para aquela escrita seja criado antes do banco de dados ser modificado. Lembrem-se o log deve residir em armazenamento estável! Um registro de log deve conter um identificador da transação (Ti), um identificado do item de dado (Xj), o valor antigo do dado (V1) e o valor novo (V2). Um registro de log pode ser descrito da seguinte forma: <Ti, Xj, V1, V2>. Outras informações que também devem aparecer no log dizem respeito das operações executadas que nos levam ao estado da transação. Temos, portanto, dentro do log as seguintes informações: <Ti start>, <Ti commit>, <Ti abort>. A terminologia padrão para recuperação de SGBDs inclui os termos roubado/não roubado (steal/no-steal) e forçado/não forçado (force/no-force), que especifica quando uma página do banco de dados poderá ser gravada em disco a partir do cache. Se uma página em cache atualizada por uma transação não puder ser gravada antes que a transação se efetive, ela será chamada de abordagem não roubada. O bit de pin-unpin indicará se a página não puder ser escrita de volta no disco. Do contrário, se o protocolo permitir o buffer atualizado antes que a transação se efetive, ele será chamado roubado (steal). Steal será usado quando o gerenciador do cache (buffer) do SGBD necessitar de um frame de buffer para outra transação, e o buffer substituir uma página existente que tenha sido atualizada, mas cuja transação não tenha se efetivado. Se todas as páginas atualizadas por uma transação forem imediatamente escritas no disco quando a transação se efetivar, ela será chamada abordagem forçada. Do contrário, será chamada não forçada. 4.4. Modificações adiadas e imediatas A modificação adiada garante atomicidade de transações quando todas as modificações do banco de dados são escritas no Log. Adia a execução de todas as operações write de uma transação até sua efetivação parcial, ou seja, imediatamente antes do checkpoint ou commit. Lembre-se de que uma transação é considerada parcialmente efetivada quando a ultima ação da transação tiver sido executada. Vejam um exemplo na figura abaixo: Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 25 de 41 Quando é utilizada a estratégia de modificação adiada os dados não são escritos no log até que a última ação da transação seja finalizada. Desta forma, garantimos que transação foi concluída quando escrita no log. Se uma falha acontecer, utilizaremos o log para refazer as modificações já executadas que não foram efetivamente gravadas em disco. Para tal, utilizamos a operação de Redo(Ti). Como não existe nenhum dado no disco que tenha sido gravado, mas que não tenha sua transação finalizada não precisamos desfazer nenhuma transação do disco. Esse protocolo é conhecido como NO-UNDO/REDO. Ele define o valor de todos os itens de dados atualizadospela transação Ti para os novos valores. A operação é idempotente, isto é, executá-la várias vezes geram o mesmo resultado. Após a ocorrência de uma falha, o subsistema de recuperação consulta o log para determinar quais transações têm de ser refeitas. Ti será refeita, se e somente se, o log contiver os registros <Ti start> e <Ti commit>. Sem <Ti commit> os registros de Ti devem ser removidos do log. Vamos agora falar da modificação imediata. Ela permite que as modificações no banco de dados sejam enviadas enquanto as transações ainda estão no estado ativo, ou seja, modificações não efetivadas. Na ocorrência de uma queda ou de uma falha de transação, o sistema deverá usar o campo relativo ao valor antigo dos registros do log para restauração dos itens de dados modificados e não efetivados. Antes que uma transação Ti inicie sua execução, o registro <Ti start> é escrito no log. Durante sua execução, qualquer operação de write(X) feita por Ti é precedida pela escrita apropriada do novo registro no log. Quando Ti é parcialmente efetivada o registro <Ti commit> é escrito no log. Vejam o exemplo abaixo do funcionamento das modificações imediatas. Para recuperação quando utilizamos modificação imediata temos que usar o protocolo UNDO/REDO. Fazendo primeiro as operações de undo e depois as operações de redo. As ações são descritas da seguinte forma. O Undo(Ti) retorna aos valores antigos todos os itens de dados atualizados pela transação Ti, se o log contém o registro <Ti start>, mas não tem o registro <Ti commit>. O redo(Ti) ajusta os valores de todos os itens de dados atualizados pela transação para os novos valores, se o log contém tanto o registro <Ti start> quanto o registro <Ti commit>. Lembrando que as duas operações são idempotentes. Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 26 de 41 4.5. Checkpoint Quando uma falha de sistema ocorre, devemos consultar o log para determinar aquelas transações que necessitam ser refeitas e aquelas que necessitam ser inutilizadas. A princípio deveríamos pesquisar todo o log. Para diminuir o overhead de leitura do log após uma falha podemos introduzir no log os pontos de controle ou checkpoints. Basicamente são exigidas três operações: 1. Operação de saída, para armazenamento estável, de todos os registros residentes na memória principal. 2. Operação de saída, para disco, de todos os blocos de buffer modificados. 3. Operação de saída para armazenamento estável, de um registro de log <checkpoint>. Não é permitido às transações processarem quaisquer ações de atualização, como escrever em um bloco de buffer ou escrever no registro de log, enquanto o checkpoint está em progresso. O tempo necessário para forçar a gravação de todos os buffers de memória modificados pode atrasar o processamento da transação. Vamos relembrar o processo de execução do checkpoint. 1. Suspender a execução das transações temporariamente 2. Forçar a gravação no disco de todos os buffers na memória principal que tenham sido alterados 3. Escrever um registro de [checkpoint] no log e forçar a gravação do log no disco 4. Reassumir o controle das transações. É possível usar uma técnica conhecida como fuzzy checkpoint, nela o sistema poderá reassumir o processamento das transações depois que o registro [checkpoint] for escrito no log. 4.6. Paginação Shadow Uma alternativa às técnicas de recuperação baseada em log é o uso da técnica de paginação shadow ou sombra. Ela exige (teoricamente) menos acessos ao disco, contundo é difícil de ser aplicada em transações concorrentes. Basicamente, pressupõe-se que o banco de dados seja composto por “n” páginas de tamanho fixo. Uma tabela de páginas com “n” entradas é então construída. A ideia é manter duas tabelas de página durante o processamento. A tabela de páginas atuais e a tabela de páginas shadow. Quando uma transação começa ambas as tabelas são idênticas. Então as operações são feitas na página corrente. Quando todas as alterações terminam a pagina corrente transforma em página shadow. As alterações, então são passadas para a nova página corrente. Vejam as três figuras que apresentam o passo-a-passo desse processo. A primeira representa o estado inicial. Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 27 de 41 A segunda figura representa as modificações, feitas apenas sobre a pagina corrente. A próxima e última figura representa a atualização da nova página corrente, devidamente atualizada. As páginas imagem, sombra ou shadow são úteis para ambientes monousuários, pois não precisamos de uma estrutura de log. Quando partimos para ambientes multiusuários pode ser necessário usar log, principalmente, se o método de controle de concorrência usar. A grande vantagem deste método é uma recuperação após falhas significativamente mais rápida, pois não há necessidade de Undo ou Redo de operações. Contudo a lista de desvantagens é enorme: A fragmentação de dados, nela, as páginas atualizadas mudam de localização no disco, impedindo de manter juntas páginas relacionadas; O overhead de efetivação, se a tabela de páginas é grande, o tempo para gravar as tabelas de páginas imagem no Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 28 de 41 commit é significativo; e a coleta de lixo ou garbage collection para liberação de páginas antigas que é necessário após o commit. Além dos inconvenientes mencionados, a adaptação da paginação shadow a sistemas com transações concorrentes é mais difícil que o registro de log. Em tais sistemas, algum tipo de registro de log é normalmente necessário, mesmo que a paginação shadow seja usada. 4.7. Visão geral do algoritmo de Aries O ARIES é um algoritmo de recuperação que é projetado para trabalhar com uma abordagem de “roubar” e “não forçar”. Está baseado em três conceitos: 1. Registro adiantado em log, 2. Repetição de histórico durante o refazer e 3. Mudanças do log durante o desfazer A repetição de histórico significa que o ARIES relê todas as ações tomadas pelo sistema de banco de dados antes da queda para reconstruir seu estado quando a queda ocorreu. Transações que não foram efetivadas em tempo de queda, ou seja, as transações ativas são desfeitas. O uso e atualização do log durante o desfazer evitará que o ARIES torne a desfazer operações já desfeitas, caso ocorra uma falha durante a recuperação, com consequente reinício do processo de recuperação. Os buffers podem ser perdidos durante uma queda, uma vez que estão na memória principal. Tabelas adicionais armazenadas no log durante o checkpoint (Tabela de Página Lixo, Tabela de transações) permitem ao ARIES identificar essas informações. Quando o gerenciador de recuperação é invocado após uma falha, o reinício se procede em três fases. Fase de Análise (1) que identifica páginas sujas no buffer e transações ativas no momento da falha. Fase de Refazer (2) que repete todas as ações, começando do ponto apropriado no log e restaura o estado da base de dados idêntico ao momento da falha. Fase de Desfazer (3) que desfaz as ações das transações que não realizaram o commit, de forma que a base de dados reflita apenas as ações das transações que realizaram o commit. Algumas informações são necessárias para o processo. Precisamos do Log, da Tabela de Transações e da Tabela de Pagina Lixo. Essas duas tabelas são mantidas pelo gerenciador de transações e gravadas no log durante o checkpoint. Cada registro tem um número de sequência de log (LSN).Sobre o algoritmo ele usa fuzzy checkpoint. Sobre o algoritmo de ARIES não precisamos descer mais em detalhes, pois não é cobrado em provas de concurso. Aqui terminamos nossa aula de transações, controle de concorrência e recuperação após falha. Seguimos com nossa tradicional lista de questões comentadas. Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 29 de 41 Questões Comentadas Apresentamos abaixo um conjunto de questões sobre o assunto que aprendemos nesta aula. Esperamos que elas ajudem na fixação da matéria. Qualquer dúvida, estamos às ordens! 4. ANO: 2015 BANCA: FGV ÓRGÃO: TJ-SC PROVA: ANALISTA JUDICIÁRIO - ANALISTA DE SISTEMAS ACID é uma conhecida sigla do jargão da área de banco de dados, e refere-se às propriedades que as transações executadas por um sistema gerenciador devem observar. A letra ”I” nessa sigla está associada ao algoritmo: A de “undo/redo” sobre arquivos de log; B shadow paging; C write-ahead logging; D two-phase lock; E two-phase commitment. Comentário: Essa questão é interessante, pois nos remete a vários conceitos associados a transações em banco de dados. O primeiro deles é o undo/redo utilizado para recuperação do banco de dados. A depender o protocolo de recuperação escolhemos como aplicar as informações presentes no log sobre a base de dados. Executando o UNDO sempre que alguma transação não efetivada estiver com seus dados já gravados em disco. E utilizamos a operação de REDO sempre que uma instrução já efetivada não estiver devidamente gravada em disco. A próxima alternativa se refere às páginas sombra. Elas são utilizadas como uma técnica para garantir a consistência dos dados. Basicamente as modificações são feitas na cópia dos dados e em seguida atualizamos os ponteiros utilizando os dados da cópia como principais. O write-ahead logging, ou escrita antecipada do log, refere-se a uma técnica ou protocolo para gravação dos registros do log no disco. O two-phase lock, ou bloqueio em duas fases, é um protocolo de controle de concorrência que bloqueia os dados que serão utilizados pela transação. Garantido o isolamento de outras transações simultâneas. Gabarito: D 5. ANO: 2015 BANCA: MP-RS ÓRGÃO: MP-RS PROVA: TÉCNICO EM INFORMÁTICA - SISTEMAS Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 30 de 41 Uma falha não pode deixar o banco de dados em um estado no qual uma transação tenha sido parcialmente executada. Qual é a propriedade que garante que todos os efeitos de uma transação se refletirão no banco de dados? A Consistência. B Isolamento. C Atomicidade. D Durabilidade. E Redundância. Comentário: A propriedade que garante que todas as operações que fazem parte de uma transação sejam executadas ou nenhuma delas será concluída é conhecida como atomicidade. Tratamos, portanto, uma transação como algo indivisível. Gabarito: C 6. ANO: 2015 BANCA: UERJ ÓRGÃO: UERJ PROVA: ANALISTA DE SISTEMAS - DESENVOLVIMENTO Das propriedades ACID, a que está ligada à serialização de transações é: A atomicidade B consistência C isolamento D durabilidade Comentário: O isolamento trata do fato de uma transação não ter conhecimento das demais. Outro contexto importante é a ideia que os efeitos gerados sobre o banco quando temos duas transações sendo executadas em paralelo deve ser o mesmo das mesmas transações executadas de forma sequencial. Esse contexto nos leva a serialização de transações. Gabarito: C 7. ANO: 2015 BANCA: UERJ ÓRGÃO: UERJ PROVA: ANALISTA DE SISTEMAS - DESENVOLVIMENTO Dos níveis de isolamento definidos pela SQL, aquele em que não pode ocorrer o fenômeno “leitura fantasma” é: A READ UNCOMMITTED B REPEATABLE READ C READ COMMITTED D SERIALIZABLE Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 31 de 41 Comentário: Os quatro níveis de isolamento propostos pelo SQL podem permitir que alguns problemas aconteçam durante a execução de transações paralelas. O nível de isolamento que garante que não teremos problemas com a leitura fantasma é o SERIALIZABLE. Gabarito: D 8. ANO: 2015 BANCA: CESPE ÓRGÃO: MPOG PROVA: ANALISTA - ANALISTA EM TECNOLOGIA DA INFORMAÇÃO Acerca de sistema de gerenciamento de banco de dados (SGBD), julgue os seguintes itens. [1] Os dados armazenados em um SGBD são acessados por um único usuário de cada vez, sendo impedido o acesso concorrente aos dados. Comentário: O acesso concorrente para leitura é perfeitamente permitido. Os problemas são graves quando temos das transações que querem escrever no mesmo registro ao mesmo tempo. Isso deve ser evitado por meio de protocolos de controle de concorrência. Gabarito: E 9. ANO: 2014 BANCA: VUNESP ÓRGÃO: DESENVOLVESP PROVA: ANALISTA - ANALISTA DE SISTEMAS Assinale a alternativa correta com relação aos bloqueios, utilizados para implementar a concorrência em bancos de dados relacionais. A Bloqueios dos tipos compartilhado e exclusivo aplicam-se apenas a bancos de dados distribuídos. B Bloqueios dos tipos compartilhado e exclusivo aplicam-se apenas a tabelas com mais de 100 registros. C Uma transação que tenha obtido um bloqueio do tipo compartilhado sobre um item pode ler e escrever sobre tal item. D Uma transação que tenha obtido um bloqueio do tipo compartilhado sobre um item pode ler, mas não escrever sobre tal item. E Uma transação que tenha obtido um bloqueio do tipo exclusivo sobre um item pode ler, mas não escrever sobre tal item. Comentário: Sabemos que uma transação ao obter um bloqueio compartilhado ela só pode executar operações de leitura sobre aquele item de dados. O bloqueio compartilhado é sinônimo de operações de leitura. A outra opção de bloqueio seria o bloqueio exclusivo, nele podemos ter operações de escrita, mas perceba que nenhuma outra transação pode ter esse bloqueio sobre o mesmo item de dados simultaneamente. Gabarito: D Transações e controle de concorrência Prof. Thiago Rodrigues Cavalcanti ʹ Aula 03 Prof. Thiago Rodrigues Cavalcanti www.estrategiaconcursos.com.br 32 de 41 10. ANO: 2014 BANCA: VUNESP ÓRGÃO: TJ-PA PROVA: ANALISTA JUDICIÁRIO - ANÁLISE DE SISTEMA - SUPORTE Uma das formas de se implementar um controle para o acesso concorrente de usuários a um banco de dados é por meio da utilização de bloqueios, sobre os quais é correto afirmar que A bloqueios do tipo compartilhado não permitem o acesso simultâneo de mais do que um usuário. B bloqueios do tipo exclusivo não permitem o acesso simultâneo de mais do que um usuário. C em um bloqueio do tipo exclusivo é possível apenas ler o conteúdo do item de dados bloqueado. D um bloqueio do tipo exclusivo só é removido quando o banco de dados é desativado. E em um bloqueio do tipo compartilhado é possível ler e escrever sobre o conteúdo do item de dados bloqueado. Comentário: Essa questão é complementar a anterior. Agora estamos mostrando a definição ou a característica determinante da utilização dos bloqueios exclusivos. Gabarito: B 11. ANO: 2014 BANCA: CESPE ÓRGÃO: TC-DF PROVA: ANALISTA DE ADMINISTRAÇÃO PÚBLICA - SISTEMAS DE TECNOLOGIA DA INFORMAÇÃO Julgue os itens subsequentes, no que se refere a bancos de dados distribuídos e data warehouse. [1] Em sistemas de bancos de dados distribuídos, o controle de concorrência baseado em bloqueio de duas fases determina que, após a liberação de um de seus bloqueios, as transações não solicitem um novo bloqueio.
Compartilhar