Translate

viernes, 12 de octubre de 2012

Upgrade Grid infraestructure and database from 11.2.0.1 to 11.2.0.2 step by step



En la siguiente nota, se encuentran los pasos para actualizar ASM y la base de datos de la versión  11.2.0.1 a  las versión  11.2.0.2, la manera descripta a continuación es la recomendada por Oracle.

Actualización del home Grid Infraestructure:

1- Para esto se necesita bajar los instaladores de la pagina de Oracle support ,es el patchset 11.2.0.2 , solo neceitamos  el 1 , 2 y3 .El 1y2 donde el binario de la base de datos  y el 3  es el binario  del  grid  infraestructure.

Database:
p10098816_112020_Linux-x86-64_1of7.zip 
p10098816_112020_Linux-x86-64_2of7.zip

Grid Infraestructure:
p10098816_112020_Linux-x86-64_3of7.zip


2- Instalar el binario de Grid Infrastructure 11.2.0.2 en una ubicación diferente en la que se encuentra instalado el binario de Grid Infraestucture 11.2.0.1 que queremos  actualizar.

En mi caso tenia instalado la version 11.2.0.1 en el siguiente path:
/oracle/app/oracle/product/11.2.0

Para la instalacion del nuevo binario del grid genere un directorio con el nombre "11.2.0.2". /oracle/app/oracle/product/11.2.0.2  


 hacemos  unzip  p10098816_112020_Linux-x86-64_3of7.zip

Nos genera una carpeta llama Grid 

Nota: Antes  de comenzar la instalacion se debe bajar las instancias de base de datos  que utilizan  ASM 

/vol01/soft/grid/./runInstaller

Elegimos la opcion:

"Upgrade Oracle Grid Infrastructure or Oracle Automatic Storage Management" 

Software Location :  es la ubicacion  donde se va a instalar el nuevo  Grid 11.2.0.2 

ej:
/oracle/app/oracle/product/11.2.0.2/grid 


3- Al finalizar la actualizacion nos va a pedir que ejecutemos  un scrupt  con  el usuario  root 

/oracle/product/oragrid/11.2.0.2/rootupgrade.sh 

Este shell  , va a ser el encanrgado  de hacer el proceso  de migracion  de la la instancia asm  al  nuevo  home 11.2.0.2 , no es necesario bajar la instancia ASM  este se encarga de hacer el shutdown  de la manera  ordenada.

Al terminar la ejecuacion  de este proceso  ya tenemos  migrado  listo  el upgrade del  Grid Infraestructure  con  su  respectiva instancia  ASM


Actualización del home de la base de datos:


1- En la base a actualizar (11.2.0.1) ejecutar los  siguentes comandos sql:

a)Purgar el recycle bin:
PURGE DBA_RECYCLEBIN;

b)Truncar la pista de auditoria
TRUNCATE TABLE SYS.AUD$;

c)Como best practice de Oracle, se requiere una recopilacion de estadisticas para una posterior  comparacion con la base ya con  upgrade realizado.

execute dbms_stats.gather_dictionary_stats;
execute dbms_stats.gather_fixed_objects_stats;
@?/rdbms/admin/catplan.sql  -- recrear la plan table
@?/rdbms/admin/dbmsxpln.sql -- reload dbms_xplan spec
@?/rdbms/admin/prvtxpln.plb -- reload dbms_xplan implementation  

d) Verificar  los  objetos  invalidos :
SELECT UNIQUE object_name, object_type, owner FROM dba_objects WHERE status='INVALID'; 

En el caso de que la query anterior nos retona algo, ejecutar el siguente script para recompilarlos:
@?/rdbms/admin/utlrp.sql

Y verificar con la query anterior nuevamente.

4- Verificar si cumplimos con los prerequisitos , este escript  se encuentra en el home de la nueva instalacion.

SPOOL /home/oracle/upgrade_info2.log
@/oracle/app/oracle/product/11.2.0.2/db/rdbms/admin/utlu112i.sql
SPOOL OFF


