SQL Server

Aquí encontraras todos nuestros post relacionados con SQL Server desde cero hasta un nivel avanzado. Desde infraestructura hasta modelado de datos.

Page Split: el invitado indeseado en SQL Server

Hay conceptos en SQL Server que son como ese compañero de trabajo que nadie ha invitado a la reunión pero que aparece, opina y encima se queda a tomar café. Los Page Split son ese compañero. Y lo peor de todo es que, en muchos casos, somos nosotros los que, sin querer, les abrimos la puerta. En este artículo vamos a diseccionar qué son, por qué ocurren, cómo detectarlos y, sobre todo, cómo podemos hacerles la vida difícil para que molesten lo menos posible.

Qué demonios es un Page Split

Cuando hablamos de Page Split en SQL Server nos referimos a un fenómeno que ocurre cuando el motor de base de datos necesita insertar un registro en una página de datos (o de índice) que ya está llena. Como SQL Server trabaja con páginas de 8 KB (sí, esa unidad tan entrañable que nos acompaña desde hace décadas), llega un momento en el que no hay espacio para ese nuevo registro. Entonces, el motor se ve obligado a dividir la página en dos: mueve aproximadamente la mitad de las filas a una nueva página y deja espacio en la original para la nueva inserción. Esto es el famoso Page Split.

Hasta aquí podría parecer un mecanismo inteligente y útil. Y lo es, en teoría. El problema es el impacto que tiene: incremento del número de páginas (y por tanto del tamaño del índice), fragmentación lógica, más operaciones de I/O, y un rendimiento que empieza a cojear como un servidor sin mantenimiento en una década.

Cuándo y por qué ocurre el Page Split

La causa principal de un Page Split es el uso de claves que no son secuenciales en índices clustered o nonclustered. Insertar valores intermedios en el orden lógico del índice fuerza al motor a abrir hueco donde no lo hay. Por ejemplo, si tenemos un índice clustered sobre un campo Nombre y estamos insertando valores aleatorios, SQL Server tendrá que hacer malabarismos para mantener el orden lógico.

Claro, alguno podría pensar: “Esto con un índice clustered en una clave IDENTITY no pasa”. Efectivamente, las claves secuenciales como IDENTITY, NEWSEQUENTIALID() o datetime en inserciones crecientes suelen evitar la mayoría de los Page Split. Pero ojo: incluso con claves secuenciales, si empezamos a hacer updates que ensanchan las filas más de lo que la página puede aguantar, también podemos provocar splits. Porque sí, los Page Split no son sólo cosa de INSERT, también los UPDATE pueden invitar al desastre si agrandan las filas.

Cómo afectan al rendimiento (y al ánimo del DBA)

Los Page Split producen fragmentación interna y externa. Interna porque dejan huecos en las páginas; externa porque el orden lógico del índice ya no se corresponde con el orden físico. Esto se traduce en más lecturas para recuperar los datos, más uso del log de transacciones y, en general, más I/O. Y todos sabemos que el disco es, casi siempre, el cuello de botella por donde mueren los sueños de un servidor bien optimizado.

Por si fuera poco, cada Page Split genera actividad en el log de transacciones: hay que registrar la creación de la nueva página, el movimiento de filas y la actualización de punteros. Si tenemos una base de datos en modo FULL, el crecimiento del log puede ser un espectáculo digno de verse (si uno disfruta con los desastres).

Cómo detectar Page Split

Como sabes, lo que no se mide no se puede optimizar, lo bueno es que detectar los Page Split no es complicado si sabemos dónde mirar. Un sitio clásico es el contador de rendimiento SQLServer:Access Methods – Page Splits/sec. Si ese contador empieza a dar cifras escandalosas, es momento de investigar.

Otra opción es recurrir a las DMV. La vista sys.dm_db_index_physical_stats nos permitirá ver el grado de fragmentación de los índices. Un índice muy fragmentado suele ser un buen candidato a tener Page Split en su historial reciente. Y si queremos verlos en tiempo real, un Extended Event como page_split o sqlserver.page_split, según versión, nos dará información jugosa sobre cuándo y dónde están ocurriendo.

Sí, podemos hacerlo también con Profiler, pero sinceramente, a estas alturas quien siga usando Profiler en producción para esto se merece un Page Split en su jornada laboral.

Cómo prevenir los Page Split

Es mejor prevenir que curar, siempre. La primera y más efectiva estrategia es diseñar bien las claves de los índices. Un índice clustered sobre un campo secuencial es nuestro mejor amigo. Esto evita la mayor parte de los Page Split derivados de inserciones.

Otra técnica clásica es jugar con el FILLFACTOR. Cuando creamos o reconstruimos un índice podemos indicar un valor de Fillfactor que deje un porcentaje de espacio libre en las páginas (por ejemplo, un 90% en vez del 100% por defecto). Esto da margen a que nuevas inserciones se acomoden sin provocar un split inmediato. Claro, no es gratis: el índice ocupará más espacio y necesitaremos más memoria y más I/O. Pero al menos los splits no nos atacarán a traición.

Eso sí, cuidado con el Fillfactor. Poner un Fillfactor bajo indiscriminadamente es como invitar al primo gorron a casa: puede aliviar al principio pero al final nos pasa factura. Hay que medir, probar y ajustar.

Y no olvidemos las operaciones de mantenimiento: reconstruir o reorganizar los índices periódicamente ayuda a reducir la fragmentación causada por los Page Split. Aquí no vamos a descubrir nada nuevo, pero sí recordar lo evidente: el mantenimiento es como lavarse los dientes; si no lo haces, el problema llegará y será feo.

Casos reales y conclusiones claras

En entornos OLTP con claves no secuenciales he llegado a ver índices con más del 70% de fragmentación en menos de una hora de actividad. La consecuencia era un aumento de I/O y un rendimiento que hacía llorar al más curtido. ¿La solución? Cambio de diseño de clave, ajuste del Fillfactor y un plan de mantenimiento digno.

En entornos con cargas masivas de datos desordenados, lo ideal es insertar en tablas heap (sin clustered) y luego aplicar el índice clustered al finalizar, o bien usar particiones y cargas ordenadas. Porque sí, hay vida más allá de pelearse con Page Split en cada carga.

En definitiva, los Page Split son inevitables en determinados escenarios, pero podemos hacer mucho para mantenerlos a raya. El diseño de los índices, el Fillfactor y un mantenimiento adecuado son nuestras principales armas. Y no, el truco no está en hacer rebuilds cada noche a lo loco; está en entender el porqué y el cuándo, y actuar con cabeza.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de LinkedIn y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

Publicado por Roberto Carrancio en Cloud, Rendimiento, SQL Server, 0 comentarios

El problema del Reenvío de punteros en tablas heap

Hoy vamos a hablar de un fenómeno tan molesto como habitual en ciertos entornos: el reenvío de punteros en tablas heap de SQL Server. Sí, ese “detalle” que suele pasar desapercibido hasta que un día nuestras consultas empiezan a ir como un carro tirado por burros, y claro, toca ponerse el traje de bombero.

