Archivo de la Categoría SQL SERVER

En el post anterior veíamos como reparar una bbdd. Si el estado es cualquiera de los otro dos (REPAIR MODE o EMERGENCY), entonces tendremos que recurrir a otro tipo de apaños. En mi caso he experimentado el problema tras tratar de recrear un nuevo transaction log para una bbdd, pero también puede servir en casos en el que el archivo de datos este dañado.

Voy a indicar lo que hice para reproducir el problema. Separé una bbdd y borré su .LDF, luego al adjuntarla obtenía este error:

Error al adjuntar las bases de datos. Haga clic en el hipervínculo de la columna de mensajes para obtener más información.

Crearlo a mano no es muy buena idea según nos muestra el siguiente error:

The operating system returned error 38(Se ha alcanzado el final del archivo.) to SQL Server during a read at offset 0000000000000000 in file ‘C:\Archivos de programa\SWsoft\Plesk\Databases\MSDE\MSSQL\Data\sergiodb_log.ldf’. Additional messages in the SQL Server error log and system event log may provide more detail. This is a severe system-level error condition that threatens database integrity and must be corrected immediately. Complete a full database consistency check (DBCC CHECKDB). This error can be caused by many factors; for more information, see SQL Server Books Online. (Microsoft SQL Server, Error: 823)

Dado que no era posible adjuntar la bbdd, el siguiente paso fue renombrar el archivo de datos sergiodb.mdf por sergiodb_bak.mdf y crear una nueva bbdd con el nombre sergiodb. Con esto obtenemos un nuevo mdf y un ldf limpio.

El siguiente paso fue detener SQL Server y sobrescribir sergiodb.mdf por el bueno e iniciar de nuevo SQL. Con esto se produce el siguiente error al intentar por ejemplo ver las propiedades de la bbdd:

Unable to open the physical file “C:\Archivos de programa\SWsoft\Plesk\Databases\MSDE\MSSQL\Data\sergiodb.mdf”. Operating system error 5: “5(Acceso denegado.)”. (Microsoft SQL Server, Error: 5120)

Tras dar permisos NTFS al archivo de datos, el error cambiaba a:

Database ’sergiodb’ cannot be opened due to inaccessible files or insufficient memory or disk space. See the SQL Server errorlog for details. (Microsoft SQL Server, Error: 945)

Con todo esto el estado de mi BD era RECOVERY_PENDING

SELECT state_desc FROM sys.databases WHERE name =’sergiodb’;

 

SOLUCION

ALTER DATABASE sergiodb SET EMERGENCY ;– lo primero que haremos es pasar la bbdd del modo “RECOVERY_PENDING” al modo “EMERGENCY” (es necesario tener privilegio de sysadmin)

ALTER DATABASE sergiodb SET SINGLE_USER ;– La ponemos en modo de usuario único.

DBCC CHECKDB (sergiodb, REPAIR_ALLOW_DATA_LOSS )WITH NO_INFOMSGS ;– Chequeamos la bd con la opción REPAIR_ALLOW_DATA_LOSS

ALTER DATABASE sergiodb SET MULTI_USER ;– Por ultimo la ponemos en modo multiusuario

Ahora debería estar en modo ONLINE y funcionando.

Debido a múltiples circunstancias como cortes eléctricos inesperados, problemas de espacio en disco, fallos de hardware, que hayas borrado el archivo de log (.ldf), etc. Una bbdd puede corromperse, normalmente la mejor manera de solucionar esto es recurrir a la última copia de seguridad pero como puede ocurrir en estos casos no hay copia o la que tenemos disponible es ya algo vieja. En esos casos quizá aún podamos recuperar la información.

Una bbdd puede tener estos estados (LINK):

  • ONLINE: La base de datos está disponible para su acceso. El grupo de archivos principal está en línea, aunque la fase de deshacer de la recuperación puede no haberse completado.
  • OFFLINE: La base de datos no está disponible. Una base de datos pasa a estar sin conexión por la acción explícita del usuario y permanece sin conexión hasta que el usuario toma otra acción. Por ejemplo, la base de datos puede desconectarse para mover un archivo a un nuevo disco. La base de datos se vuelve a poner en línea una vez completado el traslado.
  • RESTORING: Uno o varios archivos del grupo de archivos principal se está restaurando, o uno o varios archivos secundarios se están restaurando sin conexión. La base de datos no está disponible.
  • RECOVERING: Se está recuperando la base de datos. El proceso de recuperación es un estado transitorio, la base de datos se pone automáticamente en línea si la recuperación tiene éxito. Si la recuperación no tiene éxito, la base de datos pasa a ser sospechosa. La base de datos no está disponible.
  • RECOVERY PENDING: SQL Server ha encontrado un error relacionado con un recurso durante la recuperación. La base de datos no está dañada pero pueden faltar archivos o bien limitaciones de recursos del sistema pueden estar impidiendo que se inicie. La base de datos no está disponible. Se necesita una acción adicional por parte del usuario para resolver el error y permitir que se complete el proceso de recuperación.
  • SUSPECT: Como mínimo un grupo de archivos principal es sospechoso y puede estar dañado. La base de datos no se puede recuperar durante el inicio de SQL Server. La base de datos no está disponible. Se requiere una acción adicional por parte del usuario para resolver el problema.
  • EMERGENCY: El usuario ha cambiado la base de datos y ha establecido el estado en EMERGENCY. La base de datos está en modo de usuario único y se puede reparar o restaurar. La base de datos está marcada como READ_ONLY, el registro está deshabilitado y el acceso está limitado a miembros de la función fija de servidor sysadmin. EMERGENCY se utiliza principalmente para solucionar problemas. Por ejemplo, una base de datos marcada como sospechosa se puede establecer en el estado EMERGENCY. Esto puede permitir al administrador del sistema acceso de sólo lectura a la base de datos. Sólo los miembros de la función fija de servidor sysadmin pueden establecer una base de datos en el estado EMERGENCY.

     

