El error de 16 años oculto en la base de datos que usa cada app de tu teléfono

Base de datosSQLiteInfraestructura

Fuentes:HN + web research · HN

El error de 16 años oculto en la base de datos que usa cada app de tu teléfono

En agosto de 2026, Tailscale, una empresa especializada en software de redes privadas seguras, publicó un análisis retrospectivo (postmortem) revelando que su base de datos principal había sufrido 19 corrupciones inexplicables en los seis meses anteriores. Cada incidente provocó breves caídas de red para parte de los usuarios, exigiendo más de una hora de trabajo para recuperarse en cada ocasión. Tras meses de minuciosa investigación, los ingenieros encontraron la causa raíz: una condición de carrera oculta dentro del motor de base de datos más desplegado del mundo durante al menos 16 años.

Tailscale crea herramientas para conectar dispositivos de forma segura en redes privadas. Aunque nunca hayas oído hablar de la compañía, esta historia te concierne directamente, porque el software de base de datos en el centro del misterio está ejecutándose en tu teléfono móvil ahora mismo.

El software omnipresente que nunca has visto

Primero, conozcamos al protagonista. SQLite es la base de datos más utilizada del planeta, presente según cifras oficiales en miles de millones de dispositivos. Tus aplicaciones de mensajería, bancarias, navegadores web y juegos confían en ella para guardar sus datos.

Lo que hace único a SQLite es su diseño embebido o integrado. Mientras que las grandes bases de datos empresariales funcionan como la bóveda de un banco que requiere guardias dedicados y un edificio independiente (servidores dedicados), SQLite es como una pequeña caja fuerte portátil que cada aplicación lleva consigo. No requiere instalación, ni administración de procesos, ni mantenimiento. Los desarrolladores guardan los datos en ella y pueden olvidarse del asunto durante décadas.

Esta comodidad convirtió a SQLite en la base invisible del mundo digital. Dado que miles de millones de dispositivos realizan transacciones en ella constantemente, su fiabilidad ha sido probada innumerables veces, reduciendo la probabilidad de fallos a niveles infinitesimales, tan bajos que incluso sus propios creadores creían que sus componentes fundamentales carecían de errores.

Un fallo escondido en los cimientos

Desde 2022, Tailscale guardaba todos sus datos clave en SQLite porque era “tecnología aburrida” (Boring Technology), un elogio en el argot técnico que significa que es predecible y no causa problemas. Desde principios de 2023 hasta el verano de 2025, todo funcionó sin el menor inconveniente.

Sin embargo, en agosto de 2025, el sistema de copias de seguridad lanzó una alerta inesperada: un archivo de base de datos estaba dañado. El equipo reparó y analizó el fallo sin encontrar una explicación lógica. Luego vino una segunda corrupción, una tercera… sumando 19 incidentes en medio año. En la ingeniería de sistemas a gran escala, si la probabilidad de un evento raro es mayor que cero, cuando el volumen y el número de operaciones crecen lo suficiente, lo improbable termina convirtiéndose en rutina.

Lo más frustrante era que los 19 incidentes no compartían ningún patrón aparente: no ocurrieron en los mismos servidores, ni con los mismos usuarios, ni en las mismas franjas horarias, ni bajo el mismo tipo de carga. Los ingenieros no tenían pistas ni forma de reproducir el error en su laboratorio.

”Primero las notas, luego el libro principal”: El modo WAL

Para entender la investigación, es necesario conocer un modo de funcionamiento de SQLite llamado WAL (Write-Ahead Log, o registro de escritura previa).

Imagina un libro de contabilidad. El modo tradicional consiste en abrir el libro e inscribir cada transacción directamente en sus páginas. En el modo WAL, en cambio, los apuntes se anotan rápidamente en un taco de notas adhesivas. Cuando se acumula una cantidad determinada de notas, se transfieren todas juntas al libro principal. El taco de notas es el archivo WAL, el libro principal es el archivo de la base de datos y la acción de transferir los datos se denomina checkpoint (punto de control).

WAL y archivos de base de datos

Fig.: Los nuevos datos se escriben primero en el archivo WAL y luego se transfieren al archivo principal de la base de datos. Fuente: tailscale.com