Antes de entrar en harina, pongamos un poco de contexto. Las tablas heap, esas nobles estructuras sin índice clustered, a veces se eligen por necesidad, otras por ignorancia y, en los peores casos, porque alguien tenía prisa por entregar y pensó que ya lo arreglaríamos después.Y claro, luego nunca se arregla. Y mientras tanto, los forwarded records o reenvíos de punteros campan a sus anchas.

¿Qué es un reenvío de punteros y por qué debería importarnos?

Cuando una tabla no tiene índice clustered, SQL Server guarda las filas donde buenamente puede. Sin ese ordenamiento y estructura que un clustered impone, el heap es un campo abierto. Hasta aquí, todo bien. El problema aparece cuando actualizamos una fila y esa nueva versión no cabe en la misma página. ¿Qué hace SQL Server? ¿Mover toda la fila a otra página y actualizar los punteros que la referencian? Ojalá. Lo que hace es dejar un puntero en la ubicación original que apunta a la nueva ubicación de la fila. Ese es el reenvío de puntero: un salto innecesario que se añade al acceso de la fila.

Esto, que puede parecer inofensivo en pequeñas dosis, se convierte en un verdadero problema cuando la tabla crece y las modificaciones son frecuentes. Cada reenvío implica un acceso extra a disco o memoria para encontrar la fila real. Y como bien sabemos, esos accesos extra no son gratuitos: incrementan el tiempo de lectura y degradan el rendimiento de las consultas. Especialmente en esas tablas que alguien decidió consultar con un SELECT * y sin WHERE, porque total, ¿qué podría salir mal?

Cómo se genera un reenvío de punteros

Veámoslo en acción. Tenemos una tabla heap. Insertamos filas. Todo perfecto. Llega el día en que un UPDATE aumenta el tamaño de una fila (añadimos datos a una columna VARCHAR, por ejemplo). La fila ya no cabe en su página. SQL Server mueve la fila a una nueva página y deja un puntero en la posición original apuntando a la nueva ubicación. Algo así como el cartel de nos hemos mudado que ponen algunos negocios en su antiguo local cuando cambian de ubicación. Ahora acceder a esa fila implica primero leer la página con el puntero, luego saltar a la nueva página y leer la fila real. Siguiendo con el ejemplo anterior es como si el GPS te llevase al local antiguo para que vieses el cartel y tuvieses que ir al nuevo.

Pero es que la fiesta no termina ahí. Si la fila se vuelve a actualizar y tampoco cabe en su nueva página, obtenemos un reenvío de un reenvío. ¿Bonito, verdad? Sí, tan bonito como ese fragmento lógico que nadie defragmenta porque “total, no pasa nada”.

Impacto en el rendimiento de los reenvíos de punteros

El impacto de los reenvíos de punteros se manifiesta principalmente en las operaciones de lectura. Cada reenvío supone al menos un salto adicional. Si tenemos un número considerable de ellos, nuestras lecturas se convierten en una gincana de páginas de datos, con sus correspondientes cache misses, latches y demás alegría. Pero no creas que las escrituras están exentas, recuerda que antes de escribir casi siempre lees.

Esto no solo afecta a la velocidad de las consultas. También incrementa el uso de CPU, el tráfico de I/O y la presión sobre el buffer pool. Y aquí viene el detalle que más nos gusta: el optimizador de consultas no tiene en cuenta el coste de los reenvíos al planificar. Así que podemos tener un plan que parecía estupendo sobre el papel y que en ejecución se arrastra como un SELECT con hints absurdos.

Cómo detectar el reenvío de punteros

Detectar reenvíos de punteros no es complicado, pero requiere mirar donde hay que mirar. Podemos usar sys.dm_db_index_physical_stats con la opción DETAILED para analizar las tablas heap y ver el número de forwarded_records. Si este número empieza a crecer, es hora de preocuparse.

Un ejemplo de consulta para los amigos de lo rápido y directo:

Esto nos da una idea de cuántos reenvíos tenemos por tabla. Si ese número no es cero, tenemos trabajo pendiente. Y si el número es alto, es probable que también tengamos un problema de rendimiento.

¿Como elimino los reenvíos de punteros?

La primera solución (y la más eficaz) es: no uses heap salvo que tengas un motivo sólido para hacerlo. Si la tabla tiene lecturas frecuentes y actualizaciones que modifican el tamaño de las filas, un índice clustered es casi siempre mejor elección. Sí, incluso aunque esa tabla sea de staging y “solo esté ahí un ratito”.

Si por algún motivo tenemos que seguir con el heap, toca plan de mantenimiento especial. Por norma general, los planes de mantenimiento de índices no nos van a servir. En su lugar, tenemos que usar el comando ALTER TABLE [NombreTabla] REBUILD que reconstruye el heap y elimina los reenvíos de puntero. Pero claro, eso implica bloqueo de tabla (en algunas versiones de SQL) y no es algo que uno quiera hacer en mitad de un horario productivo.

Otra opción es rediseñar el esquema de la tabla para minimizar las columnas de longitud variable que crecen sin control. Porque claro, si tenemos un VARCHAR(8000) para guardar un número de teléfono “por si acaso”, el problema no es el heap: el problema somos nosotros.

Y por supuesto, monitorizar. Tener un job que periódicamente revise el número de forwarded_records y alerte si se dispara es una medida sencilla que nos puede ahorrar muchas sorpresas.

¿Hay situaciones donde el heap tenga sentido?

Sí, existen. Por ejemplo, en tablas de staging para cargas de datos donde no se hacen actualizaciones y los datos se procesan y eliminan rápidamente. Ahí un heap puede funcionar bien. Pero claro, en cuanto se empieza a hacer algún UPDATE, la decisión de no poner un clustered se vuelve difícil de defender. Y no, el argumento de “es que así insertamos más rápido” no vale si luego el rendimiento de las consultas se va al traste.

Conclusión

El reenvío de punteros es un mecanismo interno de SQL Server para lidiar con el crecimiento de filas en tablas heap. No es un bug, es un diseño consciente. El problema es que suele aparecer porque tomamos decisiones de diseño pobres o porque descuidamos el mantenimiento. Si tenemos un heap, debemos ser conscientes de las implicaciones y monitorizar su estado. Y si vemos reenvíos, actuar antes de que el rendimiento se desplome.

Como siempre, lo más efectivo es evitar el problema desde el principio. Un índice clustered bien elegido elimina de raíz el riesgo de reenvíos. Y si alguien nos insiste en que un heap es la mejor opción para esa tabla con 500 millones de filas y actualizaciones frecuentes, siempre podemos sugerirle que haga las pruebas en producción. Total, ¿qué podría salir mal?

