clickhouse-system-log-disk-exhaustion

Par divinevideo · divine-mobile

Corrigez les erreurs ClickHouse « Code: 243 Cannot reserve 1.00 MiB, not enough space » causées par les tables de logs système (`text_log`, `trace_log`, `processors_profile_log`, `query_log`) qui saturent le disque. Utilisez ce guide quand : (1) les insertions ClickHouse échouent avec l'erreur `NOT_ENOUGH_SPACE`, (2) le disque est plein à 100 % alors que les tables applicatives sont petites, (3) la base de données `system` est 10 à 100 fois plus volumineuse que les bases utilisateur, (4) Sentry signale des échecs d'insertion/commit par lots sur plusieurs tables simultanément. Couvre aussi bien ClickHouse auto-hébergé (opérateur Altinity sur K8s) que ClickHouse Cloud, avec des procédures de remédiation distinctes pour chaque cas.

npx skills add https://github.com/divinevideo/divine-mobile --skill clickhouse-system-log-disk-exhaustion

Épuisement du disque du journal système ClickHouse

Problème

Les tables de journal système interne de ClickHouse (text_log, trace_log, processors_profile_log, query_log, metric_log, asynchronous_metric_log) se remplissent sans limite avec un TTL par défaut de 180 jours, finissant par remplir le disque entier. Cela provoque l'échec de toutes les opérations INSERT avec Code: 243 - Cannot reserve 1.00 MiB, not enough space, se propageant simultanément sur toutes les tables d'application.

Contexte / Conditions déclenchantes

  • Message d'erreur : Code: 243. DB::Exception: Cannot reserve 1.00 MiB, not enough space. (NOT_ENOUGH_SPACE)
  • Symptômes : Tous les écritures échouent simultanément sur plusieurs tables ; les lectures peuvent encore fonctionner
  • Pattern Sentry : Plusieurs problèmes d'insertion/commit batch en lot apparaissent en même temps
  • Requête de diagnostic : SELECT database, formatReadableSize(sum(total_bytes)) FROM system.tables WHERE total_bytes > 0 GROUP BY database ORDER BY sum(total_bytes) DESC
    • Si la base de données system est 10 fois ou plus plus volumineuse que les bases de données d'application, c'est la cause
  • Symptôme supplémentaire ClickHouse Cloud : Les tables avec suffixe numéroté (trace_log_16, text_log_19) provenant des nœuds serveurs désaffectés s'accumulent et ne sont jamais nettoyées dans la fenêtre TTL

Solution

Diagnostic

-- Vérifier la taille des bases de données
SELECT database, formatReadableSize(sum(total_bytes)) as size
FROM system.tables WHERE total_bytes > 0
GROUP BY database ORDER BY sum(total_bytes) DESC;

-- Trouver les plus grandes tables système
SELECT name, formatReadableSize(total_bytes) as size
FROM system.tables
WHERE database = 'system' AND total_bytes > 100000000
ORDER BY total_bytes DESC LIMIT 20;

-- Vérifier l'utilisation du disque
SELECT name, formatReadableSize(free_space) as free, formatReadableSize(total_space) as total
FROM system.disks WHERE name = 'default';

Correction : ClickHouse auto-hébergé (accès kubectl)

Étape 1 : Si le disque est à 100% plein (TRUNCATE lui-même échoue avec NOT_ENOUGH_SPACE)

TRUNCATE a besoin d'espace disque temporaire. Quand le disque est vraiment à 100%, vous devez d'abord libérer l'espace au niveau du système de fichiers :

