viernes, 28 de mayo de 2021

PAGEIOLATCH_EX


He querido hacer esta entrada porque este tipo de wait es muy buscado, poco entendido y puede significar un dolor de cabeza.

El día de hoy recibimos el reporte de un cliente de que su sistema estaba sumamente lento, que la cantidad de timeouts estaba siendo insoportable y que estaba afectando seriamente la operación.

Al ingresar y visualizar la lista de sentencias que estaban en ejecución, notamos que la mayoría de ellas estaban con un wait del tipo PAGEIOLATCH_EX o del tipo PAGEIOLATCH_SH.

Primero, ¿qué diferencia existe entre un PAGEIOLATCH_XX y un PAGELATCH_XX?, es simple, el primer grupo se refiere a eventos de lectura y escritura desde el sistema de almacenamiento y el segundo se refiere a eventos de lectura y escritura sobre el buffer de datos de SQL Server.    En nuestro caso notamos que todas las esperas eran del tipo PAGEIOLATCH_XX.

Utilizando la función sys.dm_io_virtual_file_stats obtuvimos información acerca de los tiempos de espera para actividades de IO desde y hacia el sistema de almacenamiento por cada uno de los archivos de la base de datos del ERP.    El query utilizado fue el siguiente:

SELECT F.name, F.filename, FS.io_stall_read_ms / FS.num_of_reads END AS avg_read_wait_ms, FS.io_stall_write_ms / FS.num_of_writes AS avg_write_wait_ms
FROM sys.sysfiles F
CROSS APPLY sys.dm_io_virtual_file_stats(DB_ID(), F.fileid) FS


Los resultados que obtuvimos nos indicaron problemas catastróficos sobre la unidad de almacenamiento donde están ubicados los archivos de datos de la base de datos del ERP. Recordemos que el tiempo de espera ideal no debe de pasar de los 15 milisegundos.

El personal de infraestructura nos ayudó a verificar la situación actual del arreglo de discos y fue posible determinar que uno de los tres discos que formaban el RAID estaba dando muchos problemas, y es por ello que los tiempos de espera de lectura y escritura estaban por los cielos.

Se quitó el disco del arreglo y después de que pasó algún tiempo en lo que SQL terminaba de "calentar" la memoria, el rendimiento volvió a su estado óptimo.

Espero te resulte de utilidad esta información, nos vemos la siguiente.


sábado, 30 de enero de 2021

Login failed for user 'X'


Hace bastante tiempo que no venía por aquí para compartir otra entrada en relación a SQL Server o .NET. Pero en esta ocasión la situación lo amerita, debido que un cliente me pidió solucionar un problema de conexión que jamás había visto en 18 años y me gustaría compartir lo que he ido haciendo para encontrar la solución.

Problema: No te puedes conectar con el SSMS a la instancia local utilizando autenticación de SQL Server, el mensaje que devuelve al momento de conectarse es el famosísimo:

Login failed for user 'X' (Microsoft SQL Server, Error: 18456)

Si abres la ventana para obtener mayor información del error te muestra:

Server Name: .
Error Number: 18456
Severity: 14
State: 1
Line Number: 65536

Y si vas al archivo ErrorLog de la instancia te encuentras algo así:

Logon       Error: 18456, Severity: 14, State: 8.
Logon       Login failed for user 'X'. Reason: Password did not match that for the login provided. [CLIENT: <local machine>]

Antes de que comiences a pensar en lo que podría ser, te comparto la configuración verificada:
  1. Autenticación de SQL Server habilitada en la instancia y ésta ya fue reiniciada en cuanto fue aplicado el cambio.
  2. Ya se verificó que la contraseña sea correcta, inclusive estableciendo la contraseña en el login copiando su valor desde un bloc de notas.
  3. Debido a que la conexión es local, ya se verificó que el protocolo Shared Memory esté habilitado.
  4. Service Pack 4 instalado sobre la instancia (SQL Server 2012) y aplicado también en el SQL Server Management Studio.
Pruebas que ya se realizaron y su resultado:
  1. Conexión local utilizando sqlcmd y con autenticación de SQL: la conexión fue exitosa.
  2. Conexión remota con SQL Server Management Studio y autenticación de SQL: la conexión fue exitosa. 
Con todo lo anterior podemos saber que el problema no es la autenticación debido a que sí se ha podido establecer una conexión tanto local como remota con autenticación de SQL Server.    El único lugar donde está fallando la conexión es en el SSMS local, ya se intentó por ".", "localhost" y por dirección IP, y el resultado siempre es el mismo.

Para poder averiguar un poco más de lo que podría estar haciendo el SSMS al momento de intentar iniciar la conexión con autenticación de SQL Server, utilizamos el procmon de sysinternals pero nada de lo que encontramos ayudó a intentar identificar el problema.

Releí el mensaje de error que se almacena en el archivo ErrorLog de la instancia y encontré algo extraño, que está reportando que la contraseña no es correcta para el login.    Lo que me parece súper extraño por lo siguiente:
  • Si la contraseña la copio desde un bloc de notas y la pego en la línea de comandos con el sqlcmd, sí se conecta.
  • Si la contraseña la copio desde un bloc de notas y la pego en la caja de texto de contraseña del SSMS, ¡no conecta!
La siguiente prueba que se me ocurrió fue cambiarle la contraseña al login "X" y ponerle una contraseña vacía, ¿y qué crees?, ¡SÍ CONECTÓ DESDE EL SSMS!

Lo anterior me lleva a pensar que por alguna muy extraña razón (y me parece extraña porque al momento de escribir esto la desconozco) la contraseña escrita en la caja de texto de la pantalla de ingreso del SSMS, está siendo alterada de alguna manera antes de llegar a SQL Server.

Para no dejar algo de lado y sin probar, se me ocurrió hacer un programa que pidiera servidor, usuario y contraseña para conectarse, en los framework 2.0, 3.5, 4 y 4.5.   Todas las pruebas fueron exitosas.

No encontré alguna referencia del lenguaje de programación utilizado para el SSMS 2012, no sé si fue hecho en C++ o en el .NET Framework.    Pero para verificar que no solamente fuera local el problema, generé un login en otro servidor de base de datos de pruebas y que está expuesto a la internet, hice la prueba de conexión ¡y no conectó!, el error reportado en el otro servidor es el mismo: Password did not match that for the login provided.

Esto comienza a preocuparme un poco más de lo normal, primero por la incertidumbre de no saber lo que está sucediendo, y segundo porque la contraseña que escribes en la caja de texto no es la misma que le está llegando al servidor destino, ¿habrá sido comprometido el servidor?, lo revisaré más a fondo para ver si encuentro algo extraño (sí, más)

En cuanto tenga más noticias, regresaré a actualizar esta entrada.

Se realizó una revisión de componentes del sistema operativo y también se corrió una revisión completa contra malware, ambas operaciones no reportaron problemas.

Lamentablemente, no se encontró otra alternativa que reinstalar el SQL Server Management Studio y el problema dejó de ocurrir.    Y pongo "lamentablemente" porque no me deja satisfecho la solución, pero el tiempo ya se tenía encima y no había forma de seguir investigando para encontrar el problema de raíz.