Espero que este artículo te haya resultado útil e interesante. Si tienes alguna duda o comentario, no dudes en contactarnos en Twitter o por mail o dejarnos un mensaje en los comentarios de aquí abajo. Y recuerda que también tenemos un grupo de LinkedIn al que te puedes unir.

Publicado por Roberto Carrancio en Cloud, Rendimiento, SQL Server, 0 comentarios

SORT_IN_TEMPDB: lo que de verdad hay que saber

Entre las opciones que nos ofrece SQL Server a la hora de crear o reconstruir un índice, SORT_IN_TEMPDB es una de esas que suele generar más dudas que certezas. A menudo la encontramos marcada (o desmarcada) en scripts heredados sin que nadie recuerde por qué se tomó esa decisión. Y claro, luego llegan las sorpresas: operaciones que fallan por falta de espacio, tiempos de reconstrucción eternos o índices más fragmentados que la agenda de un comercial. Hoy vamos a poner orden y explicar, con rigor y sin adornos innecesarios, qué hace realmente SORT_IN_TEMPDB, cuándo nos conviene usarlo y cuándo es mejor no tocarlo.

¿Qué es SORT_IN_TEMPDB y cuál es su propósito real?

Cuando creamos o reconstruimos un índice, SQL Server tiene que ordenar los datos para generar la estructura B-Tree. Este proceso de ordenación genera lo que se llaman sort runs, que son fragmentos intermedios de datos ya ordenados que se van almacenando en disco. Por defecto, esos sort runs se guardan en el mismo filegroup de destino del índice, lo que implica que el espacio temporal necesario para la ordenación y el espacio final del índice compiten en el mismo sitio.

Con SORT_IN_TEMPDB ON, lo que hacemos es indicarle al motor que esos sort runs se almacenen en tempdb, mientras que el índice final sigue creándose en el filegroup de destino. Esto no cambia el hecho de que el índice ocupe lo que tenga que ocupar; lo que cambia es dónde se consumen los recursos temporales durante la operación.

El objetivo de esta opción es optimizar el patrón de I/O: si tempdb está en discos diferentes al filegroup de destino, podemos lograr un acceso más secuencial y eficiente, con menos movimientos de cabezales (en discos mecánicos) o menos contención de I/O (en cualquier tipo de almacenamiento). El resultado: potencialmente menos tiempo de creación o reconstrucción del índice. Eso sí, el beneficio depende por completo de cómo tengamos configurado el entorno.

Espacio necesario: no es menos, es más (en el buen sentido)

Uno de los errores más extendidos es pensar que SORT_IN_TEMPDB reduce el espacio requerido para la operación. Nada más lejos de la realidad. Lo que hace es repartir el consumo de espacio entre tempdb y el destino del índice, pero el total de espacio consumido durante el proceso será mayor, porque estamos usando espacio en dos sitios al mismo tiempo.

Para ser claros:

Si SORT_IN_TEMPDB está en OFF (comportamiento por defecto), todo el espacio temporal y el índice final comparten el mismo filegroup. Los sort runs se van liberando conforme se procesan, y sus extents pueden ser reutilizados para el índice final, aunque esto suele provocar que los extents del índice queden menos contiguos.

Si SORT_IN_TEMPDB está en ON, necesitamos suficiente espacio en tempdb para los sort runs y suficiente espacio en el destino para el índice final. La ventaja es que los extents que se asignen al índice final estarán menos fragmentados, porque no se verán afectados por los extents que se van liberando de los sort runs.

Esto implica algo obvio pero que conviene recordar: si no hemos dimensionado tempdb con el espacio suficiente, la operación fallará. Lo mismo si el filegroup destino anda justo de espacio. Ni SORT_IN_TEMPDB ni ningún otro parámetro nos salvará de un error por falta de espacio.

Beneficios reales: cuándo SORT_IN_TEMPDB es útil

El principal beneficio de SORT_IN_TEMPDB es el patrón de I/O más eficiente durante la creación o reconstrucción del índice. Al separar las lecturas de los datos base, las escrituras de los sort runs y las escrituras del índice final en diferentes volúmenes (idealmente), conseguimos que el motor trabaje de forma más ordenada. En discos mecánicos esto significa menos saltos de cabezales; en SSDs o cabinas de almacenamiento, menos contención de I/O.

Además, como hemos comentado antes, usar SORT_IN_TEMPDB mejora la probabilidad de que los extents del índice final sean contiguos, lo que se traduce en un índice más compacto y eficiente en el acceso posterior. Esto es especialmente útil cuando creamos índices grandes, donde la fragmentación inicial puede tener un impacto notable en el rendimiento de las consultas.

Eso sí, el beneficio se da cuando tempdb está en un storage diferente, rápido y bien dimensionado. Si tempdb comparte disco con el resto de bases de datos, o está en un volumen saturado, no sólo no veremos ventaja alguna, sino que podemos incluso empeorar la situación al sumar más carga a un único punto de fallo.

Impacto de SORT_IN_TEMPDB en operaciones online y con columnas LOB

Cuando combinamos SORT_IN_TEMPDB con operaciones online (ONLINE = ON), el consumo de espacio temporal en tempdb puede ser significativo, especialmente si el índice incluye columnas LOB o tenemos activada la opción de compactación de LOB. Aquí el riesgo de quedarnos sin espacio en tempdb es real y hay que tenerlo muy en cuenta. No es raro ver operaciones online que fallan a mitad de proceso por no haber calculado bien este detalle.

Por tanto, si vamos a combinar SORT_IN_TEMPDB con ONLINE, más nos vale monitorizar tempdb y asegurarnos de que tenemos espacio suficiente antes de lanzar el proceso. Y si además lo vamos a hacer en un entorno con mucha carga concurrente, tocará vigilar muy de cerca el uso de I/O y espacio.

Consideraciones finales y buenas prácticas

SORT_IN_TEMPDB es una herramienta muy útil en el arsenal de mantenimiento de índices, pero no es un interruptor mágico que podamos activar sin pensar. Antes de decidir su uso, hay que valorar:

¿Tenemos tempdb en un storage separado y rápido? ¿Hay suficiente espacio disponible en tempdb y en el destino del índice? ¿El índice es lo bastante grande como para que el beneficio compense?

En bases de datos pequeñas o medianas, o en entornos donde tempdb no está optimizado, probablemente no veamos ninguna diferencia perceptible. En cambio, en bases de datos grandes con índices voluminosos y tempdb bien dimensionado, el uso de SORT_IN_TEMPDB puede marcar la diferencia en el tiempo de ejecución y en la calidad del índice generado.

Ah, y no olvidemos un detalle que no por obvio deja de ser importante: SORT_IN_TEMPDB sólo afecta a la operación actual. No hay metadatos que recuerden que un índice se creó o reconstruyó con esta opción. Así que, si queremos un comportamiento consistente, tendremos que especificarlo en cada script donde lo consideremos necesario.

Conclusión

