Blog do Léo

Conteúdo voltado para banco de dados Oracle e SQL Server

Numa bela tarde de terça-feira (12/06/2018) me deparo com esse erro bacana ao tentar colocar uma PK de uma tabela online .. Os scripts que eu tentei executar sempre tomavam esse erro. A causa desse problema foi um rebuild de índice PK que parei no meio do processo com um alter system kill session e o mesmo ficou incompleto.

A solução estava num doc id do MOS 375856.1 nomeado de: Session Was Killed During The Rebuild Of Index ORA-08104 : )

Basicamente é rodar esse script na instância que está ocorrendo o erro e em seguida rodar o rebuild dos índices:

DECLARE
isClean BOOLEAN;
BEGIN
isClean := FALSE;
WHILE isClean=FALSE
LOOP
isClean := dbms_repair.online_index_clean(
dbms_repair.all_index_id, dbms_repair.lock_wait);
dbms_lock.sleep(10);
END LOOP;
END;


Até a próxima.

 

 

Tarefa comum e corriqueira de um DBA é criar novos hosts para testes, ambientes de produção, desenvolvimento e homologação. Há poucos dias atrás precisei criar um servidor para instalação do Oracle Cloud Control 13c e fui surpreendido com a facilidade em alterar o nome de um servidor.

Nas versões anteriores era preciso alterar o arquivo /etc/hosts e reiniciar o S.O., porém na versão 7 basta digitar os comandos abaixo:

1 º – Checar o nome do servidor:

[root@localhost ~]# hostnamectl status
Static hostname: localhost.localdomain
Icon name: computer-vm
Chassis: vm
Machine ID: 5e2ea38c44ec49a497be3d6919cd9e96
Boot ID: 1996d9bfa13b48978e6cf411711a5e21
Virtualization: xen
Operating System: Oracle Linux Server 7.4
CPE OS Name: cpe:/o:oracle:linux:7:4:server
Kernel: Linux 4.1.12-94.3.9.el7uek.x86_64
Architecture: x86-64

2 º – Alterar o nome do servidor:

[root@localhost ~]# hostnamectl set-hostname SERVER002

3º – Checar o nome do servidor

[root@localhost ~]# hostnamectl status
Static hostname: SERVER002.localdomain
Icon name: computer-vm
Chassis: vm
Virtualization: xen
Operating System: Oracle Linux Server 7.4
CPE OS Name: cpe:/o:oracle:linux:7:4:server
Kernel: Linux 4.1.12-94.3.9.el7uek.x86_64
Architecture: x86-64

Foi só executar o passo 2 que o servidor já teve seu nome alterado, nem foi preciso reiniciar o S.O. para atingir tal objetivo.

Tenho um servidor de banco de dados que possui diversas instâncias do Oracle rodando sob um único ASM e recentemente precisei fazer um levantamento de quais eram os maiores bancos dentro dos DISKGROUPs de FRA e DATA. Inicialmente fiz um select em cada instância e joguei para uma planilha, mas .. são 23 instâncias, então certamente esse não era o melhor caminho : )

O script abaixo deve ser rodado na instância do ASM, basta trocar o que está na linha: WHERE gname=’FRA_ASM_DG’ pelo nome do seu diskgroup.

col gname form a10
col dbname form a10
col file_type form a14

SELECT
    gname,
    dbname,
    file_type,
    round(SUM(space)/1024/1024) mb,
    round(SUM(space)/1024/1024/1024) gb,
    COUNT(*) "#FILES"
FROM
    (
        SELECT
            gname,
            regexp_substr(full_alias_path, '[[:alnum:]_]*',1,4) dbname,
            file_type,
            space,
            aname,
            system_created,
            alias_directory
        FROM
            (
                SELECT
                    concat('+'||gname, sys_connect_by_path(aname, '/')) full_alias_path,
                    system_created,
                    alias_directory,
                    file_type,
                    space,
                    level,
                    gname,
                    aname
                FROM
                    (
                        SELECT
                            b.name            gname,
                            a.parent_index    pindex,
                            a.name            aname,
                            a.reference_index rindex ,
                            a.system_created,
                            a.alias_directory,
                            c.type file_type,
                            c.space
                        FROM
                            v$asm_alias a,
                            v$asm_diskgroup b,
                            v$asm_file c
                        WHERE
                            a.group_number = b.group_number
                        AND a.group_number = c.group_number(+)
                        AND a.file_number = c.file_number(+)
                        AND a.file_incarnation = c.incarnation(+) ) START WITH (mod(pindex, power(2, 24))) = 0
                AND rindex IN
                    (
                        SELECT
                            a.reference_index
                        FROM
                            v$asm_alias a,
                            v$asm_diskgroup b
                        WHERE
                            a.group_number = b.group_number
                        AND (
                                mod(a.parent_index, power(2, 24))) = 0
                    ) CONNECT BY prior rindex = pindex )
        WHERE
            NOT file_type IS NULL
            and system_created = 'Y' )