Cuando se corrompe la tendremos seguramente en Online, Recovery pending o Suspect.

Puedes ver el estado de la BD utilizando esta consulta (sustituye sergiodb por la bbdd a consultar):

SELECT state_desc FROM sys.databases WHERE name = 'sergiodb';

Si la bbdd está en estado ONLINE, lo más fácil es intentar un checkdb con la opción REPAIR_ALLOW_DATA_LOSS.

DBCC CHECKDB (MAGIC, REPAIR_ALLOW_DATA_LOSS)WITH NO_INFOMSGS

Más info en http://technet.microsoft.com/es-es/library/ms188422.aspx

Mañana publicaré como reparar si la bbdd se encuentra en alguno de los otros 2 modos o no se puede adjuntar.

El Transaction Log de SQL server es uno de los quebraderos de cabeza para muchos administradores noveles que no cuentan con un buen plan de mantenimiento o no conocen a fondo el funcionamiento de SQL como para reducirlo a mano. En este post trataré de explicar y dar algunas soluciones rápidas para evitar el aburrimiento. A quien quiera información más detallada le recomiendo los Libros en Pantalla de SQL o Googlear un poco que nunca está de más ;).

¿Qué es el Transaction Log?

Por cada bbdd (archivo .mdf) se crea un archivo de log (archivo .ldf) en el que se almacenan todos los cambios que se producen en la bbdd. En él se van guardando cambios que luego permitirán volver atrás (rollback) en una transacción o incluso hacer una recuperación a un estado anterior.

¿Por qué puede ocupar mucho más que la propia bbdd?

Cuando se ejecutan muchas consultas y/o afectan a un gran número de registros, produciendo cambios en la bbdd. Todos los cambios se van almacenando en el transaction log, si además no tenemos un plan de mantenimiento que reduzca este log de forma periódica el .ldf se irá llenando hasta ocupar una gran cantidad de espacio y terminará por llenar el disco.

¿Cómo se reduce el log de transacciones?

Existen varias maneras, la forma más recomendable es utilizando un plan de mantenimiento que realice una copia de seguridad del registro de transacciones. A continuación vamos a ver algunos ejemplos y posibilidades:

  • Backup log: Guardamos un backup y luego reducimos el log de la bbdd “sergiodb” a 10 Mb

USE [sergiodb] – Utilizamos la bbdd sergiodb
CHECKPOINT – Para que todas las páginas de memoria se escriban en la bd

GO

EXEC sp_addumpdevice ‘disk’ ,‘CopiaMiBase_sergiodb’ ,‘c:\LogMiBase_sergiodb.bak’ – Creamos un punto donde guardaremos el log y procedemos a hacer el backup con truncado del log

BACKUP DATABASE sergiodb TO CopiaMiBase_sergiodb
BACKUP LOG pruebamm WITH TRUNCATE_ONLY
DBCC SHRINKFILE (’sergiodb_log’, 10) –- Dejamos el archivo de log con un tamaño de 10 Mb
  • Reducir sin hacer backup:

USE [sergiodb] – Utilizamos la bbdd sergiodb
CHECKPOINT – Para que todas las páginas de memoria se escriban en la bd
GO
BACKUP
LOG sergiodb WITH TRUNCATE_ONLY
– Truncamos el registro
DBCC SHRINKFILE (sergiodb _Log, 10) – Lo reducimos a 10 Mb

  • Eliminar el archivo de log para que se genere de nuevo: Esta solución es más arriesgada, aunque a veces es necesario tirar de ella por ejemplo cuando el log es tan grande que el servidor no tiene espacio o memoria como para gestionarlo.

ALTER DATABASE [sergiodb] SET SINGLE_USER; – Ponemos la bbdd en single user
GO
sp_detach_db ’sergiodb’ – Separamos la bbdd

Ahora es necesario localizar el archivo de log, en mi caso C:\Archivos de programa\SWsoft\Plesk\Databases\MSDE\MSSQL\Data\sergiodb_log.ldf y eliminarlo. Luego ejecutamos esta nueva consulta para adjuntarla de nuevo.