SORT_IN_TEMPDB no es un adorno exótico ni un parámetro para marcar por inercia. Es una opción que, bien usada, nos ayuda a crear y mantener índices más eficientes, más compactos y, potencialmente, más rápido. Pero como todo en SQL Server, depende de que el entorno esté preparado para soportarlo. Porque al final, lo que importa no es el checkbox que marquemos, sino que el índice se construya bien y el servidor no acabe temblando tras la operación. Y eso, amigos, sólo se consigue con planificación, conocimiento y un tempdb en condiciones.

Espero que este artículo te haya resultado útil e interesante. Si tienes alguna duda o comentario, no dudes en contactarnos en Twitter o por mail o dejarnos un mensaje en los comentarios de aquí abajo. Y recuerda que también tenemos un grupo de LinkedIn al que te puedes unir.

Publicado por Roberto Carrancio en Cloud, Índices, Rendimiento, SQL Server, 0 comentarios

¿Es PLE un buen indicador de rendimiento de SQL Server?

Durante años, el Page Life Expectancy (PLE) ha sido una de esas métricas que aparecen en los scripts de monitorización como si fueran mantras sagrados. Una de esas columnas que se miran con recelo, que hacen saltar alertas y que, para algunos, justifican peticiones de más memoria RAM con la ligereza con la que se pide café. Pero como todo en SQL Server, nada es tan sencillo como parece y el PLE, aunque útil, tiene trampa.

¿Qué demonios es el PLE?

El PLE representa cuántos segundos, de media, una página de datos puede permanecer en el buffer pool antes de ser desalojada. Es decir, mide cuánto tiempo vive la información en memoria antes de que SQL Server tenga que expulsarla para hacer sitio a otra. Técnicamente, es un contador de rendimiento (sys.dm_os_performance_counters) que se encuentra dentro de Buffer Manager.

Cuando este valor es alto, respiramos tranquilos: significa que las páginas permanecen en memoria lo suficiente, probablemente porque tenemos un buffer pool holgado y un acceso a disco relajado. Cuando cae en picado, suele ser síntoma de presión de memoria o de lecturas físicas excesivas, muchas veces provocadas por planes de ejecución poco afortunados.

Ahora bien, el número mágico de 300 segundos (5 minutos) que algunos siguen usando como umbral es tan fiable como usar una brújula en mitad de un campo magnético. Ese valor tenía sentido… cuando los servidores venían con 4 GB de RAM. Hoy, con instancias que superan los 512 GB, seguir usando el mismo umbral es como usar una regla de colegio para medir una autopista.

Valores PLE deseables: ¿hay alguno?

Aquí viene la gran pregunta que a su vez es el gran problema del PLE: su valor es absolutamente relativo. Depende del tamaño del buffer pool, del patrón de carga de trabajo, de los tipos de queries que se estén ejecutando, y de si el sistema ha tenido un pico puntual de actividad.

Una instancia con 256 GB de RAM debería tener un PLE mucho más alto que una con 16 GB. ¿Cuánto más? No hay una cifra mágica, pero una orientación razonable sería multiplicar los segundos base (300 en los viejos tiempos) por un factor en relación al tamaño del buffer pool. O mejor aún, establecer una línea base propia de nuestra carga habitual y monitorizar desviaciones.

Porque eso es lo que importa: no tanto si el PLE es 2.000 o 20.000, sino si ha caído bruscamente respecto a lo normal. Un descenso repentino suele estar vinculado a algo que no encaja: una query que hace lecturas absurdas, un mantenimiento mal planteado, o simplemente un usuario que ha decidido escanear toda la tabla de movimientos de 200 millones de registros “por si acaso”.

El PLE no es una medida mágica

Muchos lo tratan como si fuera el santo grial de la salud del servidor, pero en realidad el PLE no mide nada en términos de experiencia de usuario. Es un indicador indirecto de presión de memoria, no una medida de rendimiento ni de latencia. Puede estar alto mientras el sistema responde lento, o estar bajo y aun así tener una experiencia fluida si las queries están bien cacheadas.

Además, el PLE es un promedio a nivel de NUMA node, lo que significa que puede estar sesgado si tenemos un servidor con múltiples nodos y la presión se concentra solo en uno de ellos. SQL Server calcula un PLE por cada nodo NUMA, pero los scripts que aglutinan el valor total no siempre lo desglosan correctamente. De ahí que convenga analizarlo por nodo para tener una visión clara.

Y por si fuera poco, el PLE se resetea con cada reinicio de la instancia. Así que no, si ves un valor bajo justo después de un restart, no es el fin del mundo: es simplemente lo que hay.

Detractores: con razón, no por moda

Los que critican el PLE no lo hacen por capricho. Lo hacen porque, en muchos entornos, mirar el PLE sin contexto lleva a diagnósticos erróneos y decisiones equivocadas. Se han visto DBAs pidiendo 128 GB de RAM más “porque el PLE está bajo”, sin pararse a mirar que el problema era una consulta sin WHERE que se colaba a producción cada viernes a las 15:00.

El PLE tampoco distingue entre lecturas necesarias y lecturas absurdas. Si haces un SELECT * de una tabla de logs históricos porque alguien quiere exportarla a Excel “por si acaso”, el PLE caerá en picado igual que si tuvieras una mala estrategia de índices. Así que usarlo como medida absoluta de salud es, como poco, ingenuo.

Alternativas: mirar más allá del PLE

Si queremos una visión más rica, hay vida más allá del PLE. Podemos observar métricas como el Buffer Cache Hit Ratio, aunque también con cautela, porque este valor suele estar cerca del 100% en casi todas las instancias modernas y no siempre significa lo que creemos. Lo que realmente nos interesa es entender qué queries están provocando lecturas físicas excesivas.

Aquí entra en juego la DMV sys.dm_exec_query_stats, que combinado con sys.dm_exec_sql_text y sys.dm_exec_query_plan, nos puede dar visibilidad sobre qué consultas están provocando lecturas físicas o lógicas desproporcionadas. También podemos revisar el sys.dm_io_virtual_file_stats para analizar el I/O por base de datos y archivo. 

Y si lo que nos interesa es el uso de memoria, el sys.dm_os_memory_clerks y el sys.dm_os_buffer_descriptors ofrecen información mucho más granular sobre cómo SQL Server está usando realmente la RAM.

Además, a partir de SQL server 2025 tendremos la nueva DMV sys.dm_os_memory_health_history pero eso da para otro artículo.

En resumen: el PLE puede servirnos como un primer vistazo, como ese canario en la mina que nos avisa de que algo pasa. Pero confiar ciegamente en él es como juzgar un libro por el grosor del lomo.

Monitorizar el PLE: ¿sí o no?

Entonces, ¿monitorizamos el PLE o no? Esta es una de esas preguntas que genera debates infinitos y respuestas del tipo “depende”. Yo voy a ser neutral, no voy a entrar en la trinchera de los que lo consideran inútil ni en la de los que lo elevan al nivel de oráculo. Lo que sí diré es que monitorizar el PLE puede tener sentido si sabemos lo que estamos mirando y no nos dejamos llevar por interpretaciones simplistas.

