Script para listar permisos

Esto no es algo nuevo, en realidad tengo mucho tiempo de tener este codigo. Y otras veces me fue super util. Hoy de hecho me funciono en el trabajo cuando necesitaba replicar permisos de una base de datos que tuvimos que cambiar de un servidor a otros.

SELECT 
		[Permisos] = state_desc 
			+ ' ' + permission_name 
			+ ' on [' + c.name
			+ '].[' + b.name 
			+ '] to [' + ar.name 
			+ ']' COLLATE latin1_general_ci_as
FROM 
	sys.database_permissions AS a
	INNER JOIN sys.objects AS b 
		ON a.major_id = b.object_id
	INNER JOIN sys.schemas AS c 
		ON b.schema_id = c.schema_id
	INNER JOIN sys.database_principals AS ar 
		ON a.grantee_principal_id = ar.principal_id
UNION
SELECT 
		[Permisos] = state_desc 
			+ ' ' + permission_name 
			+ ' on Schema::['+ c.name 
			+ '] to [' + ar.name 
			+ ']' COLLATE latin1_general_ci_as
FROM 
	sys.database_permissions AS a
	INNER JOIN sys.schemas AS c 
		ON a.major_id = c.schema_id AND a.class_desc = 'Schema'
	INNER JOIN sys.database_principals AS ar 
		ON a.grantee_principal_id = ar.principal_id
		

Automatic Index Tuning in SQL Server Using the Missing Index Dynamic Management Views

Este es un artículo de lo más interesante. Talvez no sea lo que uno quisiera hacer en sus ambientes. Pero en casos en los que no podes mejorar el rendimiento de las consultas por no tener acceso a la maquina

Avatar de jmdorityJustin M. Dority on Development

In many cases, a DBA may not have access to your deployed databases (if they are deployed to customer sites), may not be able to predict which indexes will help most in ad-hoc reporting databases, or simply may not have the time to hand-tune indexes on all of your databases. To help DBAs with tuning indexes, the missing index Dynamic Management Views (DMVs) were introduced in SQL Server 2005, but they only provide suggestions, there is no built-in facility to automate index tuning. However, with a small T-SQL script, you can put some of your databases on autopilot, and hopefully provide a better experience for your users.

Once again, there is no replacement for an experienced DBA with knowledge of your data and usage patterns performing tuning, but if you don’t have a DBA available for your database, just want a little guidance in which indexes are needed, or you…

Ver la entrada original 383 palabras más

Cual job se esta ejecutando???

