Problema
As aplicações conectando no banco de dados, quando executam “SELECT SYSDATE FROM DUAL” recebem um horário 3h adiantado.
O horário no servidor (comando date no Linux) estava correto.
O resultado da consulta “SELECT SYSDATE FROM DUAL” conecando diretamente na instância com “sqlplus / as sysdba” retornava o horário correto.
O timezone do servidor estava correto (comando timedatectl), estava com “America/Sao_Paulo (-03, -0300)”.
Conexão via sqlplus através do servidor, mas passando pelo Listener (comando sqlplus usuario@banco) retornava o horário incorreto.
O problema ocorria somente quando a instância era iniciada via srvctl, se iniciada diretamente via sqlplus. o horário sempre retornava correto.
Não havia variável de ambiente no profile do banco (srvctl getenv database).
Não havia variável de ambiente no profle do listener (srvctl getenv listener).
Causa
O Grid Infrastructure foi instalado quando o servidor tinha o Time Zone UTC, depois o Time Zone do sistema operacional (Linux) foi alterado para “America/Sao_Paulo”. O Grid tem um arquivo de variaveis de ambiente que é definido durante a instalação dos binários e precisaria ser ajustado manualmente quando alterasse o Time Zone do SO.
O arquivo fica em: GI_HOME/crs/install/s_crsconfig_<hostname>_env.txt
$ . oraenv <<< +ASM1
ORACLE_SID = [grid] ? The Oracle base remains unchanged with value /u01/app/grid
$ cat $ORACLE_HOME/crs/install/s_crsconfig_$(hostname)_env.txt
#########################################################################
#This file can be used to set values for the NLS_LANG and TZ environment
#variables and to set resource limits for Oracle Clusterware and
#Database processes.
#1. The NLS_LANG environment variable determines the language and
# characterset used for messages. For example, a new value can be
# configured by setting NLS_LANG=JAPANESE_JAPAN.UTF8
#2. The Time zone setting can be changed by setting the TZ entry to
# the appropriate time zone name. For example, TZ=America/New_York
#3. Resource limits for stack size, open files and number of processes
# can be specified by modifying the appropriate entries.
#
#Do not modify this file except as documented above or under the
#direction of Oracle Support Services.
#########################################################################
TZ=UTC
NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1
CRS_LIMIT_STACK=2048
CRS_LIMIT_OPENFILE=65536
CRS_LIMIT_NPROC=65536
TNS_ADMIN=
Solução
Alterar o arquivo GI_HOME/crs/install/s_crsconfig_<hostname>_env.txt com Time Zone correto e reiniciar o CRS.
O arquivo pertence ao usuário root:
$ echo $ORACLE_HOME/crs/install/s_crsconfig_$(hostname)_env.txt
/u01/app/19.0.0.0/grid/crs/install/s_crsconfig_dbprd_env.txt
$ exit
logout
# vi /u01/app/19.0.0.0/grid/crs/install/s_crsconfig_dbprd_env.txt
Em TZ, foi alterado para ficar dessa forma:
TZ=America/Sao_Paulo
Por fim, reinicie os serviços do Grid.
ATENÇÃO! Essa etapa requer DOWNTIME, irá parar todas as instâncias no servidor.
# crsctl stop crs
# crsctl start crs
O comando de start retorna quase imediamente, mas os serviços são inicializados na sequência e pode levar alguns minutos até que a instância de banco de dados fique online novamente, mas ela será iniciada de forma automática.
Referências
Real Application Clusters Installation Guide for Linux and UNIX
To change the time zone of the host on DB systems that use Grid Infrastructure.
How To Change Timezone for Grid Infrastructure (Doc ID 1209444.1)