Guia para Domínio Avançado dos Comandos do Linux - Parte 2


Por Arup Nanda

Publicado Fevereiro 2007

Na Parte 1 desta série, você aprendeu alguns comandos úteis não tão conhecidos e alguns comandos freqüentes, porém com parâmetros não tão conhecidos, para fazer seu trabalho com mais eficiência. Continuando a série, agora aprenderemos alguns comandos ligeiramente mais avançados do Linux que ajudarão usuários Oracle, sejam desenvolvedores ou DBAs.

alias e unalias

Vamos supor que você queira verificar o conjunto de variáveis do ambiente ORACLE_SID em seu shell. Digite: 

echo $ORACLE_HOME

Como DBA ou desenvolvedor, você usará com freqüência esse comando e rapidamente cansará de ficar digitando todos os 16 caracteres. Não tem um jeito mais simples?
Tem, sim: o comando alias. Com essa técnica, é possível criar um pequeno alias, como "os", para representar o comando inteiro:

alias os='echo $ORACLE_HOME'

Assim, sempre que você quiser verificar o ORACLE_SID, bastará digitar "os" (sem as aspas) e o Linux executará o comando com alias.
Entretanto, se você se desconectar e reconectar, o alias será perdido e será preciso digitar o comando alias novamente. Para eliminar essa etapa, basta colocar o comando no arquivo de perfis de seu shell. Para bash, o arquivo é .bash_profile (observe o ponto antes do nome do arquivo – ele é parte integrante) em seu diretório principal. Para shells bourne e korn, use.profile, e para c-shell, use .chsrc.
Você pode criar um alias em qualquer nome. Por exemplo, sempre crio um alias para o comando rm como rm -i, o que torna o comando rm interativo. 

alias rm=’rm -i’

Sempre que emito um comando rm, o Linux pede minha confirmação e, a menos que eu digite "y", ele não remove o arquivo – por isso, fico protegido contra a remoção acidental de um arquivo importante. Uso a mesma técnica para mv (para mover o arquivo para um novo nome), que evita a substituição acidental dos arquivos existentes, e cp (para copiar o arquivo).

A seguir está uma lista de alguns aliases bastante úteis que gosto de definir:

alias bdump='cd $ORACLE_BASE/admin/$ORACLE_SID/bdump'
alias l='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias mv='mv -i'
alias oh='cd $ORACLE_HOME'
alias os='echo $ORACLE_SID'
alias rm='rm -i'
alias tns='cd $ORACLE_HOME/network/admin'

 

Para ver quais aliases foram definidos no shell, consulte alias sem nenhum parâmetro.

Entretanto, há um pequeno problema. Defini um alias, o rm, que executa rm -i. Esse comando pedirá minha confirmação sempre que eu tentar excluir um arquivo. Mas e se eu quiser remover muitos arquivos e tiver certeza de que eles podem ser excluídos sem minha confirmação?

A solução é simples: para suprimir o alias e usar somente o comando, precisarei digitar duas aspas simples: 

$ ''rm *