WHERE gname='FRA_ASM_DG'
GROUP BY
    gname,
    dbname,
    file_type
ORDER BY
4 desc;

O resultado deve ser algo parecido com o output abaixo:


GNAME      DBNAME     FILE_TYPE              MB         GB     #FILES
---------- ---------- -------------- ---------- ---------- ----------
FRA_ASM_DG LP142      ARCHIVELOG         241766        236         22
FRA_ASM_DG LP852      ARCHIVELOG         162494        159         66
FRA_ASM_DG LP90       ARCHIVELOG         147272        144          8
FRA_ASM_DG LP74       ONLINELOG           92376         90          8
FRA_ASM_DG LP65       ONLINELOG           81928         80          4
FRA_ASM_DG LP66       ONLINELOG           61448         60          4
FRA_ASM_DG LP98       ARCHIVELOG          58618         57        163
FRA_ASM_DG LP41       ARCHIVELOG          56984         56          8
FRA_ASM_DG LP42       ARCHIVELOG          33384         33         20
FRA_ASM_DG LP44       ONLINELOG           32776         32          4
FRA_ASM_DG LP22       ARCHIVELOG          31224         30       2807


Feito isso você terá noção de quais são os maiores bancos dentro do seu ASM, nesse caso, o LP142 está utilizando 236GB dentro do diskgroup de FRA e o LP22 está usando apenas 30GB.

Até a próxima.

Um erro muito comum em empresas que possuem equipes distintas de DBA, AD e Desenvolvimento é criar as estruturas de banco sem o devido cuidado em indexar as FK’s. Sistemas e melhorias são feitos diariamente e isso pode incluir novos dados, colunas, constraints e demais objetos no banco dedados.

Um script que costumo rodar semanalmente é o que verifica se as FK’s estão indexadas, pois dependendo do uso da tabela, podemso ter um aumento do wait TM CONTENTION. NO meu caso, todos os schemas começam com DB, portanto eu ajustei em 2 lugares para trazer somente os dados referente á esses schemas:

  AND a.owner LIKE 'DB%' 
  WHERE  c.index_owner LIKE 'DB%' 

Basta adaptar o script ás suas necessidades, ou se preferir não filtrar nada, retira esse trecho do código e execute-o.

O script é simples mas de grande utilidade, conforme pode ser visualizado abaixo:

SELECT CASE 
         WHEN b.table_name IS NULL THEN 'unindexed' 
         ELSE 'indexed' 
       END               AS status, 
       a.owner, 
       a.table_name      AS table_name, 
       a.constraint_name AS fk_name, 
       a.fk_columns      AS fk_columns, 
       b.index_name      AS index_name, 
       b.index_columns   AS index_columns 
FROM   (SELECT a.owner, 
               a.table_name, 
               a.constraint_name, 
               Listagg(a.column_name, ',') 
                 within GROUP (ORDER BY a.position) fk_columns 
        FROM   dba_cons_columns a, 
               dba_constraints b 
        WHERE  a.constraint_name = b.constraint_name 
               AND b.constraint_type = 'R' 
               AND a.owner LIKE 'DB%' 
               AND a.owner = b.owner 
        GROUP  BY a.owner, 
                  a.table_name, 
                  a.constraint_name) a, 
       (SELECT table_name, 
               index_name, 
               Listagg(c.column_name, ',') 
                 within GROUP (ORDER BY c.column_position) index_columns 
        FROM   dba_ind_columns c 
        WHERE  c.index_owner LIKE 'DB%' 
        GROUP  BY table_name, 
                  index_name) b 
WHERE  a.table_name = b.table_name(+) 
       AND b.index_columns(+) LIKE a.fk_columns 
                                   || '%' 
ORDER  BY 1 DESC, 
          2; 

Uma simples maneira de limpar o arquivo de log do listener (Listener.log) é escrevendo nele mesmo um valor simbólico.

Abaixo vamos aprender como limpar de maneira rapida o log do listener. É recomendável que você compacte e guarde em algum lugar para consultas futuras.

Ao listar
-rw-r—–   1 oracle dba   15G Jul 21 19:05 listener.log

Execute o comando:
# cat /dev/null > listener.log

E verifique que o arquivo foi sobrescrito:
-rw-r—–   1 oracle dba  1,1K Jul 21 19:09 listener.log