Si tenemos una línea base sólida, si entendemos la arquitectura NUMA de nuestra instancia y si usamos el PLE como un indicador más dentro de un conjunto más amplio de métricas, entonces puede ser útil. Pero si lo usamos como termómetro único del rendimiento, vamos a acabar medicando al paciente por fiebre sin saber que tiene apendicitis.

Conclusión

El Page Life Expectancy no está muerto, pero tampoco es un mesías. Es una métrica con contexto, con historia y con limitaciones. Sirve para levantar sospechas, no para dictar sentencias. Hay que leerlo con ojo clínico, entender lo que implica y, sobre todo, combinarlo con otras métricas más modernas y más específicas.

Como siempre, no hay atajos. Lo que hay es análisis, observación y un poco de sentido común. Que no es mucho pedir… salvo que creas que SELECT * sigue siendo buena idea.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

Publicado por Roberto Carrancio en Cloud, Rendimiento, SQL Server, 0 comentarios

CPU NUMA: Cuando el procesador también tiene barrios

Hay palabras que, al oírlas, nos ponen en guardia. “NUMA” es una de ellas. No porque suene peligrosa, sino porque suele venir envuelta en conceptos vagos y soluciones mágicas a problemas que no entendemos del todo. Pero no nos engañemos: si administramos SQL Server sobre hardware serio (y no sobre portátiles reciclados con Docker “porque mola”), entender cómo se comporta la arquitectura NUMA no es opcional. Es imprescindible.

¿Qué es NUMA? Una ciudad con barrios.

NUMA (Non-Uniform Memory Access) es una arquitectura de memoria en la que cada CPU (o grupo de CPUs) tiene acceso preferente a un bloque de memoria. A este conjunto se le llama nodo NUMA. Sí, se puede acceder a la memoria de otros nodos, pero es más lento. Y en un mundo donde las latencias de microsegundos importan más que los deadlines de los Project Managers, eso no es un detalle menor.

Puede parecer lioso pero vamos a verlo en una imagen para que no haya dudas. Realmente todo esto no es algo abstracto, viene directamente definido a nivel hardware. Las placas base de los servidores tienen varios socket de procesadores y, cada uno de ellos, tiene unos slots de RAM más cercanos a los que accede con menor latencia.

Aquí, por ejemplo, vemos dos sockets físicos, cada uno con 8 núcleos y 128 GB de RAM. Cada socket está conectado a su propia porción de memoria. Esto es lo que llamamos una arquitectura NUMA: cada CPU accede más rápido a su “propia” memoria que a la del otro socket. Y sí, como os decía, un procesador puede acceder a la memoria del otro, pero con más latencia. Cómo cruzar la ciudad para ir al mercadona de otro barrio teniendo uno en el tuyo, se puede, pero no es lo ideal.

SQL Server es plenamente NUMA-aware desde hace muchas versiones. Y no es solo marketing. El motor entiende esta arquitectura y la usa para optimizar la asignación de memoria, la ejecución de tareas en paralelo y la gestión de schedulers. Todo esto siempre y cuando no le pongamos la zancadilla con configuraciones absurdas.

Planificación y schedulers: cómo SQL Server reparte el trabajo

Cada nodo NUMA tiene un conjunto de schedulers, que no son otra cosa que planificadores de hilos (threads). Para ser lo más eficiente posible, SQL Server intenta ejecutar los hilos en el mismo nodo donde se asignaron, y acceder a la memoria local del mismo. Si la información está bien distribuida, esto reduce el tráfico entre nodos y mejora la latencia general. Pero si metemos la pata, por ejemplo fijando la afinidad de forma manual y sin criterio, podemos forzar al motor a comportarse como un repartidor de pizzas desorientado: yendo de un barrio a otro sin sentido y perdiendo tiempo en cada esquina.

Además, cada instancia de SQL Server crea un grupo de trabajo por cada nodo NUMA visible. Y si usamos el modo de memoria comprimida, las decisiones de qué nodo usa qué buffer pool se vuelven aún más relevantes. Ignorar esto es como jugar al ajedrez sin mirar el tablero. Puede parecer divertido, pero termina mal.

El efecto de un mal diseño NUMA

Cuando un servidor tiene múltiples sockets físicos, es muy probable que cada socket represente un nodo NUMA. Pero algunos sistemas operativos y BIOS permiten desactivar o modificar esta topología. Resultado: servidores con 256 núcleos que se ven como un único nodo NUMA. ¿Y eso qué implica? Pues, para empezar, que SQL Server no puede distribuir sus schedulers de forma eficiente. El escalado se resiente, la contención de recursos aumenta y las consultas paralelas empiezan a hacer cosas raras.

¿Has visto alguna vez una consulta que parece ir más lenta cuanto más CPUs tiene disponibles? Bienvenido al infierno del mal NUMA. Y sí, hay admins que creen que poner más CPUs siempre mejora el rendimiento. También hay quien piensa que una tabla de log no necesita índices. Vivir para ver.

Las virtualizaciones y sus trampas con NUMA

Ah, la virtualización. Ese mundo donde puedes tener 64 vCPU repartidas en 2 nodos NUMA virtuales y no saber por qué tu SQL Server tiene el rendimiento de un 486 con resaca. Los hipervisores serios (como VMware, Hyper-V o, incluso, Proxmox) permiten configurar el número de nodos NUMA expuestos a la máquina virtual. Pero si dejas esto en manos de un “especialista” que nunca ha leído una página del “whitepaper de arquitectura NUMA en SQL Server” (sí, no solo existe, cada fabricante tiene uno propio), lo normal es que termines con un entorno virtualizado más caótico que una tabla sin clave primaria.

Por eso, cuando trabajamos con entornos virtualizados, conviene revisar cuidadosamente cómo están asignados los núcleos físicos, cuántos nodos NUMA ve la VM y cómo se está presentando la memoria. SQL Server lo detectará, pero no puede arreglar por sí solo una chapuza.

¿Y qué hay del NUMA en SQL Server en Azure?

Pues aquí el tema se vuelve más oscuro. Microsoft no publica (con detalle) la topología NUMA exacta de sus VMs, pero en general puedes asumir que, en las series más potentes, hay más de un nodo. Las VMs con más de 16 vCPU casi siempre están divididas en al menos dos nodos NUMA virtuales. ¿Cómo lo comprobamos? Ejecutando SELECT * FROM sys.dm_os_nodes y observando el campo memory_node_id. Si ves más de un nodo con memory_node_id distinto de 64 (el de DAC), estás en terreno NUMA.

Por tanto, cuando afinamos instancias en Azure, conviene monitorizar la distribución de la carga entre nodos. A veces, ciertas consultas intensivas pueden estar trabajando siempre sobre el mismo nodo, provocando un cuello de botella local mientras el resto del servidor está de paseo.