Las ventajas del modo WAL son evidentes: escribir en una nota rápida es mucho más ágil que modificar un libro pesado, y la transferencia de datos se puede realizar de forma asíncrona cuando el sistema está desocupado. Además, quienes consultan el libro no interfieren con quienes anotan nuevas transacciones. Muchas aplicaciones de alto rendimiento utilizan este modo. Tailscale no solo lo usaba, sino que tomó una decisión drástica: forzar checkpoints de forma manual y extremadamente frecuente para facilitar las copias de seguridad. Esta decisión fue la mecha de todo lo que vino después.

Condición de carrera: El colapso de dos operaciones simultáneas

El mecanismo del fallo se resume en una frase: cuando la transferencia de datos al libro y la anotación de una nueva transacción ocurrieron al mismo tiempo, el orden de las operaciones falló. En informática, esto se conoce como una condición de carrera (race condition).

Sucedió de la siguiente manera: el proceso de checkpoint revisó el taco de notas, vio 10 notas pendientes y empezó a copiarlas al libro principal. Justo a mitad de camino, otra operación añadió una nueva nota y reinició la cuenta de los números de las notas. De ahí proviene el nombre del error: “WAL-Reset”. El proceso de checkpoint, sin darse cuenta del reinicio, continuó copiando basándose en la numeración antigua. Como resultado, una página de datos que en realidad no se había transferido fue marcada por error como “ya copiada” y se omitió.

Flujo de checkpoint

Fig.: El proceso de checkpoint copia las páginas de datos del WAL al archivo principal de la base de datos. Fuente: tailscale.com

Esa anotación desapareció sin dejar rastro. Para colmo, en otras páginas del libro principal quedaron índices que apuntaban a esa información perdida, provocando que SQLite declarara toda la base de datos como “corrupta”. Tiempo después, los ingenieros de Tailscale encontraron una cifra contradictoria en sus registros: el archivo WAL solo contenía 10 páginas de datos, pero el checkpoint informó haber copiado 20 páginas. Las 10 páginas extra eran la ilusión óptica producida por la numeración antigua, convirtiéndose en la pista clave para resolver el caso.

¿Por qué permaneció oculto durante 16 años?

El equipo oficial de desarrolladores de SQLite calcula que este error llevaba en el código al menos 16 años. Logró pasar desapercibido tanto tiempo debido a lo inverosímil de sus condiciones de activación: requería una combinación específica de versiones de librerías, que la transacción de escritura coincidiera con una ventana exacta de microsegundos dentro del proceso de checkpoint, y un comportamiento particular del sistema de archivos del sistema operativo. La probabilidad de que los tres factores coincidieran en un uso habitual era, en palabras del propio creador de SQLite, “prácticamente imposible en condiciones normales”.

De hecho, para comprobar que el parche de corrección funcionaba, los desarrolladores de SQLite tuvieron que introducir código de prueba especial dentro del motor para forzar artificialmente la colisión, algo que nunca antes habían hecho para ningún otro error.

La mayoría de los usuarios utiliza la configuración por defecto y jamás se topa con este problema. Tailscale lo sufrió 19 veces porque sus propios intervalos hiperfrecuentes de checkpoint multiplicaron exponencialmente las probabilidades de colisión. El “suceso imposible” se transformó en su entorno en una simple cuestión de tiempo.

Cómo resolvieron el caso los detectives

Entre los muchos informes de análisis de fallos en la industria, este destaca por su meticulosidad técnica.

Durante los primeros meses no hubo avances. Revisaron todo su propio código sin encontrar fallos y el error no se podía reproducir. Hubo incluso un periodo de calma de seis semanas sin incidentes, lo que demostró que la ausencia de fallos no significa que el problema haya desaparecido. Entonces tomaron una decisión clave: registrar cada instrucción de modificación de la base de datos en un archivo de registro independiente.

Este registro detallado dio el fruto esperado. Durante los dos incidentes siguientes, al reproducir los registros descubrieron algo insólito: una transacción confirmada correctamente acabó volviéndose “invisible” más tarde. Una escritura se esfumó en el aire sin emitir ninguna advertencia, algo insólito en el mundo de las bases de datos transaccionales.

En ese momento, los desarrolladores principales de SQLite se sumaron a la investigación a través del servicio de soporte profesional contratado por Tailscale. Juntos crearon una herramienta de diagnóstico a medida llamada tmstmpvfs shim (un shim es una capa de supervisión que envuelve a un módulo existente). La arquitectura de SQLite consta de tres capas principales: la capa superior interpreta comandos SQL, la capa intermedia divide los datos en bloques y la capa inferior se encarga de escribir físicamente en el disco. Esta última capa se llama VFS (Virtual File System). El shim envolvió la capa VFS para registrar cada lectura y escritura como si fuera una cámara de seguridad instalada en la puerta de la bóveda.

