domingo, 28 de dezembro de 2008

Controle de concorrencia

Transação

Definição: Uma transacção é uma sequência de operações que faz transitar um sistema de informação de um estado coerente inicial (A) para um estado coerente final (B).

Este conceito é realizado com base nas seguintes primitivas:

  • Inicio: Que inicia a transacção e antecede a sequência de operações; fica assim definido o estado inicial A.
  • Fim: Que marca a terminação bem sucedida da transacção, marcando assim o estado final B do sistema; o sistema deve comprometer-se em manter este novo estado, que poderá ser acedido por futuras transacções; (commit).
  • Abortar: Que marca a anulação da transacção, em reacção a um dos incidentes imprevistos, obrigando o sistema a manter o estado inicial inalterado (A), como se a transacção nunca se tivesse iniciado. (rollback [implicito ou explicito]).

Transações devem obdecer as regras impostas pelo conceito ACID, o banco de dados deve garantir que os dados sejam consistentes e permanentemente gravados no DB.

Regras ACID

A sigla ACID se refere a propriedade de banco de dados relacionais, onde tais imposições são postas em cima de cada transação, todas as base relacionais Oracle funcionam em função dessas caracteristicas. Em banco de dados, um operação lógica é chamada de transação.

  • Atomicidade – Trabalho como indivisivel, atomico, ou tudo é realizado ou nada é executado, como analogia temos uma mulher que esta grávida ou não esta. Nada será debitado da sua conta se nada for créditado em outra. (comitt e rollback).
  • Consistencia – Garante que mesmo antes ou depois da transação ter finalizado os dados continuam consistentes. (constraints).
  • Isolamento – Trabalho em nivel individual, os mesmos dados não podem ser alterados simultaneamente, entretando, a qualquer consulta pode ser executada a qualquer momento. (locks).
  • Durabilidade – Deve se garantir que em caso de sucesso os dados referentes a transação sejam permanentemente inseridos. (redo log).

Mecanismo de controle de concorrencia

Devido ao fato das transações serem executadas concorrentemente uma as outras, é necessário um metodo de equacionar as transações, tais transações necessecitam um ordenamento coerente, há a necessidade de impor restrições nas ações que cada transacção realiza, assim surgi um escalonador, que resolve o problema quando duas transações tentam modificar simultaneamente um objecto em comum.

Em operações de leitura ou escrita, o escalonador é acionado, e ele é quem decidi se a operação é aceita, rejeita ou deve ser adiada.

Há duas grandes classes de escalonadores:

  • Pessimistas: Metodo baseado em locks ou estampilhas, assume que conflitos entre as transações são frequentes, e tendem a resolve-los rejeitando ou adiando operações.
  • Optimistas: Assume que os conflitos são poucos frequentes, em caso de conflito tende a anular e iniciar a operação desde o inicio. Este metodo permite a operação avançar sem lidar com conflitos, utiliza-se de espaço privados, e somente valida ao final, commit, não necessita lidar com deadlocks, há maior paralelismo, todavia pode ser custoso em caso excessivo de falhas, pois ao final em caso de conflito toda operação deve ser refeita.

Locks

Nos metodos baseados em locks, as relações de dependencias de transações seguem uma ordem cronologica, uma transação que cause um conflito é obrigada a aguardar até que o objeto seja liberado, este metodo tem que lidar com conflitos irreversiveis, deadlocks.

Existem diversos metodo de mecanismos de controle de concorrencia para escalonadores pessimistas, entre eles temos:

Travamento Bifasico ou Two-phase locking

Metodo baseado em locks, cada transação antes de ler um objeto precisa de um bloqueio S (compartilhado ou shared), e antes de escrever em um objeto precisa de um bloqueio X (exclusivo), depois de finalizado a transação não pode mais obter nenhum lock, enquanto houver lock X não pode haver nenhum lock S ou X.
Este mecanismo é utilizado no sql até a versão 2005.

Multiversion concurrency control (MCC), controle de concorrencia multi-versão.