5- Instalar el binario de base de datos de la version 11.2.0.2 en una ubicacion  diferente en el que estaba  el de la version  11.2.0.1 como  hicimos con  el grid 

ej: /oracle/app/oracle/product/11.2.0.2/db

Elegir  la opcion:  
"Install database software only"

Software location : /oracle/app/oracle/product/11.2.0.2/db

Al finalizar la instalacion ejecutamos  con  el usuario root  el shell

/oracle/app/oracle/product/11.2.0.2/db/root.sh

6- Ahora necesitamos hacer la migracion de la data de la base de datos 11.2.0.1 a la version 11.2.0.2 

Para esto necesitamos configurar las siguentes variable de entorno:

ORACLE_BASE=/oracle/app/oracle; export ORACLE_BASE
ORACLE_HOME=$ORACLE_BASE/product/11.2.0.2/db; export ORACLE_HOME
PATH=/usr/sbin:$PATH; export PATH
PATH=$ORACLE_HOME/bin:$PATH; export PATH
LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib; export LD_LIBRARY_PATH
CLASSPATH=$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib; export CLASSPATH


7- Ejecutamos  el database upgrade assitant

dbua

Elegimos que base vamos a actualizar, next, next ,next y al terminar nos da un reporte de que cosas fallaron  o si somos exitosos con  la actualizacion.

con  esto  nuestros  homes  estas migrados  a 11.2.0.2 

En el caso que tengas que actualizar la version del DST, aqui  indico el ID de  nota en el MOS (ID 977512.1)   









miércoles, 26 de septiembre de 2012

Baseline from 10g to 11g , migration baseline

Importar un sqlset de 10g  a 11g

Muchas veces migramos de versiones 10 a 11r2 y tenemos  problemas de performance ya que lamentablemente el optimizer de la version 11g de Oracle no logra resolver de la mejor manera algunas queries que en la version 10g funcionaban de maravillas.

Aqui  les indico una manera de transladar el plan de ejecucion de esa consulta tediosa de la base 10g e  importarlo en la version 11g

1- Ejecutamos en la base de datos  10g

a) Creamos el baseline

BEGIN
    DBMS_SQLTUNE.CREATE_SQLSET(
        sqlset_name => '10G_TO_11G'
    );
END;
/


b) Capturamos los planes de ejecucion  durante 60 segundos en intevalos de 5 segundos, en este momento ejecutamos las consultas que funcionaban bien en la version 10g.

exec dbms_sqltune.capture_cursor_cache_sqlset( -
                                        sqlset_name     => '10G_TO_11G', -
                                        time_limit      =>  60, -
                                        repeat_interval =>  5);

b) Cuando termine la captura verificamos la cantidad del consultas que hay en el baseline .

select owner,name, statement_count  from dba_sqlset;

select sql_id,sql_text  from dba_sqlset_statements where sqlset_name='10G_TO_11G' and  upper(sql_text) like '%VUELO%';

Nota:donde VUELO  es la parte del query que tenemos  problemas.

c) Compruebo el plan en la base 10g

select * from table(dbms_xplan.display_cursor('7019kaqwwd8j5',0));
veo el plan  y lo comparo con el de la base 11g

d) Creamos una tabla STAGE para pasar a la base 11g:

begin
     dbms_sqltune.create_stgtab_sqlset(
           table_name => 'STS10G_STAGING'
              );
end;

e) Generamos  un paquete con  la info del baseline
begin
      dbms_sqltune.pack_stgtab_sqlset(
           sqlset_name => '10G_TO_11G'
          ,sqlset_owner => 'SYS'
          ,staging_table_name => 'STS10G_STAGING'
          ,staging_schema_owner => 'SYS'
      );
end;
/

f) Verifico que se paso todo a la tabla stage
select count(*) from STS10G_STAGING;

g) Exporto  la tabla stage

exp \'/ as sysdba\' file=/home/oracle/10gsts.dmp tables=STS10G_STAGING


2) Ahora en la base de datos destino  11g