Capa de depuración VFS shim

Fig.: La interfaz de almacenamiento de más bajo nivel de SQLite envuelta en una capa de monitoreo (shim). Fuente: tailscale.com

Con la cámara instalada, solo quedaba esperar el siguiente fallo. No tardó en ocurrir. Con los registros completos en mano de los desarrolladores principales de SQLite, la condición de carrera fue capturada con las manos en la masa: a mitad del checkpoint, una transacción de escritura reinició el WAL sin que el checkpoint lo detectara.

Casi al mismo tiempo, la empresa especializada en pruebas de software Antithesis logró reproducir el error de forma independiente utilizando pruebas basadas en propiedades (property-based testing). El sistema generó de forma automática secuencias masivas de operaciones aleatorias de escritura y checkpoint simultáneos, vigilando dos reglas de oro: “las escrituras confirmadas nunca deben perderse” y “la base de datos nunca debe corromperse”. Las herramientas detectaron la violación en las versiones antiguas y confirmaron el comportamiento correcto en la versión corregida. Lo que a un humano no se le habría ocurrido, la máquina lo descubrió por fuerza bruta.

La solución y una falsa alarma

La corrección en sí requirió modificar un solo punto del código: añadir una verificación dentro de la función de checkpoint para comprobar si otro hilo había reiniciado el estado del WAL y, en tal caso, abortar la operación de forma segura. El parche se lanzó oficialmente en la versión 3.51.3 de SQLite.

Pero la historia no terminó ahí. Cuando Tailscale desplegó la versión corregida, su panel de control se tiñó de rojo con alertas de corrupción. Por suerte, resultó ser una falsa alarma: una sutil anomalía de índices generada por versiones anteriores fue sacada a la luz por una optimización de la nueva versión. El equipo de SQLite retiró de inmediato esa versión y publicó un compilado limpio con la corrección del WAL-Reset únicamente. Por su parte, Tailscale ajustó la estructura de sus datos para evitar la anomalía secundaria. Corregir un error a menudo saca a relucir otros problemas escondidos, una reacción en cadena habitual en la ingeniería de software.

El paso definitivo llegó al final. Para confirmar al cien por cien que el fallo había ocurrido realmente en su entorno de producción, Tailscale añadió una alerta que registraba cualquier choque entre una escritura y un reinicio de WAL. Tras dos meses de silencio, la alarma sonó, demostrando que la condición de carrera de 16 años había intentado repetirse pero fue detenida con éxito por el parche. Durante los cuatro meses siguientes no volvió a registrarse ni una sola corrupción.

Los componentes más fiables merecen la mayor inspección

Esta historia deja una lección profunda para la ingeniería de software. SQLite es una de las piezas de software más confiables del mundo; ningún desarrollador dudaría de su estabilidad al iniciar un proyecto. Sin embargo, fue precisamente esa confianza ciega la que permitió que un fallo grave permaneciera oculto durante 16 años en miles de millones de dispositivos. Cuando los cimientos fallan, toda la estructura construida encima se tambalea y nadie piensa en mirar los cimientos.

La actitud de los ingenieros de Tailscale al abordar este problema fue aplaudida por toda la comunidad técnica. El término más repetido en los comentarios fue “refreshing” (reconfortante): en lugar de buscar culpables, contrataron el soporte oficial de SQLite, financiaron el desarrollo de la herramienta de diagnóstico de código abierto y compartieron sus hallazgos con el resto del mundo.

Que una empresa invierta recursos en patrocinar herramientas de diagnóstico para proyectos de código abierto es algo poco común en el mundo corporativo. Para los usuarios comunes, este caso recuerda que detrás de los programas invisibles que funcionan sin descanso en nuestros teléfonos hay ingenieros dedicados durante meses a erradicar errores que parecen “prácticamente imposibles”.

Un fallo de 16 años ha sido resuelto. Pero, ¿dónde estará el próximo? Tal vez esté esperando pacientemente en alguna de las aplicaciones en las que más confías hoy.

Enlaces de referencia:

  • Tailscale: Análisis del error WAL-Reset de SQLite
  • Antithesis: Breaking the WAL
  • Discusión en HN (item?id=49272832)