Observe que há duas aspas simples (') antes do comando rm, e não duas aspas duplas. Esse procedimento suprimirá o alias rm. Outra abordagem é usar uma barra invertida (\):

$ \rm *

Para remover um alias definido anteriormente, basta usar o comando unalias:

$ unalias rm

ls

O singelo comando ls é usado com freqüência porém raramente em sua capacidade máxima. Sem oferecer nenhuma opção, ls meramente exibe todos os arquivos e diretórios em formato tabular. 

$ ls
admin            has                  mesg         precomp
apex             hs                   mgw          racg
assistants       install              network      rdbms
... output snipped ...


Para mostrá-los em uma lista, use a opção -1 (o número 1, e não a letra "l"). 

$ ls -1
admin
apex
assistants
... output snipped ...

 

Esta opção é útil em scripts de shell nos quais os nomes de arquivos precisam ser alimentados em outro programa ou comando para fins de manipulação.
Provavelmente você usou -l (a letra "l", e não o número "1") que exibe todos os atributos dos arquivos e diretórios. Vamos ver outra vez:
 

$ ls -l 
total 272
drwxr-xr-x    3 oracle   oinstall     4096 Sep  3 03:27 admin
drwxr-x---    7 oracle   oinstall     4096 Sep  3 02:32 apex
drwxr-x---    7 oracle   oinstall     4096 Sep  3 02:29 assistants

 

A primeira coluna mostra o tipo de arquivo e as permissões nele: "d" significa diretório, "-" significa um arquivo normal, "c" significa um dispositivo de caractere, "b" significa um dispositivo de bloco, "p" significa pipe nomeado e "l" (o L minúsculo, e não um I maiúsculo) significa um link simbólico.
Uma opção muito útil é --color, que mostra os arquivos em muitas cores diferentes com base no tipo de arquivo. A seguir está um screenshot de exemplo:
Observe que os arquivos file1 e file2 são arquivos comuns. link1 é um link simbólico, mostrado em vermelho; dir1 é um diretório, mostrado em amarelo; e pipe1 é um pipe nomeado, mostrado em cores diferentes para facilitar a identificação.
Em algumas distribuições de Linux, o comando ls vem pré-instalado com um alias (descrito na seção anterior) como ls --color; por isso é possível ver os arquivos em cores ao digitar "ls". Entretanto, talvez essa abordagem não seja desejável, principalmente se você tiver um resultado conforme acima. Você pode alterar as cores, mas um jeito mais rápido pode ser simplesmente desativar o alias:
 

$ alias ls="''ls"

Outra opção útil é -F, que acrescenta um símbolo depois de cada arquivo para mostrar o tipo do arquivo - a "/" depois de diretórios, "@" depois de links simbólicos e "|" depois de pipes nomeados. 

$ ls -F
dir1/  file1  file2  link1@  pipe1|

 

Se houver um subdiretório sob um diretório e você quiser listar somente esse diretório, ls -l também mostrará o conteúdo do subdiretório. Por exemplo, vamos supor que a estrutura de diretórios tenha estas características:

/dir1
+-->/subdir1
+--> subfile1
+--> subfile2

 

O diretório dir1 tem um subdiretório subdir1 e dois arquivos: subfile1 e subfile2. Se você apenas quiser ver os atributos do diretório dir1, emitirá: 

$ ls -l dir1
total 4
drwxr-xr-x    2 oracle   oinstall     4096 Oct 14 16:52 subdir1
-rw-r--r--    1 oracle   oinstall        0 Oct 14 16:48 subfile1
-rw-r--r--    1 oracle   oinstall        0 Oct 14 16:48 subfile2

 

Observe que o diretório dir1 não está listado nos resultados. Em vez disso, o conteúdo do diretório será exibido. Esse é um comportamento esperado ao processar diretórios. Para mostrar somente o diretório dir1, será necessário usar o comando -d.

 
Se você perceber o resultado de ls –l a seguir:

-rwxr-x--x    1 oracle   oinstall 10457761 Apr  6  2006 rmanO
-rwxr-x--x    1 oracle   oinstall 10457761 Sep 23 23:48 rman
-rwsr-s--x    1 oracle   oinstall 93300507 Apr  6  2006 oracleO
-rwx------    1 oracle   oinstall 93300507 Sep 23 23:49 oracle


perceberá que os tamanhos dos arquivos são mostrados em bytes. Talvez seja fácil lidar com arquivos pequenos, mas quando os tamanhos dos arquivos são bem grandes, um número longo pode não ter fácil leitura. Nesse caso, a opção "-h" se torna conveniente para exibir o tamanho em formato legível.

$ ls -lh
-rwxr-x--x    1 oracle   oinstall      10M Apr  6  2006 rmanO
-rwxr-x--x    1 oracle   oinstall      10M Sep 23 23:48 rman
-rwsr-s--x    1 oracle   oinstall      89M Apr  6  2006 oracleO
-rwx------    1 oracle   oinstall      89M Sep 23 23:49 oracle


Observe que o tamanho é mostrado em M (megabytes), K (kilobytes) e assim por diante. 

$ ls -lr

O parâmetro -r mostra o resultado em ordem invertida. Nesse comando, os arquivos serão mostrados em ordem alfabética invertida. 

$ ls -lR

O operador -R faz com que o comando ls seja executado recursivamente – ou seja, ir abaixo dos subdiretórios e mostrar esses arquivos também.

E se você quiser mostrar os arquivos dos maiores para os menores? Isso pode ser feito com o parâmetro -S. 

$ ls -lS
total 308
  -rw-r-----    1 oracle   oinstall    52903 Oct 11 18:31 sqlnet.log
  -rwxr-xr-x    1 oracle   oinstall     9530 Apr  6  2006 root.sh
  drwxr-xr-x    2 oracle   oinstall     8192 Oct 11 18:14 bin
  drwxr-x---    3 oracle   oinstall     8192 Sep 23 23:49 lib

xargs

A maioria dos comandos do Linux tem a ver com a obtenção de um resultado: uma lista de arquivos, uma lista de strings e assim por diante. Mas e se você quiser usar algum outro comando com o resultado do anterior como parâmetro? Por exemplo, o comando file mostra o tipo do arquivo (executável, de texto ascii e assim por diante) e permite manipular o resultado para mostrar somente os nomes de arquivo. Agora, você quer passar esses nomes para o comando ls -l para ver o registro de data e hora. O comando xargs faz exatamente isso. Ele permite executar alguns outros comandos no resultado. Lembre-se desta sintaxe da Parte 1: 

file -Lz * | grep ASCII | cut -d":" -f1 | xargs ls -ltr

Agora, queremos usar o comando ls -l e passar a lista acima como parâmetros, um por vez. O comando xargs permitia fazer isso. A última parte, xargs ls -ltr, pega o resultado e executa o comando ls -ltr com base neles, como se executasse: 

ls -ltr alert_DBA102.log
ls -ltr alert_DBA102.log.Z
ls -ltr dba102_asmb_12307.trc.Z
ls -ltr dba102_asmb_20653.trc.Z

 

Assim, xargs não é útil sozinho, mas é bastante poderoso quando combinado com outros comandos.

A seguir está outro exemplo, em que queremos contar a quantidade de linhas nesses arquivos: 

$ file * | grep ASCII | cut -d":" -f1  | xargs wc -l
  47853 alert_DBA102.log
     19 dba102_cjq0_14493.trc
  29053 dba102_mmnl_14497.trc
    154 dba102_reco_14491.trc
     43 dba102_rvwr_14518.trc
  77122 total

 

(Observação: a tarefa anterior também pode ser executada com o seguinte comando:) 

$ wc -l ‘file * | grep ASCII | cut -d":" -f1 | grep ASCII | cut -d":" -f1‘

A versão xargs é fornecida para ilustrar o conceito. O Linux tem várias maneiras de executar a mesma tarefa; use a mais adequada à sua situação.

Usando essa abordagem, você pode renomear arquivos em um diretório rapidamente. 

$ ls | xargs -t -i mv {} {}.bak

A opção -i instrui xargs para que substitua {} pelo nome de cada item. A opção -t instrui xargs para que imprima o comando antes de executá-lo.
Outra operação bem útil é quando você quer abrir arquivos para edição usando vi: 

$ file * | grep ASCII | cut -d":" -f1 | xargs vi

Este comando abre os arquivos um a um usando vi. Quando você quer procurar muitos arquivos e abri-los para edição, ele é bastante conveniente.

Também tem várias opções. Talvez a mais útil seja a opção -p, que torna a operação interativa: 

$ file * | grep ASCII | cut -d":" -f1 | xargs -p vi
vi alert_DBA102.log dba102_cjq0_14493.trc dba102_mmnl_14497.trc
   dba102_reco_14491.trc dba102_rvwr_14518.trc ?...


Nesse código, xarg pede para você confirmar antes de executar cada comando. Pressionando "y", o comando será executado. Você o achará extremamente útil em algumas operações irreversíveis e com potencial de corromper o arquivo – por exemplo, removê-lo ou sobrescrevê-lo.

A opção -t usa um modo detalhado; ela exibe o comando que está prestes a executar, o que é bastante proveitoso durante a depuração.

E se o resultado passado para xargs estiver em branco? Leve em consideração

$ file * | grep SSSSSS | cut -d":" -f1 | xargs -t wc -l
wc -l 
            0
$

 

Nesse caso, procurar "SSSSSS" não produz nenhuma correspondência; por isso, a entrada para xargs está totalmente em branco, conforme mostra a segunda linha (produzida desde que usamos a opção -t ou detalhada). Talvez isso seja útil, mas em alguns casos convém interromper xargs se não houver algo para ser processado; nesse caso, você poderá usar a opção -r: 

$ file * | grep SSSSSS | cut -d":" -f1 | xargs -t -r wc -l
$

 

O comando é encerrado se não há nada a ser executado.

Vamos supor que você queira remover os arquivos usando o comando rm, que deveria ser o argumento do comando xargs. Entretanto, rm pode aceitar uma quantidade limitada de argumentos. E se a lista de argumentos ultrapassar esse limite? A opção -n de xargs limita a quantidade de argumentos em uma única linha de comando.

A seguir está o procedimento para limitar somente dois argumentos por linha de comando: Mesmo se cinco arquivos forem passados para xargs ls -ltr, somente dois serão passados para ls -ltr por vez. 

$ file * | grep ASCII | cut -d":" -f1 | xargs -t -n2 ls -ltr  
ls -ltr alert_DBA102.log dba102_cjq0_14493.trc 
-rw-r-----    1 oracle   dba           738 Aug 10 19:18 dba102_cjq0_14493.trc
-rw-r--r--    1 oracle   dba       2410225 Aug 13 05:31 alert_DBA102.log
ls -ltr dba102_mmnl_14497.trc dba102_reco_14491.trc 
-rw-r-----    1 oracle   dba       5386163 Aug 10 17:55 dba102_mmnl_14497.trc
-rw-r-----    1 oracle   dba          6808 Aug 13 05:21 dba102_reco_14491.trc
ls -ltr dba102_rvwr_14518.trc 
-rw-r-----    1 oracle   dba          2087 Aug 10 04:30 dba102_rvwr_14518.trc

 

Usando essa abordagem, você pode renomear arquivos em um diretório rapidamente. 

$ ls | xargs -t -i mv {} {}.bak

A opção -i instrui xargs para que substitua {} pelo nome de cada item.


rename

Como você sabe, o comando mv renomeia arquivos. Por exemplo,

$ mv oldname newname

substitui todos os arquivos com a extensão .log por .log.<formato_de_data>. Assim, sqlnet.log torna-se sqlnet.log.2006-09-12-23:26:28.


find

Um dos comandos mais conhecidos dos usuários Oracle é o find. A esta altura, você já sabe como usar find para localizar arquivos em um determinado diretório. A seguir está um exemplo de como localizar arquivos que começam com a palavra "file" no diretório atual: 

$ find . -name "file*"
./file2
./file1
./file3
./file4

 

Entretanto, e se você quiser procurar nomes como FILE1, FILE2 e assim por diante? -name "file*" não corresponderá a eles. No caso de uma procura sem diferenciação entre maiúsculas e minúsculas, use a opção -iname: 

$ find . -iname "file*"
./file2
./file1
./file3
./file4
./FILE1
./FILE2

 

Você pode limitar sua procura a somente um tipo específico de arquivos. Por exemplo, o comando anterior obterá os arquivos de todos os tipos: arquivos normais, diretórios, links simbólicos e assim por diante. Para procurar somente os normais, use o parâmetro -type f. 

$ find . -name "orapw*" -type f 
./orapw+ASM
./orapwDBA102
./orapwRMANTEST
./orapwRMANDUP
./orapwTESTAUX

 

O -type pode incluir os modificadores f (arquivos normais), l (links simbólicos), d (diretórios), b (dispositivos de bloco), p (pipes nomeados), c (dispositivos de caractere), s (soquetes).

Um pequeno truque no comando anterior é combiná-lo com o comando file que você aprendeu na Parte 1. O comando file informa qual tipo de arquivo ele é. Você pode passá-lo como um pós-processador para o resultado a partir do comando find. O parâmetro -exec executa o comando após o parâmetro. Nesse caso, o comando a ser executado após find é file: 

$ find . -name "*oraenv*" -type f -exec file {} \;
./coraenv: Bourne shell script text executable
./oraenv: Bourne shell script text executable

 

Isso é útil quando você quer descobrir se o arquivo de texto ASCII poderia ser algum tipo de script de shell.

Se você substituir -exec por -ok, o comando será executado, mas solicitará sua confirmação antes. A seguir está um exemplo: 

 find . -name "sqlplus*" -ok {} \;      
< {} ... ./sqlplus > ? y
 
SQL*Plus: Release 9.2.0.5.0 - Production on Sun Aug 6 11:28:15 2006
 
Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
 
Enter user-name: / as sysdba
 
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.5.0 - 64bit Production
With the Partitioning, Real Application Clusters, OLAP and Oracle Data Mining options
JServer Release 9.2.0.5.0 - Production
 
SQL> exit
Disconnected from Oracle9i Enterprise Edition Release 9.2.0.5.0 - 64bit Production
With the Partitioning, Real Application Clusters, OLAP and Oracle Data Mining options
JServer Release 9.2.0.5.0 - Production
< È* ... ./sqlplusO > ? n
$

 

Nesse exemplo, pedimos ao shell para localizar todos os programas que começam com "sqlplus" e executá-los. Observe que não há nada entre -ok e {}, por isso ele apenas executará os arquivos que localizar. O shell localiza dois arquivos – sqlplus e sqlplusO – e, para cada caso, pergunta se você quer executar o arquivo. Respondemos "y" ao prompt em relação a "sqlplus" e ele foi executado. Depois de encerrado, foi emitido o prompt para o segundo arquivo localizado (sqlplusO) e a confirmação outras vezes, ao qual respondemos "n" – assim, ele não foi executado.

Dica para usuários Oracle


O Oracle produz muitos arquivos irrelevantes: arquivos de rastreamento, de log, de despejo e assim por diante. A menos que sejam limpos periodicamente, eles poderão sobrecarregar o sistema de arquivos e paralisar o banco de dados.

Para evitar que isso aconteça, simplesmente procure os arquivos com a extensão "trc" e remova-os se tiverem mais de três dias. Um simples comando faz o truque:

find . -name "*.trc" -ctime +3 -exec rm {} \;

Para forçar a remoção deles antes do prazo-limite de três dias, use a opção -f.

find . -name "*.trc" -ctime +3 -exec rm -f {} \;

Se quiser apenas listar os arquivos:

find . -name "*.trc" -ctime +3 -exec rm {} \;

 

m4

Este comando pega um arquivo de entrada e substitui as strings contidas nele pelos parâmetros passados, o que é semelhante à substituição por variáveis. Por exemplo, a seguir está um arquivo de entrada: 

$ cat temp
The COLOR fox jumped over the TYPE fence.

 

Se você fosse substituir as strings "COLOR" por "brown" e "TYPE" por "broken", poderia usar: 

$ m4 -DCOLOR=brown -DTYPE=broken temp
The brown fox jumped over the broken fence.
Else, if you want to substitute "white" and "high" for the same:

$ m4 -DCOLOR=white -DTYPE=high temp  
The white fox jumped over the high fence.


whence and which

Esses comandos são usados para descobrir onde os executáveis mencionados estão armazenados no CAMINHO do usuário. Quando os executáveis são localizados no caminho, eles se comportam da mesma maneira e exibem o caminho: 

$ which sqlplus  
                        
/u02/app/oracle/products/10.2.0.1/db1/bin/sqlplus
                        
$ whence sqlplus
                        
/u02/app/oracle/products/10.2.0.1/db1/bin/sqlplus
                      

O resultado é idêntico. Entretanto, se o executável não for encontrado no caminho, o comportamento será diferente. O comando which produz uma mensagem explícita: 

$which sqlplus                         

/u02/app/oracle/products/10.2.0.1/db1/bin/sqlplus

$ whence sqlplus

/u02/app/oracle/products/10.2.0.1/db1/bin/sqlplus
                      

e retorna para o prompt do shell. Isso é útil em casos em que o executável não é localizado no caminho (em vez de exibir a mensagem): 

$ whence invalid_command                      

$ which invalid_command

which: no invalid_command in (/usr/kerberos/sbin:/usr/kerberos/bin:/bin:/sbin:
                        
                              /usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:

                              /usr/bin/X11:/usr/X11R6/bin:/root/bin)      
                      

Quando whence não localiza um executável no caminho, ele retorna sem nenhuma mensagem, mas o código de retorno não é zero. Esse fato pode ser explorado em scripts de shell, por exemplo: 

RC=‘whence myexec‘
                        
If [ $RC -ne "0" ]; then
                        
   echo "myexec is not in the $PATH"

fi       
                      

Uma opção muito útil é -i, que exibe o alias e também o executável, se estiver presente. Por exemplo, você viu o uso do alias no início deste artigo. O comando rm é na verdade um alias em meu shell, e há um comando rm em qualquer outro lugar no sistema também, 

$ which ls
  /bin/ls
  $ which -i ls
  alias ls='ls --color=tty'
  /bin/ls

cujo comportamento padrão é mostrar a primeira ocorrência do executável no caminho. Se o executável existir em diferentes diretórios no caminho, as ocorrências subseqüentes serão ignoradas. Você pode ver todas as ocorrências do executável através da opção -a. 

$ which java
                        
  /usr/bin/java

$ which -a java

  /usr/bin/java

  /home/oracle/oracle/product/11.1/db_1/jdk/jre/bin/java

top

O comando top provavelmente é o mais útil para um DBA Oracle que gerencia um banco de dados no Linux. Suponha que o sistema esteja lento e que você queira descobrir quem está sugando toda a CPU e/ou memória. Para exibir os principais processos, use o comando top.
Observe que, diferentemente de outros comandos, top não produz um resultado e fica parado. Ele atualiza a tela para exibir as novas informações. Por isso, se você apenas emitir top e deixar a tela ativa, as informações mais atuais estarão sempre aparecendo. Para interromper, encerrar e voltar para o shell, você pode pressionar Control-C. 

$ top

18:46:13  up 11 days, 21:50,  5 users,  load average: 0.11, 0.19, 0.18 
151 processes: 147 sleeping, 4 running, 0 zombie, 0 stopped 
CPU states:  cpu    user    nice  system    irq  softirq  iowait    idle 
           total   12.5%    0.0%    6.7%   0.0%     0.0%    5.3%   75.2% 
Mem:  1026912k av,  999548k used,   27364k free,       0k shrd,  116104k buff 
                    758312k actv,  145904k in_d,   16192k in_c 
Swap: 2041192k av,  122224k used, 1918968k free                  590140k cached 
 
  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME CPU COMMAND 
  451 oracle    15   0  6044 4928  4216 S     0.1  0.4   0:20   0 tnslsnr 
 8991 oracle    15   0  1248 1248   896 R     0.1  0.1   0:00   0 top 
    1 root      19   0   440  400   372 S     0.0  0.0   0:04   0 init 
    2 root      15   0     0    0     0 SW    0.0  0.0   0:00   0 keventd 
    3 root      15   0     0    0     0 SW    0.0  0.0   0:00   0 kapmd 
    4 root      34  19     0    0     0 SWN   0.0  0.0   0:00   0 ksoftirqd/0 
    7 root      15   0     0    0     0 SW    0.0  0.0   0:01   0 bdflush 
    5 root      15   0     0    0     0 SW    0.0  0.0   0:33   0 kswapd 
    6 root      15   0     0    0     0 SW    0.0  0.0   0:14   0 kscand 
    8 root      15   0     0    0     0 SW    0.0  0.0   0:00   0 kupdated 
    9 root      25   0     0    0     0 SW    0.0  0.0   0:00   0 mdrecoveryd
... output snipped ...


Vamos examinar os diferentes tipos de informações produzidas. A primeira linha:

18:46:13 up 11 days, 21:50, 5 users, load average: 0.11, 0.19, 0.18

mostra a hora atual (18:46:13), que o sistema está ativo há 11 dias; que o sistema está funcionando há 21 horas e 50 segundos. A média de carga do sistema é mostrada (0.11, 0.19, 0.18) para os últimos 1, 5 e 15 minutos, respectivamente. (Aliás, também é possível obter essas informações emitindo o comando uptime.)

Se a média de carga não for necessária, pressione a letra "l" (L minúsculo); ela será desativada. Para reativá-la, pressione l novamente. A segunda linha: 

151 processes: 147 sleeping, 4 running, 0 zombie, 0 stopped

mostra o número de processos, em execução, em hibernação etc. A terceira e quarta linhas: 

CPU states:  cpu    user    nice  system    irq  softirq  iowait    idle

           total   12.5%    0.0%    6.7%   0.0%     0.0%    5.3%   75.2%
                      

mostram os detalhes de utilização da CPU. A linha anterior mostra que os processos do usuário consomem 12,5% e o sistema consome 6,7%. Os processos do usuário incluem os processos do Oracle. Pressione "t" para desativar e ativar essas três linhas. Se houver mais de uma CPU, você verá uma linha por CPU.

As duas próximas linhas:
  

Mem:  1026912k av, 1000688k used,  26224k free,    0k shrd,  113624k buff

758668k actv,  146872k in_d,  14460k in_c

Swap: 2041192k av, 122476k used,   1918716k free             591776k cached
                      

mostram a memória disponível e utilizada. A memória total é de "1026912kb av", aproximadamente 1 GB, dos quais somente 26224 kb ou 26 MB estão livres. O espaço de permuta é de 2 GB; mas praticamente não é usado. Para desativá-lo e ativá-lo, pressione "m".
O restante da exibição mostra os processos em um formato tabular. A seguir está a explicação das colunas:

Coluna Descrição

PID

O ID do processo

USER

O usuário que executa o processo

PRI

A prioridade do processo

NI

O valor bom: quanto maior o valor, menor a prioridade da tarefa

SIZE

Memória usada por esse processo (código+dados+pilha)

RSS

A memória física usada por esse processo

SHARE

A memória compartilhada usada por esse processo

STAT

O status desse processo, mostrado em código. Alguns códigos de status principais são:
R – Em execução
S – Em hibernação
Z – Zumbi
T – Interrompido
Também é possível ver o segundo e terceiro caracteres, que indicam:
W – Processo permutado
N – Valor bom positivo

%CPU

A porcentagem da CPU usada por esse processo

%MEM

A porcentagem de memória usada por esse processo

TIME

O tempo total de CPU usado por esse processo

CPU

Se este é um sistema de múltiplos processadores, esta coluna indica o ID da CPU em que esse processo está sendo executado.

COMMAND

O comando emitido por esse processo


Enquanto top estiver sendo exibido, você pode pressionar algumas teclas para formatar a exibição como desejar. Pressione a tecla M maiúscula para classificar o resultado por utilização de memória. (Observe que o uso de m minúsculo desativará ou ativará as linhas de resumo de memória no topo da exibição.) Isso é muito útil para descobrir quem está consumindo a memória. A seguir está um exemplo de resultado: 

PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME CPU COMMAND

31903 oracle  15   0 75760  72M 72508 S     0.0  7.2   0:01   0 ora_smon_PRODB2
                        
31909 oracle  15   0 68944  66M 64572 S     0.0  6.6   0:03   0 ora_mmon_PRODB2
                        
31897 oracle  15   0 53788  49M 48652 S     0.0  4.9   0:00   0 ora_dbw0_PRODB2
                      


Agora que você aprendeu a interpretar o resultado, vamos ver como usar os parâmetros de linha de comando.

O mais útil é -d, que indica o atraso entre as atualizações de tela. Para atualizar a cada segundo, use top -d 1.

A outra opção útil é -p. Para monitorar somente alguns processos, e não todos, especifique somente aqueles depois da opção -p. Para monitorar os processos 13609, 13608 e 13554, emita: 

top -p 13609 -p 13608 -p 13554 


Isso mostrará os resultados no mesmo formato do comando top, mas somente os processos específicos.

Dica para usuários Oracle

Provavelmente nem é preciso dizer que o utilitário top é muito conveniente para analisar a performance de servidores de banco de dados. A seguir está um resultado parcial de top. 

20:51:14  up 11 days, 23:55,  4 users,  load average: 0.88, 0.39, 0.27
  113 processes: 110 sleeping, 2 running, 1 zombie, 0 stopped
  CPU states:  cpu    user    nice  system    irq  softirq  iowait    idle 
  total    1.0%    0.0%    5.6%   2.2%     0.0%   91.2%    0.0%
  Mem:  1026912k av, 1008832k used,   18080k free,       0k shrd,   30064k buff
  771512k actv,  141348k in_d,   13308k in_c 
  Swap: 2041192k av,   66776k used, 1974416k free                  812652k cached 
  
  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME CPU COMMAND 
  16143 oracle    15   0 39280  32M 26608 D     4.0  3.2   0:02   0 oraclePRODB2...
  5 root      15   0     0    0     0 SW    1.6  0.0   0:33   0 kswapd
  ... output snipped ...


Vamos analisar o resultado cuidadosamente. A primeira coisa que você deve perceber é a coluna "idle" nos estados da CPU; ela é 0.0% – ou seja, a CPU está completamente ocupada com alguma tarefa. A pergunta é: qual tarefa? Mude a atenção para a coluna "system", um pouco à esquerda; ela mostra 5.6%. Isso quer dizer que o sistema em si não tem muitas tarefas. Prossiga mais para a esquerda até a coluna marcada "user", que mostra 1.0%. Como os processos do usuário incluem Oracle também, o Oracle não está consumindo os ciclos de CPU. Então, o que está comendo toda a CPU?

A resposta está na mesma linha, logo à direita na coluna "iowait", que indica 91.2%. Isso explica tudo: a CPU está esperando IO em 91,2% do tempo.

Então, por que tanta espera de IO? A resposta está na exibição. Observe o PID do processo de maior consumo: 16143. Você pode usar a seguinte consulta para determinar o que o processo está fazendo: 

select s.sid, s.username, s.program
from v$session s, v$process p
where spid = 16143
and p.addr = s.paddr
/

       SID USERNAME PROGRAM
------------------- -----------------------------
       159 SYS      rman@prolin2 (TNS V1-V3)   


O processo rman está consumindo os ciclos de CPU relacionados a esperas de IO. Essas informações ajudam a determinar o próximo curso de ação.

skill e snice

Na discussão anterior você aprendeu como identificar um recurso que consome CPU. E se você achar que um processo está consumindo muita CPU e memória, mas não quiser encerrá-lo? Leve em consideração o resultado de top a seguir: 

$ top -c -p 16514

23:00:44  up 12 days,  2:04,  4 users,  load average: 0.47, 0.35, 0.31 
1 processes: 1 sleeping, 0 running, 0 zombie, 0 stopped 
CPU states:  cpu    user    nice  system    irq  softirq  iowait    idle 
           total    0.0%    0.6%    8.7%   2.2%     0.0%   88.3%    0.0% 
Mem:  1026912k av, 1010476k used,   16436k free,       0k shrd,   52128k buff 
                    766724k actv,  143128k in_d,   14264k in_c 
Swap: 2041192k av,   83160k used, 1958032k free                  799432k cached 
 
  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME CPU COMMAND 
16514 oracle    19   4 28796  26M 20252 D N   7.0  2.5   0:03   0 oraclePRODB2...


Agora que você confirmou que o processo 16514 está consumindo muita memória, você pode "congelá-lo" – mas não encerrá-lo – usando o comando skill. 

$ skill -STOP 1

Depois disso, verifique o resultado de top:

 

23:01:11  up 12 days,  2:05,  4 users,  load average: 1.20, 0.54, 0.38

1 processes: 0 sleeping, 0 running, 0 zombie, 1 stopped
CPU states:  cpu    user    nice  system    irq  softirq  iowait    idle
    total    2.3%    0.0%    0.3%   0.0%     0.0%    2.3%   94.8%
Mem:  1026912k av, 1008756k used,   18156k free,       0k shrd,    3976k buff
                    770024k actv,  143496k in_d,   12876k in_c
Swap: 2041192k av,   83152k used, 1958040k free                  851200k cached
                        

  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME CPU COMMAND
16514 oracle    19   4 28796  26M 20252 T N   0.0  2.5   0:04   0 oraclePRODB2...
                      

A CPU agora está 94% ociosa partindo de 0%. O processo está efetivamente congelado. Após algum tempo, você pode querer reavivar o processo do “coma”: 

$ skill -CONT 16514

Essa abordagem é extremamente útil para congelar temporariamente os processos e liberar espaço para processos mais importantes a ser concluídos.

O comando é muito versátil. Se você quiser interromper todos os processos do usuário "oracle", um único comando fará isso: 

$ skill -STOP oracle

Você pode usar um usuário, PID, comando ou id de terminal como argumento. O código a seguir interrompe todos os comandos rman. 

$ skill -STOP rman

Como você pode ver, skill decide o argumento que você informou – um ID de processo, ID de usuário ou comando – e atua adequadamente. Isso pode causar um problema em alguns casos, em que você tem um usuário e um comando no mesmo nome. O melhor exemplo é o processo "oracle", que em geral é executado pelo usuário "oracle". Assim, quando você quer interromper o processo chamado "oracle" e emite: 

$ skill -STOP oracle

todos os processos do usuário "oracle" são interrompidos, incluindo a sessão em que você estiver. Para ser bem explícito, você pode opcionalmente dar um novo parâmetro para especificar o tipo de parâmetro. Para interromper um comando chamado oracle, você pode emitir: 

$ skill -STOP -c oracle

O comando snice é semelhante. Em vez de interromper um processo, ele rebaixa sua prioridade. Primeiro, verifique o resultado de top: 

  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME CPU COMMAND 
    3 root      15   0     0    0     0 RW    0.0  0.0   0:00   0 kapmd 
13680 oracle    15   0 11336  10M  8820 T     0.0  1.0   0:00   0 oracle 
13683 oracle    15   0  9972 9608  7788 T     0.0  0.9   0:00   0 oracle 
13686 oracle    15   0  9860 9496  7676 T     0.0  0.9   0:00   0 oracle 
13689 oracle    15   0 10004 9640  7820 T     0.0  0.9   0:00   0 oracle 
13695 oracle    15   0  9984 9620  7800 T     0.0  0.9   0:00   0 oracle 
13698 oracle    15   0 10064 9700  7884 T     0.0  0.9   0:00   0 oracle 
13701 oracle    15   0 22204  21M 16940 T     0.0  2.1   0:00   0 oracle
                      

Agora, ignore a prioridade dos processos de "oracle" em quatro pontos. Observe que, quanto maior o número, menor a prioridade. 

$ snice +4 -u oracle

  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME CPU COMMAND 
16894 oracle    20   4 38904  32M 26248 D N   5.5  3.2   0:01   0 oracle


Observe como a coluna NI (valores bons) agora é 4 e a prioridade agora é definida como 20, em vez de 15. Isso é bem útil ao reduzir prioridades. 


Arup Nanda ( arup@proligence.com) é DBA Oracle há mais de 12 anos, lidando com todos os aspectos de gerenciamento de banco de dados – como ajuste de performance, segurança e recuperação de catástrofes, dentre outros. É co-autor de PL/SQL for DBAs (O'Reilly Media, 2005), foi “DBA do Ano” da Oracle Magazine em 2003 e é ACE Oracle.