Como hacer un Downgrade de SQL 2005 a SQL 2000 o de SQL 2008 a SQL 2005.
Hay muchas ocasiones en las cuales nos enfrentamos a una situacion que requiere upgradear una base de datos o bien una instancia completa de SQL.
El proceso de upgrade para una sola base de datos es bastante directo ya que solo requiere un backup del server original y un restore en el nuevo. Y por supuesto el scripteo y copia de cualquier login u objeto de servidor relacionado a esa BD.
Sin embargo esta clase de situacion involucra una serie de pruebas exhaustivas de la aplicacion que usa dicha base, y muchas veces una bateria completa de pruebas no es posible ya sea por limitaciones de tiempo o debido a alguna clase de proceso que no es regular (como ser un cierre mensual o algun proceso que corre una vez cada tanto), y muchas veces no es tan sencillo probar todo debido a la complejidad de los procesos y la informacion que requieren para hacerlo.
Teniendo en cuenta esto, la mayoria de los DBAs sabemos que la probabilidad de falla de este tipo de procesos de upgrade es muy baja, sin embargo los procedimientos existentes para la mayoria de los procesos de control de cambios requieren un plan de rollback de todo en el peor escenario.
En este caso el peor escenario seria que tenemos una base upgradeada (por ej. a SQL 2005) y los testeos iniciales fueron exitosos y todo sigue su marcha, pero en algun punto del mes la aplicacion falla debido a una incompatibilidad con la nueva version de la base e imaginemos que es aun peor, y que nos vemos obligados a hacer un rollback a la vieja version debido a una directiva de las altas gerencias de la empresa.
Como ya deben saber no se puede hacer un restore de una base de 2005 en un server de SQL 2000, asi que la unica opcion viable es realizar un export de los datos de la base 2005 e importarlos en la base 2000 en el viejo server.
Para realizar esto necesitamos seguir los siguientes pasos:
- Deshabilitar todas las constraints en la vieja base.
- Deshabilitar todos los triggers en la vieja base.
- Realizar un BCP out de todas las tablas de la nueva BD.
- Poner offline la base con version mas nueva.
- Truncar todas las tablas en la base con version vieja.
- Realizar un BCP in en las tablas de la vieja DB con la nueva data.
- Habilitar las constraints nuevamente.
- Habilitar los triggers nuevamente.
Para hacer esto se deben usar los siguientes scritps:
/**********************************************************************************************/
/* ENABLE/DISABLE FOREIGN KEYS */
/**********************************************************************************************/
DECLARE
@ExStr nVARCHAR(4000),
@tabla VARCHAR(100),
@fkname VARCHAR(100)
DECLARE @ESTADO VARCHAR (20)
SET @ESTADO = 'ENABLE' --change to DISABLE or ENABLE depending what you need to do
DECLARE fke_cur INSENSITIVE CURSOR FOR
SELECT object_name(parent_obj), name
FROM sysobjects s
where xtype in ('F')
order by object_name(parent_obj)
OPEN fke_cur
FETCH NEXT FROM fke_cur INTO @tabla,@fkname
WHILE (@@FETCH_STATUS=0)
BEGIN
IF (@ESTADO='ENABLE')
SET @ExStr= 'ALTER TABLE '+@tabla+' CHECK CONSTRAINT '+@fkname
ELSE
IF (@ESTADO='DISABLE')
SET @ExStr= 'ALTER TABLE '+@tabla+' NOCHECK CONSTRAINT '+@fkname
PRINT @ExStr;
EXECUTE sp_executesql @ExStr
FETCH NEXT FROM fke_cur INTO @tabla,@fkname
END
CLOSE fke_cur
DEALLOCATE fke_cur
/**********************************************************************************************/
/* ENABLE/DISABLE TRIGGERS */
/**********************************************************************************************/
DECLARE @ESTADO VARCHAR (20)
SET @ESTADO = 'ENABLE' -- change for DISABLE or ENABLE depending what you need to do
DECLARE cur_trigger INSENSITIVE CURSOR FOR
SELECT name
FROM sysobjects
WHERE xtype='U';
DECLARE @n_trig VARCHAR(50), @ExStr nVARCHAR(4000), @tabla VARCHAR(100);
OPEN cur_trigger;
FETCH NEXT FROM cur_trigger INTO @tabla;
WHILE (@@FETCH_STATUS=0)
BEGIN
IF (@ESTADO='ENABLE')
SET @ExStr='ALTER TABLE '+@tabla+' ENABLE TRIGGER ALL;'
ELSE
IF(@ESTADO='DISABLE')
SET @ExStr='ALTER TABLE '+@tabla+' DISABLE TRIGGER ALL;';
PRINT @ExStr;
EXECUTE sp_executesql @ExStr;
FETCH NEXT FROM cur_trigger INTO @tabla;
END;
CLOSE cur_trigger;
DEALLOCATE cur_trigger;
/* ************************************************************************
BORRA DATA DE TODAS LAS TABLAS
Nota: No use Truncate porque para usar truncate las FK
tienen que ser dropeadas no es suficiente con deshabilitarlas
************************************************************************* */
DECLARE cur_delete INSENSITIVE CURSOR FOR
SELECT name FROM sysobjects WHERE xtype='U';
DECLARE @n_trig VARCHAR(50),
@ExStr nVARCHAR(4000),
@tabla VARCHAR(100);
OPEN cur_delete;
FETCH NEXT FROM cur_delete INTO @tabla;
WHILE (@@FETCH_STATUS=0)
BEGIN
SET @ExStr='DELETE FROM '+@tabla+';';
print @ExStr
EXECUTE sp_executesql @ExStr;
FETCH NEXT FROM cur_delete INTO @tabla;
END;
CLOSE cur_delete;
DEALLOCATE cur_delete;
/* ************************************************************** */
Espero que este simple proceso los ayude a documentar apropiadamente sus cambios sobre SQL y que los ayude a completar exitosamente un downgrade en el caso que tengan que enfrentarse al mismo.
Nota: Recomiendo que tengan a mano at menos por los primeros 2 meses el ultimo backup realizado sobre la base en la vieja version (por ej. el ultimo backup de la base en SQL 2000), asi tienen el esqueleto de la BD para poder trabajar en caso de tener que hacer un downgrade.
Saludos!
MaX
Muy Bueno Max, te tiro una que me esta complicando la semana, en SQL Server 2005, los deadlocks se soluciona con SNAPSHOT??? juas help!!! Abrazo Lucas
ReplyDelete