a) Importo la tabla

imp \'/ as sysdba\' file=/home/oracle/10gsts.dmp fromuser=sys  touser=sys

b) Desempacar los baselines  de la tabla a la base 11g

begin
    dbms_sqltune.unpack_stgtab_sqlset(
         sqlset_name => '10G_TO_11G'
        ,sqlset_owner => 'SYS'
        ,replace => true
        ,staging_table_name => 'STS10G_STAGING'
        ,staging_schema_owner => 'SYS'
    );
end;
/

c) Implementa la linea base 

declare
  my_10gplans pls_integer;
begin
  my_10gplans := dbms_spm.load_plans_from_sqlset( sqlset_name => '10G_TO_11G');
end;
/

d) Se busca informacion sobre la consulta  

select sql_handle,sql_text,created,enabled,fixed,accepted from dba_sql_plan_baselines where upper(sql_text) like '%VUELO%';

select sql_handle ,plan_name,enabled,accepted,fixed ,created from dba_sql_plan_baselines where sql_handle='SQL_34429a05d74fd322';

e) Se pone en fix el plan importando desde la verion 10 para no sea  reemplazado por un nuevo  plan  calculado por el  optimizer de la base 11g 

set serveroutput on
declare
  l_plans_altered  pls_integer;
begin
  l_plans_altered := dbms_spm.alter_sql_plan_baseline(
    sql_handle      => 'SQL_34429a05d74fd322',
    plan_name       => 'SQL_PLAN_38hnu0rbnznt2fbbfda9c',
    attribute_name  => 'fixed',
    attribute_value => 'YES');
  dbms_output.put_line('Plans Altered: ' || l_plans_altered);
end;
/

f) Muestra informacion sobre el baseline en la base 11g 

select * from table(
    dbms_xplan.display_sql_plan_baseline(
        sql_handle=>'SQL_34429a05d74fd322',
        format=>'basic'));

Aqui les dejo el procedimiento para borrar un baseline: 

set serveroutput on
declare
  l_plans_dropped  pls_integer;
begin
  l_plans_dropped := dbms_spm.drop_sql_plan_baseline (
    sql_handle => 'SYS_SQL_7b76323ad90440b9',
    plan_name  => null);
  dbms_output.put_line(l_plans_dropped);
end;
/


Export / Import estadisticas de Oracle optimizer


          Oracle nos da la facilidad de poder exportar e importar las estadísticas de la base de datos , esto nos puede ser de mucha ayuda , por ejemplo en el caso que tenemos la base de datos funcionando en óptimas condiciones podemos tener una snapshot de las estadísticas y usarlas como backup, ya que aveces el mantenimiento que realiza Oracle de forma automatica la noche nos pude modificar algún plan de ejecución  y esto desencadena en un dolor de cabeza al día siguiente.

        También  podemos insertas las mismas estadísticas que tenemos  en producción  en un ambiente de testing , de esta manera obtendríamos  los mismos  planes , etc ,etc ..

Aquí  les dejo  el procesamiento para esto :

1- creo la tabla de estadísticas
   execute dbms_stats.create_stat_table('CHARLY','STATS');

Donde CHARLY es el nombre del esquema y STATS  es el nombre de la table donde se almacenaran  las estadísticas.


2- Realizamos un exp de las estadísticas del schema que nos interesa.
   execute dbms_stats.export_schema_stats('CHARLY','STATS','PROD_2012-04-10');

Este comando carga  información  sobre las estadísticas del esquema en la tabla STATS , y le colocamos  como nombre PROD_2012-04-10 ya que podemos hacer que este procedimiento sea regular y podremos identificar cuando realizamos este export.

por tabla
   EXECUTE DBMS_STATS.EXPORT_TABLE_STATS (
                                       ownname => 'CHARLY',
                                       tabname => 'nombre_de_la tabla_ a_exportar_estadisticas',
                                       stattab => 'STATS',
                                       statid => 'tabla_prod_2012-04-10');