Metodo prove a cada usuário conectado ao banco de dados uma fotografia, snapshot, de parte do banco de dados na qual ele esta trabalhando. Qualquer alteração feita por pelo mesmo não será vista pelo demais usuário do banco até que a mesma seja gravada permanentemente, commit.
MCC utiliza uma variavel de tempo ou um indentificador de transação para garantir a ordenação coerrente das multiplas transações simultaneas, tal mecanismo evita lock em operaçõs de select. Tal recurso se encontra disponivel no Oracle desde a versão 7, e obtido atraves de imagens armazenadas na tablespace de undo, a qual é uma imagem anterior da linha antes de ser alterada por uma operação.
Tal mecanismo é apenas encontrado no SQL Server a partir da versão 2005.

Durabilidade

Operações permanentemente gravadas (commits) ou não (em execução), são frequentemente gravadas em log, no Oracle chamamos de On-line redo logs, tais logs são arquivos binários gravados fisicamente em disco, informações são armazenadas nos arquivos de logs com mais frequencia que nos arquivos de dados dada a sua importancia para recuperação do ambiente, e pelo fato da escrita ser sequencial, ao contrário do arquivo de dados, que é indexada. Devido a sua importancia na recuperação de informações o arquivos de dados de ser multiplexado, isso significa que deve haver mais de um cópia do arquivo recente.
Dentro do arquivo de log há um encadeamento indetificado pelo numero de cada transação, assim é sabido por onde iniciar um recover.

Recovery

É feito em três fases, analise, redo e undo.
É analisado o log e o arquivo de controle, onde o numero de transação deve estar sincronizado em cada arquivo, caso não esteja há a necessidade de refazer as operações perdidas, redo, onde o arquivo de log é utilizado para refazer tais transações, após a operação de redo há a necessidade de undo, pois os arquivos de logs contém informações não commitadas, os valores consistentes para tais informações são encontrados na tablespace de undo do oracle, aplicando undo o banco de dados se torna consistente e integro.

Referencia:
http://en.wikipedia.org/wiki/ACID
http://en.wikipedia.org/wiki/Concurrency_control
http://en.wikipedia.org/wiki/Multiversion_concurrency_control
http://www.ime.usp.br/~reverbel/BD-00/Slides/s08.pdf

segunda-feira, 15 de dezembro de 2008

Oracle Incomplete Recover

Irei demonstrar como realizar um recovery incompleto no oracle, algumas vezes é a única maneira de recuperarmos dados, por exemplo, quando houve operações erroneas causadas por um usuário, ou durante um recover, e um dos archives não estava presente.

Vamos realizar o restore do banco utilizando o backup mais recente, porém em uma data anterior a qual desejamos recuperar o banco, iremos realizar o recovery até um determinado momento antes das alteração.

No nosso caso sabemos a data exata a qual realizaremos o restore, porém algumas vezes não há informações precisas e há a necessidade de ser investigado o momento certo das alterações.

Convenções:
Negrito: Passos a serem executados.
Fonte Azul: Comentários.

Ambiente

Antes de iniciarmos é preciso validar o ambiente, precisamos ter o banco em modo de archivelog, algumas variaveis de ambientes devem estar configuradas, e é claro devemos ter um backup válido via rman.

A parte do banco em archive e o backup do rman não será demonstrada, irei apenas demonstrar o restore e o recovery pelo rman.

Falhas

Salvar a data antes das alterações, e a seguir iremos remover o schema HR, assim, voltaremos o banco para antes do usuário HR ser removido do sistema e antes de ser perdido todas as informações do mesmo.


SQL> SELECT TO_CHAR(SYSDATE,'DD/MM/YYYY HH24:MI:SS') FROM DUAL;