Configuraciones de NUMA recomendadas

Si el servidor tiene una topología NUMA bien definida, lo mejor que podemos hacer es dejar que SQL Server gestione sus schedulers y memoria. No toques la afinidad de CPU salvo que tengas un motivo muy claro. Y por favor, no uses MAXDOP sin entender cómo afecta a los nodos. Un mal MAXDOP puede anular por completo los beneficios de NUMA, provocando saltos de memoria y escalado ineficiente.

También hay que considerar Resource Governor, que puede fijar workloads a ciertos nodos, o las nuevas opciones de Soft-NUMA (a partir de SQL Server 2016), útiles cuando el hardware ofrece más núcleos por nodo de los que SQL Server gestiona de forma eficiente por defecto.

Y si alguien propone usar lock pages in memory sin revisar la topología NUMA antes, haceos un favor: quitadle los permisos.

Conclusión

NUMA no es un problema. Es una característica muy potente. Pero como toda característica avanzada, si no la entendemos puede convertirse en un dolor de cabeza. En entornos de producción con alta carga, especialmente con muchos núcleos y grandes volúmenes de memoria, ignorar NUMA es como hacer tuning con los ojos vendados.

La solución no es complicarse la vida configurando todo a mano sin necesidad, sino entender cómo se comporta SQL Server en nuestro entorno y dejar que optimice… siempre que el terreno no esté lleno de minas.

No lo digo yo, lo dice la ciencia.

Espero que este artículo te haya resultado útil e interesante. Si tienes alguna duda o comentario, no dudes en contactarnos en Twitter o por mail o dejarnos un mensaje en los comentarios de aquí abajo. Y recuerda que también tenemos un grupo de LinkedIn al que te puedes unir.

Publicado por Roberto Carrancio en Cloud, Rendimiento, SQL Server, 0 comentarios
SSRS dice adiós: PBIRS toma el relevo en SQL Server 2025

SSRS dice adiós: PBIRS toma el relevo en SQL Server 2025

La semana pasada, en el SQL Bits, Bob Ward nos daba la noticia con la sonrisa de quien cree que ha tenido una gran idea y espera que todos aplaudamos: a partir de SQL Server 2025, SSRS se queda sin futuro. No habrá nuevas versiones, ni promesas de mejoras, ni siquiera ese Service Pack que llegaba tarde y mal. En su lugar, Microsoft ha decidido que todo lo relacionado con reporting on-premises se haga con Power BI Report Server. PBIRS entra en todas las ediciones de pago de SQL Server y SSRS, después de dos décadas de leales servicios, se queda en mantenimiento hasta 2033. Merece la pena parar un momento, repasar esta historia y ver por qué este cambio tiene sentido, aunque duela.

El ascenso y estancamiento de SSRS

SSRS lleva en nuestras vidas desde antes que alguno de vosotros. Concretamente desde 2004, cuando se presentó como una extensión gratuita para SQL Server 2000. Su propuesta era clara: permitir la creación de informes paginados usando RDL (Report Definition Language), con control pixel-perfect y exportaciones a Excel que acababan en los escritorios de medio planeta. Fue una revolución en su momento, sustituyendo soluciones propietarias más caras y difíciles de mantener (Crystal Reports, te estamos mirando a ti). A partir de SQL Server 2005, SSRS ya venía integrado, y poco a poco se convirtió en la herramienta por defecto para reporting operativo en entornos on-prem. Muchos aún lo siguen usando a diario: por robusto, por fiable y porque funciona.

Pero también es cierto que lleva años estancado. Las mejoras en las últimas versiones han sido mínimas, casi anecdóticas. La interfaz de desarrollo, ya sea en Visual Studio o en Report Builder, parece sacada de una cápsula del tiempo. Y mientras tanto, Power BI ha crecido, se ha convertido en la niña mimada del equipo de producto y ha absorbido toda la inversión. No había que ser visionario para intuir que a SSRS le quedaban pocos cartuchos.

PBIRS entra en escena con todo el respaldo

PBIRS, por su parte, se presentó como una solución híbrida. Construido sobre la base de SSRS permite ejecutar tanto informes paginados como informes interactivos en formato PBIX, lo cual lo convierte en un candidato ideal para ser ese puente entre lo tradicional y lo moderno. Además, añade características importantes como el soporte de seguridad a nivel de fila, visuales personalizados y actualizaciones con una frecuencia más propia de los productos cloud que del viejo stack on-prem. 

Hasta ahora, PBIRS era un extra al que solo podían acceder los clientes de SQL con licencia Enterprise y Software Assurance o clientes de Fabric con licencias F64 o superior, lo que limitaba mucho su adopción. Por suerte, esos tiempos oscuros se van a acabar: a partir de SQL Server 2025, cualquier edición de pago de SQL incluye derecho a instalar PBIRS, usando la misma clave del servidor. Más fácil, más directo, más lógico, como era con SSRS.

La lógica detrás del cambio de SSRS a PBIRS

La justificación oficial es que SSRS no es más que un subconjunto de lo que ofrece PBIRS. Y es cierto: todo lo que hacía SSRS, lo hace PBIRS. Pero también hace más cosas. Si estás en un entorno donde ya conviven informes RDL con Power BI, la unificación es natural. Si vienes solo de SSRS, puede que el salto te parezca innecesario, pero la dirección está clara. Microsoft quiere que el reporting on-prem hable el lenguaje de Power BI, aunque aún no estemos listos para irnos a la nube.

Lo que ganamos con PBIRS (y lo que perdemos)

Ahora bien, no todo es ganancia. En la transición se pierden cosas. Algunas funcionalidades específicas, como los informes vinculados, no tienen una traducción directa en PBIRS. Las integraciones con sistemas antiguos o personalizados, especialmente aquellas que dependían de extensiones específicas o APIs internas de SSRS, pueden requerir adaptación. Y aunque la migración de RDLs está soportada y bien documentada, eso no significa que sea trivial. Hay que revisar fuentes de datos, suscripciones, permisos, configuraciones de caché y otras complicaciones que todos sabemos que pueden existir en informes que tienen más de 20 años y duermen tranquilas hasta que una migración las despierta.

Migrar a PBIRS: lo bueno, lo malo y lo inevitable

El proceso de migración, en sí mismo, está bastante claro. Microsoft ha publicado guías detalladas y herramientas para mover informes y catálogos desde SSRS a PBIRS. Incluso puedes probar PBIRS en modo Developer o Evaluation antes de tomar decisiones definitivas. Pero, como siempre, todo depende del grado de personalización de tu entorno y de cuánto te hayas alejado del camino en los últimos diez años. Porque sí, todos decimos que usamos SSRS “como viene”, pero luego llegan los informes con código embebido, las fuentes de datos compartidas con autenticación personalizada y ese servidor que nadie quiere tocar porque “funciona y no se ha caído en años”.

Soporte hasta 2033: más calma que consuelo