USE [master]
CREATE</SPANDATABASE [sergiodb] ONFILENAME=(‘C:\Archivos de programa\SWsoft\Plesk\Databases\MSDE\MSSQL\Data\sergiodb.mdf’),
(FILENAME=‘C:\Archivos de programa\SWsoft\Plesk\Databases\MSDE\MSSQL\Data\sergiodb_log.LDF’)
FOR ATTACH
ALTER DATABASE sergiodb SET MULTI_USER; – Ponemos la bbdd en multi user

Cuando se instala SQL Server, este se configura teniendo en cuenta las interfaces habilitada en ese momento. Pero si más tarde habilitamos una nueva interfaz o la deshabilitamos esta no aparece/desaparece de la configuración de red.


La forma que he encontrado para hacer esto es editando el registro, toda la información se guarda en:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.1\MSSQLServer\SuperSocketNetLib\Tcp\]

Por tanto una forma de quitar una IP es borrar su registro y para añadirla lo que yo hago es exportar una clave ya existente y editarla como deseo antes de ejecutar el .reg para que inserte los cambios.

Muchos programadores dejan abiertas (en Sleeping) todas las consultas que abren contra una bbdd sin ser conscientes de la carga que provocan al servidor y sólo se preocupan cuando se excede el límite de conexiones y se deniega el servicio.

En muchos casos como este, puede ser útil proporcionar al programador permisos para poder ver el Monitor de Actividad de SQL Server y así controlar cuantas querys quedan abiertas de forma innecesaria. Para dar permisos al usuario “sergiosainz” basta con ejecutar la siguiente sentencia:

use master

GRANT VIEW SERVER STATE TO sergiosainz

SELECT TOP 10
qs.execution_count,
SUBSTRING(qt.text,qs.statement_start_offset/2,
(case when qs.statement_end_offset = -1
then len(convert(nvarchar(max), qt.text)) * 2
else qs.statement_end_offset end -qs.statement_start_offset)/2)
as query_text,
qt.dbid, dbname=db_name(qt.dbid),
qt.objectid
FROM sys.dm_exec_query_stats qs
cross apply sys.dm_exec_sql_text(qs.sql_handle) as qt
ORDER BY
qs.execution_count DESC

SELECT TOP 10
qs.total_worker_time/qs.execution_count as [Avg CPU Time],
SUBSTRING(qt.text,qs.statement_start_offset/2,
(case when qs.statement_end_offset = -1
then len(convert(nvarchar(max), qt.text)) * 2
else qs.statement_end_offset end -qs.statement_start_offset)/2)
as query_text,
qt.dbid, dbname=db_name(qt.dbid),
qt.objectid
FROM sys.dm_exec_query_stats qs
cross apply sys.dm_exec_sql_text(qs.sql_handle) as qt
ORDER BY
[Avg CPU Time] DESC

Ciertas operaciones requieren acceso exclusivo a la bbdd por lo que si hay conexiones abiertas contra ella obtenemos un error como este:

Mens. 5030, Nivel 16, Estado 2, Línea 1
No se puede bloquear de forma exclusiva la base de datos para realizar la operación.

Debemos ir a las propiedades de la BBDD > Opciones > Estado > Restringir acceso y seleccionamos single.

También se puede ejecutar la consulta:

ALTER DATABASE [nombre_bd] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO

Ahora se pueden hacer los cambios necesarios.

Para volver al modo de multiples usuarios hay que matar la conexión y cambiar el modo, se puede hacer fácilmente con esta consulta:

Kill [spid]

ALTER DATABASE [nombre_bd] SET MULTI_USER

Quien se haya encontrado con un Sql Server recién instalado posiblemente se habrá visto en la situación de que necesita conectar a él desde otro equipo remoto.

En primer lugar si el equipo cliente no tiene las herramientas de cliente para SQL Server, puedes descargar la versión gratuita del administrador de SQL;
Microsoft SQL Server Management Studio Express .

Mejor aún, si lo deseas puedes descargar el Kit de Herramientas de Sql Server Express 2005, este Kit además del administrador de SQL, incluye una herramienta gráfica de administración, y Business Intelligence Development Studio, un entorno de creación y edición de informes que usa SQL Server Reporting Services.

Configurando el servidor

1- Vamos a la utilidad Configuración de superficie de SQL Server 2005 (Surface Area Configuration Utility) > Configuración de superficie para servicios y conexiones > conexiones remotas > Conexiones locales y remotas > Usar TCP/IP y canalizaciones con nombre.

Surface Area Configuration Utility

2- Vamos a SQL Configuration Manager > Configuración de red de SQLEXPRESS y habilitamos las conexiones TCP/IP y las canalizaciones con nombre.

SQL Configuration Manager

3- Seguimos en el SQL Configuration Manager > Protocolos de SQL Express > TCP/IP y en las propiedades Direcciones IP > IPALL > Puerto TCP > poner el 1433 (o el puerto que desees habilitar para SQL)

SQL Configuration Manager 2

4- Crear una excepción en el FW para C:\Archivos de programa\Microsoft SQL Server\MSSQL.1\MSSQL\Binn\sqlsrvr.exe

Y abrir los puertos 1434 (UDP) y 1433 (TCP)

5- Finalmente hay que reiniciar el servicio de SQL para que se apliquen los cambios y ya estamos listos para probar la conexión desde nuestro equipo cliente.