3- Realizamos un export de la tabla STATS para transportar las estadísticas , se importa al schema destino

 exp \' / as sysdba\' table=charly.stats file=stats.dmp
 imp \' / as sysdba\' full=y  file=stats.dmp

4- Importamos  las estadísticas desde  la tabla STATS al esquema destino
execute dbms_stats.import_schema_stats('CHARLY','STATS',' PROD_2012-04-10');

Hacemos lo mismo si  lo que queremos importar es solo las estadísticas de una tabla:

execute dbms_stats.import_table_stats(ownname => 'CHARLY',
                                                  tabname => ' nombre_de_la tabla_ a_exportar_estadisticas ',
                                                  stattab => 'STATS',
                                                  statid => ' tabla_prod_2012-04-10 ');



Estadisticas Oracle optimizer plan


Estadisticas  en una base Oracle

       El optimizador de Oracle se basa en los costos y estadísticas de la base de datos, esto quiere decir que necesita información acerca de los datos almacenados en la base para poder realizar un plan de ejecución lo mas óptimo posible, esta recolección de información comprende varios puntos importantes, como puede  ser la distribución de los datos dentro de las tablas, cantidad de índices que hay sobre que columnas , lo selectivo que es cada índice, la distribución de los datos dentro de una columna indexada (clustering_factor) , como  así  también estadísticas del sistema, que pueden variar si se toman de día o de noche , ya que una base de datos durante el día puede trabajar como oltp  y por la noche como olap, además si basamos nuestras estadísticas en el costo de cpu  o de i/o.
A partir de la versión 10g hay un proceso  de mantenimiento que captura estadísticas de manera automática en horarios nocturnos, esto es por default y se puede modificar el horario o desabilitar.

       El optimizador de oracle es una tema muy complejo y apasionante ya que existe infinidad de políticas para su uso , y se podria variar su comportamiento algunos  parametros  de inicializacion como pueden ser optimizer_index_caching, optimizer_index_cost_adj, optimizer_max_permutations, etc.

Esta nota apunta a enseñar los comandos basicos e indispensables  para la recuperación  de estadísticas .

Estadísticas de un esquema completo:
exec dbms_stats.gather_schema_stats (ownname=>'CHARLY',
                                                           estimate_percent=> dbms_stats.auto_sample_size,
                                                           method_opt => 'FOR ALL COLUMNS SIZE 10',
                                                           cascade => true
                                                           degree=>4);

Aqui  voy  a explicar algunas opciones de los parámetros  mas importantes de este package :

estimate_percent=>dbms_stats.auto_sample_size : Oracle decide  que grado  de estadísticas toma .
estimate_percent=>100 : Oracle recorre  todos los objetos  del esquema y toma el 100%  de información , en bases  de datos  grandes  muchas veces  es inviable esta opción.
estimate_percent=>15 : Oracle estima y solo toma 15 % de la información de cada objeto del esquema mencionado , el dba puede ir analizando  si  con  este porcentaje de muestra alcanza .

method_opt :
for all columns size skewonly  opción que requiere mucho tiempo intensivo porque examina la distribución de valores para cada columna dentro de cada índice , DBMS_STATS descubre un índice cuyas columnas están desigualmente distribuidos, se creará histogramas para dicho índice para tomar una decision  al momento  de usar  un indice  o hacer full scn  de la tabla.
for all columns size repeat: Oracle  solo  exinara los histogramas de las columnas que ya tienen  histogramas y no buscara potenciales  nuevas columnas analizar.
for all columns size auto (default):  analizara histogramas de la columnas que Oracle considere 

casdade => true :  indica que no solo va a tomar estadísticas de la tabla sino  de los indices  asociados  a  esta.

degree=>4 : indica el grado  de paralelismo , para poder  tomar un grado  indicado  de paralelismo  podemos  utilizar  la siguiente regla :
degree = PARALLEL_THREADS_PER_CPU x CPU_COUNT

También se puede recopilar estadísticas de una tabla o índice:

