El incidente en Cloudflare fue desencadenado por una migración de esquema en ClickHouse, que introdujo una nueva clave de partición (namespace, day) para permitir la retención por inquilino. Aunque la suposición inicial era que las queries no se verían afectadas al filtrar por 'namespace', el aumento masivo en el número total de 'data parts' (de 30k a 160k por réplica) expuso un cuello de botella crítico y no obvio en los internals de ClickHouse.

La causa raíz principal fue la contención de locks y la ineficiencia en la planificación de queries. Inicialmente, cada hilo de planificación de queries adquiría un lock exclusivo (MergeTreeData) para copiar la lista completa de partes de la tabla, incluso para operaciones de solo lectura. Con cientos de queries concurrentes y decenas de miles de partes, esto creó una fila única (single-file line) para acceder a un recurso compartido, resultando en una degradación lineal del rendimiento a medida que aumentaba el número de partes. Las salvaguardas fallaron porque las métricas estándar (I/O, memoria, filas/partes leídas) no mostraban anomalías, ya que el problema no estaba en la ejecución de la query, sino en su fase de planificación.

La cascada de fallos se manifestó como una ralentización progresiva de los jobs de facturación, que son críticos en el tiempo. El aumento de la latencia en las queries SELECT, directamente correlacionado con el crecimiento del número de partes, amenazó con incumplir los plazos de facturación. Las optimizaciones se implementaron en tres fases: primero, cambiando el lock exclusivo a un shared lock para permitir concurrencia en la lectura de la lista de partes; segundo, eliminando la copia completa del vector de partes y utilizando una 'shared copy' cacheada; y tercero, implementando una búsqueda binaria para el filtrado de partes basado en el 'namespace', aprovechando la ordenación de la clave de partición. Estas medidas mitigaron la crisis inmediata, pero el artículo sugiere que el aumento continuo de partes podría generar otros problemas, como la carga en ZooKeeper.