Lo curioso es que la noticia, pese a ser una especie de epitafio para SSRS, viene acompañada de la típica promesa tranquilizadora: SSRS 2022 seguirá recibiendo actualizaciones de seguridad (en soporte extendido) hasta enero de 2033. Eso quiere decir que puedes seguir usándolo si no quieres o no puedes migrar todavía. Puedes incluso seguir instalando SSRS 2022 con versiones más nuevas del motor de SQL Server, aunque no recibirás nuevas funcionalidades. Básicamente, queda en modo mantenimiento. Como cuando apagas el monitor pero dejas el servidor encendido: sigue ahí, pero ya no espera nada de la vida.

SSRS y PBIRS: Una consolidación inevitable

Hay que reconocer que este cambio tiene sentido. No es una jugada improvisada. Es parte del movimiento más amplio hacia Fabric, hacia unificar las herramientas de BI bajo el paraguas de Power BI, y hacia simplificar el stack on-prem. En lugar de mantener dos productos con solapamientos, Microsoft apuesta por uno solo, más potente, más alineado con su estrategia cloud y más fácil de justificar a nivel de roadmap. Tiembla SSIS.

Aun así, para quienes hemos vivido el mundo SSRS puro y duro, este cambio tiene algo de nostalgia. Nos ha acompañado en muchas guerras, nos ha dado informes que imprimen correctamente en la primera pasada, nos ha dejado programar suscripciones y controlar exportaciones como si estuviésemos montando una fábrica de PDFs. Pero el futuro no es eso. El futuro tiene interactividad, exploración de datos, visuales dinámicos y conectividad con servicios cloud. Y todo eso, por mucho que nos pese, no lo va a ofrecer nunca SSRS.

Conclusión

Así que, no lo veamos como una pérdida. Veámoslo como lo que es: una consolidación que estaba cantada. PBIRS hereda todo lo bueno de SSRS y añade lo que le faltaba. Que el proceso de migración tenga sus complejidades no debería sorprendernos. Es parte del juego (y a los consultores y técnicos nos dará dinerito). Lo importante es que ahora tenemos un camino claro, una herramienta mejor y tiempo suficiente para adaptarnos. Porque sí, SSRS fue grande. Pero PBIRS es el que se queda. Y conviene conocerlo bien, porque es lo que nos espera en los próximos años.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

Publicado por Roberto Carrancio en Power BI, SQL Server, 0 comentarios

SLAs en SQL Server: Cómo prometer lo justo y sobrevivir

La mayoría de nosotros no elegimos ser DBAs por vocación mística. Llegamos aquí porque alguien tenía que entender por qué un backup no se hace solo, por qué los datos importan más que los informes bonitos y, sobre todo, porque hacía falta alguien que no creyera que «un DELETE sin WHERE es una buena idea». Y dentro de esa jungla, un tema que siempre vuelve, como los bugs tras una actualización mayor, es el de los SLAs. Sí, esos compromisos tan bienintencionados que se convierten en promesas grabadas en piedra cuando algo explota.

SLAs, KPIs y demás siglas que no son lo mismo

Antes de definir cómo establecer un SLA decente, conviene aclarar de qué demonios estamos hablando. Un SLA (Service Level Agreement) es un compromiso formal sobre el nivel de servicio que se debe prestar. En otras palabras: una promesa escrita, medible y revisable sobre tiempos de respuesta, disponibilidad o calidad.

Un KPI (Key Performance Indicator), por su parte, es un indicador que nos permite medir cómo de bien (o mal) estamos cumpliendo esos compromisos. El SLA es el contrato; el KPI, el termómetro. Confundirlos es como pensar que tener fiebre es lo mismo que firmar un seguro médico.

Por ejemplo, si el SLA dice que debemos restaurar una base de datos crítica en menos de 1 hora, el KPI será la métrica que nos dirá cuántas veces lo conseguimos, cuántas nos pasamos de tiempo y cuál es el promedio. Así de simple. Y así de importante.

¿Por qué definir SLAs para incidencias y peticiones?

Los SLAs son como las condiciones de una hipoteca: poca gente los entiende del todo, pero todos los firman y luego lloran cuando llega la letra pequeña. Para nosotros, definir SLAs no es solo una cuestión de burocracia. Es la única forma de establecer expectativas claras (y razonables) entre quien mantiene los sistemas y quien espera que todo funcione como Netflix un sábado por la noche.

SLAs mal definidos acaban en alertas fantasma, restauraciones “urgentes” de bases de datos de hace cinco años y discusiones bizarras sobre por qué una petición enviada a las 18:59 no puede resolverse “antes de irnos”. Así que vamos a ver cómo definirlos bien, con precisión, malicia técnica y sentido común.

Clasificación técnica para SLAs útiles

Lo primero es entender que no todo es “alta prioridad”. Si todo es urgente, nada lo es. Aquí es donde muchos equipos se estampan contra el muro del caos. No es lo mismo que falle un servidor de producción que una petición para crear una base de datos para pruebas. Y sin embargo, en demasiadas empresas, ambas llegan al DBA con el mismo subject: “URGENTE”.

Así que toca clasificar. Podemos dividir las solicitudes en dos grandes grupos: incidencias y peticiones. Las incidencias afectan a la continuidad del servicio. Las peticiones, en cambio, suelen ser mejoras, configuraciones nuevas, cambios programados… todo eso que también puede romper algo, pero con elegancia.

Dentro de cada grupo hay que establecer niveles de prioridad. Una clasificación útil (aunque no la única) sería: 

  • Crítica: Pérdida total de servicio o datos. El tipo de cosa que hace que los móviles empiecen a sonar y los jefes pregunten si tenemos backup. Aquí el SLA tiene que ser inmediato. Y sí, esto se traduce en “se deja todo y se arregla”.
  • Alta: Impacto serio pero parcial. Por ejemplo, una base de datos de BI que no carga el ETL nocturno. No es producción directa, pero alguien se va a cabrear en cuanto llegue a la oficina. El SLA aquí puede estar en torno a las 4 horas.
  • Media: Afecta a una parte del sistema, pero tiene alternativas o workarounds. Por ejemplo, un job de mantenimiento que falla pero no impide operar. SLA de 1 día laboral.
  • Baja: Nada crítico. Solicitudes de cambios planificados, creación de logins, ampliaciones de espacio no urgentes. Aquí hablamos de resolverlo en 2-3 días laborables, dependiendo de la carga del equipo.

¿Y los horarios?

Todo esto es muy bonito pero, si vamos a hacer esto bien, hay que dejar claro también dos cosas que en muchos sitios se omiten por pereza (o por miedo a la verdad): qué niveles activan la guardia, y si los SLAs se miden en tiempo real o en horas laborables.

En la mayoría de entornos serios, solo las incidencias críticas (reales, no las autoasignadas por usuarios con complejo de urgencia) justifican una llamada fuera del horario. Si alguien quiere soporte 24×7 para problemas de prioridad media, lo lógico es que también financie un equipo 24×7. Milagros, aquí, los justos.