exec dbms_stats.gather_index_stats('CHARLY', 'EMPLOYEES_PK', estimate_percent => 15);
exec dbms_stats..gather_table_stats('CHALY','EMPLOYEES', estimate_percent => 15);


Insercion  de estadisticar artificiales:

Nosotros  como  dba's podemos alterar  los planes del optimizer  , mediante  hint  o bien  siendo  un poco  mas radicales  directamente generando información  falsa , de esta manera el optimizer  podría  utilizar un indice que nosotros  deseamos que use.

Por ejemplo:

dbms_stats.set_index_stats(ownname=> 'CHARLY',indname => 'EMPLOYEES_IDX01',numdist=> 500);

Las estadísticas de sistema se toman  de la siguiente manera:

exec dbms_stats.gather_system_stats (gathering_mode=>'START');

exec dbms_stats.gather_system_stats (gathering_mode=>'STOP');






viernes, 21 de septiembre de 2012

Implementaciòn de dataguard 11.2

Creación de dataguard mediante comandos sql:

Pre-requisitos de la base primaria:

1) alter  database force logging;
2) deben  estar seteados  los parámetros (transport  authentication)
            log_archive_dest_N =  ubicación  de los logs

3) Configurar primary  database para recibir redo (Section 6.2.3)
fal_server= va la entrada de  la que se va a definir como  primaria

Aqui tenemos  en modo  de ejemplo un archivo  de parametros para la base de datos  primaria    
Donde Chicago  es primaria  y Boston  secundaria:

LOG_ARCHIVE_CONFIG='DG_CONFIG=(chicago,boston)'
CONTROL_FILES='/arch1/chicago/control1.ctl', '/arch2/chicago/control2.ctl'
LOG_ARCHIVE_DEST_1='LOCATION=/arch1/chicago/ VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=chicago'
LOG_ARCHIVE_DEST_2='SERVICE=boston ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=boston'
LOG_ARCHIVE_DEST_STATE_1=ENABLE
LOG_ARCHIVE_DEST_STATE_2=ENABLE
REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE
LOG_ARCHIVE_FORMAT=%t_%s_%r.arc
LOG_ARCHIVE_MAX_PROCESSES=30


4) ALTER DATABASE CREATE STANDBY CONTROLFILE AS '/tmp/boston.ctl';

5) creamos el pfile para la base de datos standby 

CREATE PFILE='/tmp/initboston.ora' FROM SPFILE;

Lo pasamos al otro servidor si es que la generamos en otro server 

6) Preparar  el pfile para la standby ,modificando los parametros para indicar que va ser la standby 

DB_NAME=chicago
DB_UNIQUE_NAME=boston
LOG_ARCHIVE_CONFIG='DG_CONFIG=(chicago,boston)'
CONTROL_FILES='/arch1/boston/control1.ctl', '/arch2/boston/control2.ctl'
DB_FILE_NAME_CONVERT='chicago','boston'
LOG_FILE_NAME_CONVERT=
'/arch1/chicago/','/arch1/boston/','/arch2/chicago/','/arch2/boston/'
LOG_ARCHIVE_FORMAT=log%t_%s_%r.arc
LOG_ARCHIVE_DEST_1=
'LOCATION=/arch1/boston/
VALID_FOR=(ALL_LOGFILES,ALL_ROLES)
LOG_ARCHIVE_DEST_2=
'SERVICE=chicago ASYNC
VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)
DB_UNIQUE_NAME=chicago'
LOG_ARCHIVE_DEST_STATE_1=ENABLE
LOG_ARCHIVE_DEST_STATE_2=ENABLE
REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE
STANDBY_FILE_MANAGEMENT=AUTO
FAL_SERVER=chicago


7)Copiar el password  file de la primaria a la standby

8)Se deben configurar en ambos Server el tnsmanes y el listener para que se pueda  efectuar el cambio  de rol (de primaria  a standby)

9)Montarla base standby  y comenzar el recover

Aplicara los redo  en real time:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;