# Trouver et supprimer les tables orphelines avec suffixe _N (provenant d'anciens replicas)
kubectl exec $CH_POD -- du -sh /var/lib/clickhouse/data/system/*_0/

# Les détacher d'abord (important !), puis supprimer les données
kubectl exec $CH_POD -- clickhouse-client --query "DETACH TABLE system.text_log_0 PERMANENTLY"
kubectl exec $CH_POD -- bash -c "rm -rf /var/lib/clickhouse/data/system/text_log_0/"
# Répéter pour les autres tables _N jusqu'à avoir ~100 MB+ de libre

Étape 2 : Supprimer les partitions ou tronquer les tables

Les tables de journal système sont partitionnées par toYYYYMM(event_date). Supprimer d'abord les partitions plus anciennes (opérations plus petites), puis tronquer :

-- Vérifier les partitions
SELECT partition, formatReadableSize(sum(bytes_on_disk)) as size
FROM system.parts
WHERE database = 'system' AND table = 'text_log' AND active
GROUP BY partition ORDER BY partition;

-- Supprimer les anciennes partitions une à la fois
ALTER TABLE system.text_log DROP PARTITION 202601 SETTINGS max_partition_size_to_drop = 0;
ALTER TABLE system.text_log DROP PARTITION 202602 SETTINGS max_partition_size_to_drop = 0;

-- Ou tronquer les tables entières (nécessite l'override max_table_size_to_drop si > 50 GB)
TRUNCATE TABLE system.text_log SETTINGS max_table_size_to_drop = 0;
TRUNCATE TABLE system.trace_log SETTINGS max_table_size_to_drop = 0;
TRUNCATE TABLE system.processors_profile_log SETTINGS max_table_size_to_drop = 0;
TRUNCATE TABLE system.query_log SETTINGS max_table_size_to_drop = 0;
TRUNCATE TABLE system.metric_log SETTINGS max_table_size_to_drop = 0;
TRUNCATE TABLE system.asynchronous_metric_log SETTINGS max_table_size_to_drop = 0;

Étape 3 : Configurer le TTL pour éviter la récurrence

-- Définir un TTL de 3 jours sur toutes les principales tables de journal système
ALTER TABLE system.text_log MODIFY TTL event_date + INTERVAL 3 DAY SETTINGS materialize_ttl_after_modify = 0;
ALTER TABLE system.trace_log MODIFY TTL event_date + INTERVAL 3 DAY SETTINGS materialize_ttl_after_modify = 0;
ALTER TABLE system.processors_profile_log MODIFY TTL event_date + INTERVAL 3 DAY SETTINGS materialize_ttl_after_modify = 0;
ALTER TABLE system.query_log MODIFY TTL event_date + INTERVAL 7 DAY SETTINGS materialize_ttl_after_modify = 0;
ALTER TABLE system.metric_log MODIFY TTL event_date + INTERVAL 3 DAY SETTINGS materialize_ttl_after_modify = 0;
ALTER TABLE system.asynchronous_metric_log MODIFY TTL event_date + INTERVAL 3 DAY SETTINGS materialize_ttl_after_modify = 0;
ALTER TABLE system.part_log MODIFY TTL event_date + INTERVAL 3 DAY SETTINGS materialize_ttl_after_modify = 0;
ALTER TABLE system.query_views_log MODIFY TTL event_date + INTERVAL 3 DAY SETTINGS materialize_ttl_after_modify = 0;

Correction : ClickHouse Cloud (pas d'accès shell)

ClickHouse Cloud révoque toutes les permissions de modification sur system.* des rôles créés par l'utilisateur :

REVOKE INSERT, ALTER, CREATE TABLE, DROP TABLE, TRUNCATE, OPTIMIZE ON system.* FROM default_role

Vous NE POUVEZ PAS corriger ceci via SQL. Les seules options sont :

  1. Console ClickHouse Cloud (https://clickhouse.cloud/) : Accéder aux paramètres du service et réduire les TTL des journaux système à 3-7 jours
  2. Obtenir le mot de passe de l'utilisateur default depuis la console, puis exécuter les commandes ALTER TTL
  3. Support ClickHouse Cloud : Demander un nettoyage des journaux système

Pour identifier ClickHouse Cloud : chercher les tables avec suffixe numéroté (par exemple, trace_log_16, text_log_19) provenant des pods serveur en rotation. Aussi, system.disks affichera des chemins system-tables/mergetree/ avec 16 EiB (stockage objet).

Vérification

-- Après le nettoyage, vérifier l'utilisation du disque
-- Auto-hébergé :
SELECT formatReadableSize(free_space) FROM system.disks WHERE name = 'default';

-- Les deux : vérifier que la base système est maintenant petite
SELECT database, formatReadableSize(sum(total_bytes)) as size
FROM system.tables WHERE total_bytes > 0 GROUP BY database;

-- Tester que les écritures fonctionnent
INSERT INTO your_table (...) VALUES (...);

Notes

  • La limite de sécurité max_table_size_to_drop est par défaut 50 GB. Les tables plus volumineuses que cela nécessitent SETTINGS max_table_size_to_drop = 0 pour tronquer/supprimer.
  • Quand le disque est vraiment à 100%, même les opérations DDL échouent. Vous DEVEZ d'abord libérer l'espace au niveau du système de fichiers (détacher + supprimer les tables orphelines, ou supprimer les fichiers tmp).
  • DETACH TABLE ... PERMANENTLY est important avant de supprimer les fichiers de données - cela empêche ClickHouse d'essayer d'accéder aux fichiers supprimés.
  • materialize_ttl_after_modify = 0 empêche ClickHouse d'essayer immédiatement de réécrire toutes les données pour appliquer le TTL (ce qui nécessiterait l'espace disque que vous n'avez pas).
  • Sur ClickHouse Cloud, chaque rotation de nœud serveur laisse derrière elle des tables de journal système numérotées (par exemple, _16, _19) qui s'accumulent au fil du temps. Avec 65+ nœuds sur des mois, cela s'ajoute à des dizaines de GB.
  • Le text_log est typiquement le principal responsable car il enregistre au niveau trace/debug par défaut et inclut chaque ligne de journal du serveur ClickHouse.

Références

Skills similaires