Hoy ocupaba una consulta rápida para una validación, y la verdad buscando en red me encontré un código rápido y bastante útil para encontrar los jobs o tareas programadas en ejecución, el original esta en esta pagina (http://www.sanssql.com/2013/08/t-sql-query-to-find-currently-running.html), la verdad lo único que modifique fueron las etiquetas. No es postear por postear, la verdad si me fue bastante útil en lo que ocupaba, tal ves lo sea para alguien mas

SELECT
    J.name AS 'Nombre del Job',
    ja.start_execution_date AS 'Inicio a las:',
    DATEDIFF(ss, ja.start_execution_date, GETDATE()) AS 'Ha corrido por: (Segundos)'
FROM msdb.dbo.sysjobactivity ja
     INNER JOIN msdb.dbo.sysjobs J ON J.job_id=ja.job_id
WHERE job_history_id IS NULL AND ja.start_execution_date IS NOT NULL
ORDER BY start_execution_date;

Este otro da un poco mas de info

SELECT
	J.name AS 'Nombre del Job',
	ja.start_execution_date AS 'Inicio a las:',
	DATEDIFF(ss, ja.start_execution_date, GETDATE()) AS 'Ha corrido por: (Segundos)'
FROM msdb.dbo.sysjobactivity ja
	 INNER JOIN msdb.dbo.sysjobs J ON J.job_id=ja.job_id
WHERE job_history_id IS NULL AND ja.start_execution_date IS NOT NULL
ORDER BY start_execution_date;Otra version un poco mas de detalle


SELECT 
    [sj].[job_id] AS [ID]
    , [sj].[name] AS [Nombre]
    , CASE 
        WHEN [jh].[run_date] IS NULL OR [jh].[run_time] IS NULL THEN NULL
        ELSE CAST(
                CAST([jh].[run_date] AS CHAR(8))
                + ' ' 
                + STUFF(
                    STUFF(RIGHT('000000' + CAST([jh].[run_time] AS VARCHAR(6)),  6), 3, 0, ':'), 6, 0, ':')
                AS DATETIME)
      END AS [UltimaFechaEjecucion]
    , CASE [jh].[run_status]
        WHEN 0 THEN 'Fallido'
        WHEN 1 THEN 'Completado'
        WHEN 2 THEN 'Reintento'
        WHEN 3 THEN 'Cancelado'
        WHEN 4 THEN 'Ejecutando' -- In Progress
      END AS [EstadoUltimaEjecucion]
    , STUFF(STUFF(RIGHT('000000' + CAST([jh].[run_duration] AS VARCHAR(6)),  6), 3, 0, ':'), 6, 0, ':') 
        AS [DuracionUltimaEjecucion(HH:MM:SS)]
    , [jh].[message] AS [EstadoDeLaUltimaEjecucion]
    , [jh].[last_executed_step_id] [IDUltimoPasoEjecutado]
    , [jh].[last_executed_step] [UltimoPasoEjecutado]
	, CASE [sJOBSCH].[NextRunDate]
        WHEN 0 THEN NULL
        ELSE CAST(
                CAST([sJOBSCH].[NextRunDate] AS CHAR(8))
                + ' ' 
                + STUFF(STUFF(RIGHT('000000' + CAST([sJOBSCH].[NextRunTime] AS VARCHAR(6)),  6), 3, 0, ':'), 6, 0, ':') AS DATETIME)
      END AS [FechaProximaEjecucion]
FROM 
    [msdb].[dbo].[sysjobs] AS [sj]
    LEFT JOIN (
                SELECT
                    [job_id]
                    , MIN([next_run_date]) AS [NextRunDate]
                    , MIN([next_run_time]) AS [NextRunTime]
                FROM [msdb].[dbo].[sysjobschedules]
                GROUP BY [job_id]
            ) AS [sJOBSCH]
        ON [sj].[job_id] = [sJOBSCH].[job_id]
    LEFT JOIN (
                SELECT 
                    [sjh].[job_id]
                    , [sjh].[run_date]
                    , [sjh].[run_time]
                    , [sjh].[run_status]
                    , [sjh].[run_duration]
                    , [sjh].[message]
                    , ROW_NUMBER() OVER (
                                            PARTITION BY sjh.[job_id] 
                                            ORDER BY [sjh].[run_date] DESC, [sjh].[run_time] DESC
                      ) AS RowNumber
					, [sja].[last_executed_step_id]
					, [sjs].[step_name] [last_executed_step]
					, [sja].[last_executed_step_date]
                FROM [msdb].[dbo].[sysjobhistory] sjh
					LEFT OUTER JOIN [msdb].[dbo].[sysjobactivity] sja ON sja.job_id = sjh.job_id
					LEFT OUTER JOIN [msdb].[dbo].[sysjobsteps] sjs ON sjs.job_id = sja.job_id AND sjs.step_id = sja.last_executed_step_id
                WHERE sjh.[step_id] = 0
            ) AS [jh]
        ON [sj].[job_id] = [jh].[job_id]
        AND [jh].[RowNumber] = 1
ORDER BY [Nombre]

Como medir el progreso del rollback de una transaccion

Muchas veces nos encontramos con casos de consultas (queries) que estan modificando datos por largos periodos de tiempo y honestamente lo ultimo que quiero hacer en esos momentos es terminar el proceso; si se da el caso que el Log de la base de datos se lleno es preferible crear un log temporal en otra unidad y esperar a que la transacción termine por si misma. Pero si se da el caso que no podemos esperar y hay que terminar o matar la transacción ya tenemos a nuestro jefe o cliente presionando por ello, siempre es util saber cual es el % del progreso del rollback, para ello utilizamos el mismo comando KILL <SPID> WITH STATUSONLY, este comando nos dara un estimado del porcentaje.

Para reproducir, generar un ciclo de inserción en cualquier tabla, en este ejemplo insertamos texto infinitamente:


CREATE TABLE tprueba
(
id    INT NOT NULL IDENTITY(1, 1),
texto VARCHAR(15),
CONSTRAINT pk_tprueba PRIMARY KEY (id)
)

WHILE EXISTS(SELECT 1
FROM   sys.tables
WHERE  name = 'Tprueba')
BEGIN
INSERT INTO tprueba
VALUES      (' Es Una Prueba ')
END

Una vez que tengamos el código en ejecución procedamos a matar o terminar la transacción que recien iniciamos


KILL <SPID>

Una vez en estado rollback ejecutamos la misma instrucción de KILL con el parámetro [statusonly]

KILL <spid> WITH statusonly


Errores comunes al comprimir archivo de una base de datos MSSQL

Personalmente, creo que como DBA el hecho de borrar datos es algo de por si malo, pero en algunas ocasiones hay que borrar información de manera masiva ya que son parte de los históricos de una base de datos muy grandes. En mi experiencia el borrado de datos se asocia a bases de datos que ocupan varios TB de disco duro.
Comprimir mi base de datos va a generar ciertos problemas como fragmentación de mis índices; con el tiempo he encontrado dos errores frecuentes cuando trato de comprimir archivos de base de datos utilizando el DBCC SHRINKFILE:

  1. Could not adjust the space allocation for file ‘<file name>’. Este error esta bien documentado en muchos foros, la solucion mas sencilla es modificar el tamaño del archivo que estamos comprimiendo, se le asignan unos cuantos mega bytes mas de su tamaño actual y listo.
  2. [Cannot use the PAGE granularity hint on the table «<table name>» because locking at the specified granularity is inhibited.], en este caso tenemos que analizar la tabla que nos esta generando el problema, habitualmente esta asociado a tablas sin un primary key o sin un indice clustered. En dado caso tenemos dos opciones:
  • Defragmentar los indices de la tabla cuando existe un clustered.
  • Crear un primary key para la tabla que nos genera el problema.

Espero les sea util

Contador Page life Expectancy

Ultimamente hemos observado uno que otro problema de memoria y hemos utilizado ese contador de MSSQL, que en castellano podria ser algo asi posible duracion de la pagina en memoria. Algunas veces ni siquiera traduzco los terminos tecnicos y creo que la mayoria lo hacemos de igual manera. Ahora bien este contador es mas menos eso; me indica que tanto va a estar alojada una pagina en memoria sin referencia alguna.

Microsoft hace referencia a que un PLE de 300 es un buen numero, el problema de este dato es que ese calculo nunca se actualizo cuando fue mejorando el hardware; por lo que ese numero puede ser bueno en equipos pequeños pero en máquinas poderosas puede estar muy lejos de la realidad.

Mi recomendación es mirar este contador con lupa y ver si de alguna manera podría tener problemas de memoria sin darse cuenta.

La siguiente consulta lista los numeros del PLE

SELECT  @@servername AS Instancia ,
        [object_name] Objeto ,
        [counter_name] Contador ,
        [cntr_value] AS PLE_SEGUNDOS ,
        [cntr_value] / 60 AS PLE_MINUTOS ,
        [cntr_value] / 3600 AS PLE_HORAS
FROM    sys.dm_os_performance_counters
WHERE   [object_name] LIKE '%Manager%'
        AND [counter_name] = 'Page life expectancy' 

Leyendo varios foros encontré una formula que utilizan muchos de los MVPs de SQL Server para determinar un PLE apropiado para cada equipo:

PLE Recomendado = (Tamaño en GB del Datos en Cache/4GB *300) en ingles por aquello de la traduccion: (DataCacheSizeInGB/4GB*300), como lo dice don Jonathan Kehayias

Este query trae un valor bastante cercano a lo que deberíamos esperar o buscar en realidad:

DECLARE @PLE DECIMAL

SELECT @PLE = ( ( ( bpool_committed * 8 ) / ( 1024 * 1024 ) ) / 4 ) * 300
FROM   sys . dm_os_sys_info

SELECT 'Recommended PLE' = CASE
WHEN @PLE &lt; 300 THEN 300
ELSE @PLE
END

Como renombrar una instancia de SQL

Esto es algo que realmente que uso poco, pero ciertamente me ha sido bastante util en ambientes de pruebas cuando el nombre de maquina difiere del nombre de instancia y por alguna razon en particular ocupo que sean el mismo.

Antes de renombrar tenemos que descartar lo siguiente:

  1. No usamos replicacion
  2. No existen logins de acceso remoto

El codigo de la siguiente seccion nos permitira validar estas dos condiciones:

DECLARE @txt VARCHAR(512)

SET @txt = ''

IF EXISTS(
SELECT *
FROM sys.databases
where is_published = 1 or is_subscribed =1 or is_distributor = 1
)
BEGIN
SET @txt = 'No se podra renombrar por el momento, Existe Replicacion'
END

IF EXISTS(
select *
from sys.remote_logins a
INNER JOIN sys.sysservers b on b.srvid = a.server_id
)
BEGIN
IF(@txt = '')
BEGIN
SET @txt = 'No se podra renombrar por el momento, existen [Remote Logins]'
END
ELSE
BEGIN
SET @txt = '
No se podra renombrar por el momento, existen [Remote Logins]'
END
END

IF @txt = ''
BEGIN
SET @txt = 'No existen problemas para ejecutar el sp_dropserver'
END
Print @txt

A continuacion lo que hay que hacer es buscar el nombre actual de la maquina. Lo que siempre hago es buscarlo abriendo una ventana del command prompt, y utilizando el comando hostname.

Solo quedaria correr el sp_dropserver y el sp_addserver

<span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>
DECLARE @oldname sysname
DECLARE @newname sysname

SET @oldname = 'server'
SET @newname = 'newserver'

EXEC sp_dropserver
@server = @oldname
--nombre de la instancia, tipo sysname, no acepta espacios
--@droplogins = ''
--Permite Remover los Remote Logins de la insntancia

EXEC sp_addserver
@server = @newname
--nombre de la instancia, tipo sysname, no acepta espacios
,@local = local
--indica si la insntacia es local, varchar(1)
--Cuando se asigna LOCAL le indica al SQL que el nombre
--de instacia es lo que le enviamos a @server
--,@duplicate_ok =
--Permite nombres de instancia duplicados
--Solo tiene to valores posibles duplicate_OK o NULL
--Nunca lo he usado
GO

Nota: en caso de renombrar una instancia nombrada, cambiamos el los valores
@oldname y @newname incluyendo el nombre de la maquina y el de la instancia de la siguiente manera:

SET @oldname = 'server\instance'
SET @newname = 'server\newinstance'

El nombre del servidor tambien puede cambiarse

Fuente:
MS Drop Server
MS addServer

Como encontrar corrupcion en mi base de datos?

Muchas veces hacemos uso frecuente del CHECKDB como herrarmienta de verificacion de la base de datos cuando lo que tratamos de encontrar es corrupcion.

A partir de SQL Server 2005 microsoft puso a nuestra disposicion una tabla en la MSBD que nos indica que paginas estan en un estado «sospechoso» (la traduccion del ingles suspect). El motor de base de datos inserta datos en esta tabla cuando encuentra errores al leer una pagina de datos en particular.

  • Error 823: una prueba cíclica de redundancia (CRC) generada por el sistema operativo, por ejemplo un error de disco (ciertos errores de hardware)
  • Error 824: generalmente indica errores logicos

La informacion que se registra en esta tabla se guarda durante las siguientes operaciones:

  • Lectura rutinaria durante cualquier query (consulta)
  • Respaldo de base de datos (backup restore)
  • Operaciones de reparacion de base de datos (CHECKDB)

Es importante saber cuales son los tipos de eventos listados (event_type) dentro de la tabla:

Valor event_type Descripción del error
1 Error 823 error de CRC del sistema operativo, o error 824 que no sea una suma de comprobación (checksum) no válida o una página con informacion incierta (por ejemplo, un Id. de página no válido)
2 Suma de comprobación errónea (checksum en Ingles)
3 Página rasgada (informacion incierta o Torn page en ingles)
4 Restaurada (la página se restauró después de marcarse como errónea)
5 Reparada (DBCC reparó la página)
7 Desasignada por DBCC

Para mi la autoridad en estos temas es Paul Randall, considero que los videos disponibles en este vinculo son de la informacion mas informativa disponible en linea.

Una consulta útil para buscar información en msdb..suspect_pages

SELECT 
    DB_NAME(database_id),
    [file_id],
    page_id,
    event_type,
    CASE event_type
        WHEN 1 THEN '823 or 824 or Torn Page'
        WHEN 2 THEN 'Bad Checksum'
        WHEN 3 THEN 'Torn Page'
        WHEN 4 THEN 'Restored'
        WHEN 5 THEN 'Repaired (DBCC)'
        WHEN 7 THEN 'Deallocated (DBCC)'
    END,
    error_count,
    last_update_date
FROM msdb..suspect_pages 

Una nota importante es que la información en esta pagina se actualiza; los eventos 4, 5 y 7 son de eventos que han sido actualizados y corregidos.

Esta tabla no se limpia automáticamente por lo que una vez solucionado el problema deberíamos de borrar los datos que contenga

Opciones Ahorro de Energia; resulta que ahora Windows es ecologico

No se que tanta gente habra notado el hecho de que Microsoft nos hizo un Windows ecologico para trabajar con nuestros servidores; pues si las opciones de ahorro de energia son parte de la configuracion de nuestros servidores. Esta opcion no es del todo mala; se reduce el consumo de energia; pero debemos analizar un poco mas si queremos mantenerla en nuestros equipos cuya funcionalidad sea para aplicaciones con alto flujo de datos o bien con accesos muy frecuentes; windows automaticamente saldra del modo de ahorro de energia cuando el uso de procesador o memoria sea mayor al 45% por mas de un minuto; pero ese simple minuto puede ocacionarnos quejas de nuestros jefes.

Revisar las opciones de energia es algo que nos puede ayudar a evitar llamadas a media noche del gerente o bien quejas de nuestros clientes 😀

Esta opcion esta disponible a partir de Windows Server 2008

ahorroEnergia