TO_CHAR(SYSDATE,'DD
-------------------
15/12/2008 14:59:41

SQL> SELECT SUM(BYTES)/1024/1024 FROM DBA_SEGMENTS WHERE OWNER='HR';

SUM(BYTES)/1024/1024
--------------------
1.5625

SQL> DROP USER HR CASCADE;

User dropped.

SQL> SELECT SUM(BYTES)/1024/1024 FROM DBA_SEGMENTS WHERE OWNER='HR';

SUM(BYTES)/1024/1024
--------------------


SQL>

Restore

Vamos pegar as informações necessárias para setar as váriaveis de ambiente NLS_LANG e NLS_DATE_FORMAT, utilizadas para realizar o backup do rman.

Váriaveis necessárias:
NLS_LANG = language_territory.charset
NLS_DATE_FORMAT = Qualquer formato válido.


Variaveis de Ambiente

SQL> set line 120
SQL> set pagesize 30
SQL> col description format a40
SQL> col property_value format a40
SQL> select * from database_properties where property_name like '%NLS%';


PROPERTY_NAME PROPERTY_VALUE DESCRIPTION
------------------------------ ---------------------------------------- ----------------------------------------
NLS_LANGUAGE AMERICAN Language
NLS_TERRITORY AMERICA Territory
NLS_CURRENCY $ Local currency
NLS_ISO_CURRENCY AMERICA ISO currency
NLS_NUMERIC_CHARACTERS ., Numeric characters
NLS_CHARACTERSET AL32UTF8 Character set
NLS_CALENDAR GREGORIAN Calendar system
NLS_DATE_FORMAT DD-MON-RR Date format
NLS_DATE_LANGUAGE AMERICAN Date language
NLS_SORT BINARY Linguistic definition
NLS_TIME_FORMAT HH.MI.SSXFF AM Time format
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM Time stamp format
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR Time with timezone format
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR Timestamp with timezone format
NLS_DUAL_CURRENCY $ Dual currency symbol
NLS_COMP BINARY NLS comparison
NLS_LENGTH_SEMANTICS BYTE NLS length semantics
NLS_NCHAR_CONV_EXCP FALSE NLS conversion exception
NLS_NCHAR_CHARACTERSET AL16UTF16 NCHAR Character set
NLS_RDBMS_VERSION 10.2.0.1.0 RDBMS version for NLS parameters

20 rows selected.

SQL> exit
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

Restore

1) Declaramos as variaveis de ambiente no SO
2) Chama-se o rman
3) Procedimento de recuperação

1) Variaveis de ambiente

[oracle@hodb01 logs]$export NLS_LANG=AMERICAN_AMERICA.AL32UTF8

[oracle@hodb01 logs]$ export NLS_DATE_FORMAT="DD/MM/YYYY hh24:mi:ss"

2) Rman

[oracle@hodb01 logs]$ rman


Recovery Manager: Release 10.2.0.1.0 - Production on Mon Dec 15 15:13:12 2008

Copyright (c) 1982, 2005, Oracle. All rights reserved.

RMAN> connect target /

connected to target database: ORCL (DBID=1201080710)

3) Procedimento de restore

Paramos o banco de dados, iniciamos ele em modo munted, determinamos a data a qual o banco irá voltar, realizamos o restore e o recover, e abrimos ele com resetlogs, o que faz com que o banco volte em uma nova incarnação.

RMAN> run {
2> shutdown immediate;
3> startup mount;
4> set until time '15/12/2008 14:59:41';
5> restore database;
6> recover database;
7> }

using target database control file instead of recovery catalog
database closed
database dismounted
Oracle instance shut down

connected to target database (not started)
Oracle instance started
database mounted

Total System Global Area 205520896 bytes

Fixed Size 1218532 bytes
Variable Size 79693852 bytes
Database Buffers 121634816 bytes
Redo Buffers 2973696 bytes

executing command: SET until clause

Starting restore at 15/12/2008 15:14:33
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=157 devtype=DISK
media recovery complete, elapsed time: 00:00:04
Finished recover at 15/12/2008 15:16:57

RMAN> alter database open restlogs;
RMAN> alter database open resetlogs;

database opened

RMAN> exit


Recovery Manager complete.
[oracle@hodb01 logs]$ sqlplus / as sysdba


SQL*Plus: Release 10.2.0.1.0 - Production on Mon Dec 15 15:19:21 2008

Copyright (c) 1982, 2005, Oracle. All rights reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options


SQL> SELECT TO_CHAR(SYSDATE,'DD/MM/YYYY HH24:MI:SS') FROM DUAL;