en caso  de querer  correrlo en foreground , ejecutar lo siguente:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE;

Notas: 
para cancelar el aplicado de redo ejecutar el siguente comendo  en el sqlplus
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;



10)Ejecutar en la primary
 ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE {AVAILABILITY | PERFORMANCE | PROTECTION};

11)verificar que la base primaria  esta trabajando  con  el metodo  de proteccion  indicado
SELECT PROTECTION_MODE FROM V$DATABASE;


Proceso de switch

Realizar el switch over hacia la standby fisica.
1) Verificar cual  es primaria y cual  standby:
SELECT SWITCHOVER_STATUS FROM V$DATABASE;

SWITCHOVER_STATUS
-----------------
TO STANDBY

El valor TO STANDBY o SESSIONS ACTIVE indica que la base de datos  primaria  puede cambiar a role standby.

2) Ejecutar sobre la primaria
ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN;
SQL> SHUTDOWN ABORT;
SQL> STARTUP MOUNT;

3) Ejecutar sobre la base standby  para ver si puede pasar  a role  primario

SELECT SWITCHOVER_STATUS FROM V$DATABASE;

Si nos retorna TO PRIMARY o SESSIONS ACTIVE la base standby puede ser switcheada como  role  primaria



4) Ejecutar en la standby
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;
ALTER DATABASE OPEN;

5) Ejecutar  en la  ex primaria (futura standby)
Comenzar el aplicado de redo hacia la nueva standby

ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;

Or

ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT;


Failover

1)se Ejecuta sobre la base de datos primaria en el caso de poderse montar.
# realiza un flush de los redo no enviados desde la primaria  hasta  la standby

ALTER SYSTEM FLUSH REDO TO 'SRDDBA';

2) Parar el REDO APPY en la base de datos standby

ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

3) Finalizar la aplicación de todos los redo recibidos (ejecutar en la standby)

ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;

4) Verificar que la standby  puede pasar a role primario

SELECT SWITCHOVER_STATUS FROM V$DATABASE;

Si nos retorna TO PRIMARY o SESSIONS ACTIVE la base standby puede ser switcheada como  role  primaria.

5) realizar switch de role fisica standby a primaria (ejecutar en standby)

ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY [WITH SESSION SHUTDOWN];

6) Abrir base de datos (ejecutar sobre la standby)

ALTER DATABASE OPEN;

7) Realizar un backup full de la nueva base de datos primaria.

8) Convertir  la vieja primaria  en standby fisica, usando flashback

a)Ejecutar  sobre la nueva primaria
SELECT TO_CHAR(STANDBY_BECAME_PRIMARY_SCN) FROM V$DATABASE;
TO_CHAR(STANDBY_BECAME_PRIMARY_SCN)
----------------------------------------
733778

b)Ejecutar sobre la vieja primaria

SQL>SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;

SQL> FLASHBACK DATABASE TO SCN 733778;

      c)Convertir  la vieja primaria a standby  fisica
      Ejecutar en la vieja primaria

ALTER DATABASE CONVERT TO PHYSICAL STANDBY;

Nota:este commando  desmonta la base de datos.

d) Shut down and restart the database:
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;

9) Start transporting redo to the new physical standby database.
Ejecutar en la nueva primaria

Set  lines 200;
col DESTINATION for a30
col DEST_name for a30;
col error for a10;
SELECT DEST_ID, DEST_NAME, STATUS, PROTECTION_MODE, DESTINATION, ERROR,SRL FROM V$ARCHIVE_DEST_STATUS;

En el  caso  de obtener  el siguente error :
ORA-12528:TNS:listener: all appropriate instances are blocking new connection

Ejecutar el siguente commando  para asegurar que la standby  recibe los redo desde la primaria.

SQL> ALTER SYSTEM SWITCH LOGFILE;

Verificar que el error  desaparecio.
SQL> SELECT DEST_ID, DEST_NAME, STATUS, PROTECTION_MODE, DESTINATION, ERROR,SRL FROM V$ARCHIVE_DEST_STATUS;