Y respecto al cómputo del SLA, no es lo mismo “4 horas” que “4 horas laborables”. Si no se especifica, el usuario siempre asumirá que el reloj corre todo el día, todos los días. Por eso, al definir un SLA, hay que dejar claro el calendario de servicio aplicable. ¿Es de lunes a viernes de 9 a 18h? ¿Incluye festivos? ¿Hay soporte en fines de semana? Todo eso tiene que estar negro sobre blanco. Porque si no, luego llegan los correos del domingo a las 7:12 con copia a dirección general preguntando por qué “aún no se ha resuelto”.

Prioridad, entorno y contexto: el barro donde se hunden muchos SLAs

Sería maravilloso vivir en un mundo donde la prioridad depende solo del tipo de incidencia, y no del entorno donde ocurre. Pero eso es teoría. En la práctica, los entornos importan, y mucho. No es lo mismo que se caiga producción que un entorno de desarrollo, ¿verdad? Bueno… depende.

Sí, la regla general dice que los entornos de producción son los únicos donde una incidencia puede alcanzar el nivel crítico. Pero hay excepciones. ¿Puede haber una incidencia crítica en un servidor de test? Sí, si ese entorno es parte esencial de una cadena de despliegue continuo, de validación de procesos regulados o si es el único sitio donde se puede reproducir un bug crítico que bloquea el negocio. No es lo habitual, pero pasa. Y cuando pasa, más vale tener el SLA bien definido y que el equipo no lo desprecie por ser «solo pre».

¿Y qué pasa con los entornos de desarrollo? Pues que en muchas empresas de desarrollo de software, el entorno de dev es tan vital como producción. Si el equipo de desarrollo está bloqueado porque no puede compilar, probar o desplegar por culpa de una base de datos caída, eso no es un problema menor. Igual no es crítico según la jerarquía clásica, pero es de alta prioridad. El mundo real no siempre cabe en una tabla de 2×2.

Restauraciones: ¿petición o incidencia?

Luego está el problema de que lo que para otros es una incidencia para nosotros puede ser una petición. Por ejemplo, clásico de los clásicos, “He borrado una tabla entera sin querer. ¿Esto es una incidencia o una petición?” Técnicamente es una petición (al menos para nuestro equipo), porque no es una caída del sistema. El sistema está funcionando perfectamente… demasiado bien, de hecho. Que tu tengas una incidencia a nivel de aplicación no significa que exista ningún problema a nivel servidor de base de datos. Pero, si lo miramos operativamente tiene impacto inmediato, y no tratarlo con urgencia puede ser un error de bulto. Si no actuamos rápido, el problema para la empresa (quien nos paga) puede escalar a categoría épica.

Por eso, más allá de la matriz estándar de SLAs, es necesario aplicar juicio técnico. No todo cabe en una checklist. Los equipos que sobreviven no son los que aplican normas rígidas a martillazos, sino los que saben cuándo saltarse la regla para evitar un incendio. Y, por supuesto, dejar constancia del por qué.

SLAs de respuesta vs. SLAs de resolución: no es lo mismo

Uno de los errores clásicos al definir SLAs es confundir respuesta con resolución. Responder rápido no significa resolver rápido. A veces basta con confirmar que hemos recibido la solicitud y que estamos en ello (sí, eso cuenta como “respuesta”).

El truco está en comprometerse solo a lo que podemos cumplir. No prometas restaurar un backup en 15 minutos si sabes que el fichero está en cinta y necesitas abrir un ticket a soporte, que luego vienen los lloros.

Una fórmula útil es definir ambos tiempos por separado. Por ejemplo: respuesta en 1 hora, resolución en 4. Así evitamos malentendidos del tipo “pero si dijiste que lo tendrías ya”.

¿Quién prioriza los SLAs y cómo evitar el caos?

Aquí es donde se separan los SLAs útiles de las cartas a los Reyes Magos. No podemos dejar que sea el usuario quien marque la prioridad. No porque no sepa lo que necesita, sino porque siempre va a considerar su problema como el más importante del universo. Y porque si le dejas elegir, todas las solicitudes serán “urgentes, críticas y con impacto en negocio”.

La clasificación debe estar en manos del equipo técnico, o al menos ser revisada por él. Idealmente, con criterios claros, objetivos y documentados. Sí, documentados. Aunque nos duela.

Y si hay un catálogo de servicios (y debería haberlo), que incluya ejemplos de cada tipo de incidencia o petición con su prioridad y su SLA correspondiente.

Qué hacer si un SLA no se cumple

Lo vamos a decir sin rodeos: si no hay consecuencias por incumplir SLAs, entonces son solo papel mojado. Ahora bien, tampoco se trata de irse al extremo contrario y penalizar con sangre y fuego a quien llega tarde a resolver un bug.

La clave está en el seguimiento. Medir los SLAs, revisarlos con regularidad, identificar por qué se incumplen (si se incumplen) y actuar. Puede que no se cumplan porque el equipo está desbordado. O porque el sistema de alertas es más pesado que útil. O porque alguien sigue mandando incidencias al correo personal del DBA “porque así va más rápido”.

Hacer seguimiento no es buscar culpables, es afinar procesos. Aunque si descubrimos que todas las incidencias llegan marcadas como críticas por el mismo usuario… bueno, ya sabemos a quién regalarle un curso de lectura de SLAs.

Cómo definir SLAs realistas sin usar magia negra

Definir buenos SLAs requiere conocer bien la infraestructura, los recursos disponibles y las prioridades del negocio. No podemos copiarlos de otro departamento ni improvisarlos en una reunión con PowerPoint. Hay que sentarse, medir tiempos reales de resolución, analizar históricos y, a ser posible, usar herramientas que permitan registrar y categorizar incidencias de forma estructurada.

Y si alguien insiste en que hay que tener un SLA de resolución de 15 minutos para restaurar cualquier base de datos, podemos responder con otra petición: “Vale, ¿me das almacenamiento dedicado y restauraciones «preindexadas» también?”. Spoiler: no lo hará.

Conclusión

Los SLAs no son una varita mágica ni una forma elegante de decir “hazlo rápido”. Son un acuerdo técnico con implicaciones reales. Si los definimos bien, nos ahorran dolores de cabeza, discusiones bizantinas y promesas incumplidas. Si los dejamos al azar, acabaremos apagando fuegos a todas horas y con la sospecha constante de que nos están tomando por el servicio técnico de la impresora.

Así que toca hacer el trabajo sucio: clasificar, medir, escribir, negociar. Con criterio, con datos, y sin miedo a decir que no cuando un SLA no tiene sentido. Porque, como ya hemos aprendido todos a estas alturas, prometer lo imposible es la forma más rápida de acabar con una alerta crítica… y un ticket de recursos humanos.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

Publicado por Roberto Carrancio en Cloud, SQL Server, 0 comentarios