TO_CHAR(SYSDATE,'DD
-------------------
15/12/2008 15:19:55

SQL> SELECT SUM(BYTES)/1024/1024 FROM DBA_SEGMENTS WHERE OWNER='HR';

SUM(BYTES)/1024/1024
--------------------
1.5625

SQL>


Bom esse artigo somente foi para demonstrar os procedimentos para um recover inclompleto, esse tipo de falha talves poderia ser recuperada de outra maneira um pouco mais eficente.
Como visto é simples realizar o restore incompleto pelo rman.

terça-feira, 9 de dezembro de 2008

Estratégia de backup

Vou apenas descrever uma estratégia de backup a qual é realizado um misto de backup diferencial e cumulativos, com o banco é claro em archivelog, com o propósito de impactar o quanto menos a base de dados em produção e proporcionar um tempo razoável de restore.

Convenções

Full backup - Todos os blocos usados de todos os datafiles. OBS - Não pode ser usado como base para backups incrementais.
Level 0 incremetal backup - Equivale ao full backup, porém é marcado como level 0. OBS - Pode ser usado como base de backup incrementais.
Cumulative level 1 - Todos os blocos modificados após o backup level 0.
Diferential level 1 - Todos os blocos modificados após o utimo backup incremental.

Retenção
A politica de retenção pode ser configurada com o comando configure retention policy no rman, o que irá determinar no report e no delete a nossa politica de backup. A retention policy somente é aplicada para backups full, level 0 datafile e control file, em casos de backup incrementais level 1 e archives não será aplicados politicas de rentenção já que os mesmos se tornão inválidos após a remoção de backup level 0.
Se utilizado a flash recovery area durante os backups, o comando delete não apenas remove a entrada no control file ou catalog como também remove o arquivo do SO.
Na nossa estratégia de backup iremos utilizar um misto de backup incrementais, utilizaremos backups cumulativos duas vezes durante a semana, e quatro backups incrementais e um backup incremental level 0.

level 0 level 0
|<------------------------------------------------------ span="">
| | | | | |<---- span="">
|<--------------------------------- span="">
| | | |<----- span="">
|<------------------- span="">
| |<----- span="">
|<---- span="">
LVL 0 1 1 1C 1 1C 1 0
DAY Sun Mon Tue Wed Thu Fri Sat Sun

Comparações entre o backup cumulativo e o diferencial.

  • O backup diferencial é o mais rápido backup, ocupa menos espaço, porém em operações de recover é mais lento em relação o cumulativo, pois há a necessidade de se aplicar o outros backups incrementais.
  • O backup cumulativo é o mais lento e ocupa maior espaço, porém em operações de recover é favorecido em relação ao tempo.

Durante o processo de backup, o rman precisa fazer um full scan em todos os datafiles. Para reduzir o tempo de cpu e o tempo dos backups incrementais pode ser aplicado um feature do Oracle, o Block Change Tracking, o qual consiste em armazenar em uma arquivo todos os blocos modificados, a fim não haver mais a necessidade da leitura completa dos datafiles, podemos imaginar esse arquivo como um indice, onde o qual feito a leitura é indicado somente os blocos modificados e necessário para o backup, reduzindo assim o tampo de backup e ciclos de cpus.

Habilitando o block change tracking:

Temos o seguinte procidento:

SQL> ALTER DATABASE ENABLE
2> BLOCK CHANGE TRACKING
3> USING FILE '/MYDIR/MYFILE.DBF'
4> REUSE;

Caso esteja usando Oracle Manage Files, o parametro db_create_file_dest esteja ativo não há necessidade de indicar o arquivo.

O tamanho do arquivos do block changing tracking depende não da utilização do banco, mas sim, da retenção de seus backups e o tamanho da base de dados.

Backup sintaxe

O procedimento de backup no rman é muito simples, a seguir temos as tres sintaxes necessárias para nossa estratégia de backup:

RMAN> BACKUP AS COMPRESSED BACKUPSET TAG 'WEEKLY' INCREMENTAL LEVEL 0 DATABASE PLUS ARCHIVELOG DELETE INPUT;
RMAN> BACKUP AS COMPRESSED BACKUPSET TAG 'DAILY DIF' INCREMENTAL LEVEL 1 DATABASE PLUS ARCHIVELOG DELETE INPUT;
RMAN> BACKUP AS COMPRESSED BACKUPSET TAG 'DAILY CUM' INRECMENTAL LEVEL 1 CUMULATIVE DATABASE PLUS ARCHIVELOG DELETE INPUT;

O conjunto de procedimentos anteriores são uma amostra de como podemos realizar nossa estratégia de backup, vamos estudar parte a parte.

O parametro AS COMPRESSED é utilizado para comprimir o backup, reduzindo o tráfego na rede e reduzindo o espaço do arquivo de backup, porém torna operações de backup e recover mais lentas.

TAG é utilizada para colocar um apelido no backup, o que pode tornar mais fácil para administrar os backups.

O comando PLUS ARCHIVELOG realiza o backup dos archives logs, o DELETE INPUT remove os archives recém backupeados, assim reduzindo a ocupação em disco.

INCREMENTAL LEVEL [0|1] é o tipo de backup.

BACKUP DATABASE, chama a operação de backup.

Para tornar nossa estratégia de backup completa, é essencial realizar o backup do controlfile. Podemos então configurar o rman para faze-lo, dentro do rman, podemos usar o show all, o qual irá nos mostrar os nossos parametros de backup, o parametro CONTROLFILE AUTOBACKUP é o qual determinará se é realizado ou não o backup do controlfile, se habilitado, a cada backup do banco é feito então o backup dos controlfiles, assim como o backup também do seu arquivo de parametro. Para habilita-lo é feito o comando:

CONFIGURE CONTROLFILE AUTOBACKUP ON;

Para voltar ao padrão, CONFIGURE CONTROLFILE AUTOBACKUP CLEAR;

Simulando falhas:

Imaginemos a seguinte situação, nossa estratégia de backup está em prática há alguns meses, perdemos um datafile de uma de nossas tablespaces na quinta-feira, e estamos na sexta, precisamos voltar o banco em seu estado consistente. Para isso iremos realiza o restore do backup incremental level 0 do domingo, o rescover do backup incremental cumulativo level 1 da quarta, recover do backup incremental diferencial level 1 da quinta, aplicar os archives necessários e se necessário os redo logs.

Pois ai está uma estrágia de backup a qual venho estudando e pode ser satisfatória, dependendo do ambiente.

c-ya.

quarta-feira, 3 de dezembro de 2008

Character set

No momento da criação de um banco de dados oracle, definimos qual charset será utilizado no db, isto quer dizer, qual a quantidade de bytes necessários para um caracter, deve ser uma decisão muito bem estudada pois depois que definida não será possivel altera-la.

Assim, para o idioma ingles usamos bytes com 7 bits, sendo que na lingua inglesa não temos acentuação,apenas 7 bits seriam necessário para armazenar todos os caracteres possiveis, já para o portugues, onde o acento é rigidamente necessário, temos bytes formados por 8 bits, já para liguas como o chines e o japones onde temos de 2 a 4 mil caracteres distintos, devemos ter caracteres formados por diversos bytes, entre 2 a 4 dependendo da configuração escolhida.

Unicode e o single byte.

Unicode são caracteres codificados de uma maneira singular, indepente do idioma, codificado em um unico character set.
Usando unicode como caracter set, podemos então com apenas um caracter set armazenar diversos idiomas, como o Chines, japones, portugues, usando apenas um character set. É um grande facilitador, mas não havendo a necessidade, pode ser usado o single byte, é recomendável sempre optar pelo menor consumo.
Temos diversos tipos de charset para unicode, são eles, UTF-16, UTF-8 e UCS-2.
Uma das maneiras de se verificar o character é pela seguinte consulta:
select value from nls_database_parameters
where parameter = 'NLS_CHARACTERSET';

Um dos problemas ao migrar uma base de dados é alterar o número de bytes para cada caracter, sendo que o tipo de dados varchar depende do character set do banco, uma base anterior com single byte, ao ser migrada para uma base em unicode deve se pensar na possibilidade de aumentar o valor das variaveis em varchar, pois um caracter antes armazenado em um byte teria que ser amazenado em dois ou até mais. Nunca havi pensado nisso, pois nunca passei por esse tipo de problema, mas essa semana ao conversar com um amigo meu, ele relatou esse fato, ao migrar uma base haviam dados faltando em algumas colunas do tipo varchar, pois o vchar armazena tamanho fixo para bytes, portanto ao aumentar o número de bytes por caracter teriamos também que levar em consideração o número máximo de bytes para tais colunas.

Outro fato interessante é o tipo de dados nchar, o qual não limita o armazenamento de dados a bytes, e sim a número de caracteres, por tanto, ele sempre tera 200 caracteres limites, pois ele é tipo de dados unicode, independente do charset do banco ele irá armazenar em unicode. Esse tipo de dados nchar depende também do parametro national character.

Fontes:
http://www.adp-gmbh.ch/ora/database.html
http://download.oracle.com/docs/cd/B28359_01/server.111/b28318/datatype.htm#i14946
http://www.dba-oracle.com/t_nls_lang.htm