C’est dur de prévoir le temps de transfert, ça dépend de plein de facteurs, la vitesse du disque principalement, c’est vraiment unique à chaque hardware.
La partie « transfert » n’est pas bloquante, Gladys peut-être utilisé en même temps.
En revanche, pendant la durée du transfert, les graphiques ne seront pas forcément disponibles, je dois encore décider si je laisse le double code à vie dans Gladys, où si on élimine le code et du coup le temps de la migration, les graphiques seront vide, ce qui est peut-être un tradeoff acceptable.
Par contre, ce qui est bloquant, c’est la partie « VACUUM » de la DB SQLite pour faire la réduction de la taille du disque « finale », et ça à voir si on le fait en forcé, ou si on demande à l’utilisateur de le faire. C’est sûrement plus intelligent de demander à l’utilisateur de le faire pour ne pas bloquer son instance.
Pour info, sur mon disque le VACUUM de ta DB de 13GB a duré 30 secondes, mais je suis sur un Macbook Pro du futur (10 coeurs CPU / SSD NVMe à 4.5GB/s de débit ), sur Pi ça va prendre un sacré moment je pense
Je te conseille de le faire quand même, tu vas recevoir des alertes tous les jours maintenant que la 4.44 est sortie.
Et je suis vraiment pas prêt de sortir la version avec DuckDB, j’avais parlé de mois
Journée de développement très productive aujourd’hui !
Pour vous tenir au courant, ce qui est codé :
Insertion des états dans DuckDB au lieu de SQLite
Requêtes API graphique via DuckDB
Suppression des tâches d’agrégations obsolètes
Tâche de migration de base de donnée
(Je code les tests en même temps, donc tout ce qui est fait est testé)
En cours de développement :
Sauvegarde et restauration Gladys Plus
La sauvegarde ne se fera pas en sauvegardant juste le fichier .duckdb, duckDB permet une API qui exporte un fichier compressé .parquet (Parquet, qu’est ce que c’est ?) un format dédié aux données time-serie. Ce format de fichier est néanmoins un poil plus lourd en stockage qu’un fichier DuckDB, après je suis les recommandations DuckDB et l’API officiel de export/import. Je ne pense pas qu’il soit smart de copier un fichier .duckdb à chaud pour faire une sauvegarde.
Feedback clean dans l’interface lors de la migration
L’interface doit-être très clair et expliquer ce qui se passe à l’utilisateur.
A faire :
Voir à quel moment on supprime les données dans SQLite. Pour l’instant j’ai choisi de ne pas les supprimer automatiquement pour éviter les pertes de données, et de laisser le choix à l’utilisateur de supprimer à posteriori lui même ces données via un bouton dans l’interface (pas encore codé)
Test en réel et optimisation de la migration sur des instances avec beaucoup de données et faible puissance CPU/disque
Test d’interruption et de reprise de migration
Test multi-jours/semaines en réel de l’utilisation de Gladys avec DuckDB. Objectif : vérifier la stabilité/zéro crash accepté
Waw! Pour un projet sur plusieurs mois… On sent la motivation .
Je vais déjà te rectifier : « en train de (…) vers DuckDB » sera plus correct et « un certain temps pendant lequel vos » plus joli. Ainsi, c’est fait !
Pour rappel, j’ai un RPi2 et un zero2W (équivalent RPi3) dispos pour des tests. Et je suis enseignant donc libre en été…
C’est propre comme interface, je trouve, cool. J’imagine que le bouton « purger les états SQLite » ne sera pas actionnable tant que la migration ne sera pas faite…
Et par contre, si je trouve bien qu’il faille une action manuelle pour supprimer les données de la base SQLite, je ne vois pas l’intérêt, d’un point de vue utilisateur, de devoir faire deux actions manuelles : purger, puis nettoyer. Il y a une raison à cela ?
Pas bête, je vais changer ça c’était pas le cas actuellement !
Purger c’est une action qui se fait en background et qui est non bloquante. Tu peux faire tourner la purge en pleine journée sans soucis, ça supprime par batch petit à petit. Ça peut prendre du temps par contre, mais c’est non bloquant.
Le nettoyage est une commande SQLite (« VACUUM ») qui est bloquante, Gladys est entièrement bloquée pendant son action. Sur un disque SSD NVMe très performant sur un mini PC, le blocage sera limité en temps.
Sur un SSD en USB sur un Pi, ou pire sur une carte SD, le blocage peut prendre plusieurs heures (c’est précisé du côté du bouton nettoyage)
Donc j’ai préféré séparer les deux actions pour que l’utilisateur ait le choix de timer quand il veut faire chaque action.
Si on met les deux à la chaîne, et que tu lance la purge, que Gladys tourne, puis 2h plus tard ça passe au nettoyage et que Gladys se bloque, l’utilisateur risque de ne pas comprendre et pensera que c’est un bug !
Après, la question du support d’armv6/v7 se pose, on a d’autres sujets qui ne fonctionnent plus sur armv6 (Node 20) notamment, et on va sûrement vite être poussé à abandonner cette plateforme… (fini les Pi Zero notamment, mais bon est-ce que Gladys a vraiment vocation a tourner sur ces machines, sachant que déjà sur un Pi 3/4 ça tourne pas terrible ^^)
Bon, je viens enfin de réussir à faire fonctionner l’image !
Par contre j’ai du passer d’une image Docker node-alpine à node-slim, DuckDB ne s’installe pas bien sur Alpine…
Pour l’instant, la taille de l’image Docker augmente pas mal, mais je pense qu’il y a des optimisations à faire.
En attendant, la migration DuckDB sur Pi 3 s’est bien passé :
2024-08-02T16:24:51+0200 <info> device.migrateFromSQLiteToDuckDb.js:39 (DeviceManager.migrateFromSQLiteToDuckDb) DuckDB: Migrating data from SQLite
2024-08-02T16:24:51+0200 <info> index.js:64 (Server.<anonymous>) Server listening on port 80
2024-08-02T16:24:51+0200 <info> device.migrateFromSQLiteToDuckDb.js:47 (DeviceManager.migrateFromSQLiteToDuckDb) DuckDB: Found 0 already migrated device features in DuckDB.
2024-08-02T16:24:51+0200 <info> device.migrateFromSQLiteToDuckDb.js:51 (DeviceManager.migrateFromSQLiteToDuckDb) DuckDB: Migrating 3 device features
2024-08-02T16:24:51+0200 <info> device.migrateFromSQLiteToDuckDb.js:8 (migrateStateRecursive) DuckDB : Migrating device feature = 91f39b3d-d747-4fd0-9880-8bc1e8f9067e, offset = 0
2024-08-02T16:24:51+0200 <info> device.migrateFromSQLiteToDuckDb.js:11 (migrateStateRecursive) DuckDB : Device feature = 91f39b3d-d747-4fd0-9880-8bc1e8f9067e has 0 states to migrate.
2024-08-02T16:24:51+0200 <info> device.migrateFromSQLiteToDuckDb.js:8 (migrateStateRecursive) DuckDB : Migrating device feature = 813c1830-b494-4f01-b339-1f287f621548, offset = 0
2024-08-02T16:24:54+0200 <info> device.migrateFromSQLiteToDuckDb.js:11 (migrateStateRecursive) DuckDB : Device feature = 813c1830-b494-4f01-b339-1f287f621548 has 34723 states to migrate.
2024-08-02T16:24:55+0200 <info> index.js:130 () DuckDB : Inserting chunk 0 for deviceFeature = 813c1830-b494-4f01-b339-1f287f621548.
2024-08-02T16:25:00+0200 <info> scene.checkCalendarTriggers.js:25 (SceneManager.checkCalendarTriggers) Checking calendar triggers at Fri, 02 Aug 2024 14:25:00 GMT
2024-08-02T16:25:02+0200 <info> index.js:130 () DuckDB : Inserting chunk 1 for deviceFeature = 813c1830-b494-4f01-b339-1f287f621548.
2024-08-02T16:25:09+0200 <info> index.js:130 () DuckDB : Inserting chunk 2 for deviceFeature = 813c1830-b494-4f01-b339-1f287f621548.
2024-08-02T16:25:16+0200 <info> index.js:130 () DuckDB : Inserting chunk 3 for deviceFeature = 813c1830-b494-4f01-b339-1f287f621548.
2024-08-02T16:25:19+0200 <info> device.migrateFromSQLiteToDuckDb.js:8 (migrateStateRecursive) DuckDB : Migrating device feature = 813c1830-b494-4f01-b339-1f287f621548, offset = 40000
2024-08-02T16:25:19+0200 <info> device.migrateFromSQLiteToDuckDb.js:11 (migrateStateRecursive) DuckDB : Device feature = 813c1830-b494-4f01-b339-1f287f621548 has 0 states to migrate.
2024-08-02T16:25:20+0200 <info> device.migrateFromSQLiteToDuckDb.js:8 (migrateStateRecursive) DuckDB : Migrating device feature = 24e039f2-d497-468a-87ee-517a1e67923d, offset = 0
2024-08-02T16:25:20+0200 <info> device.migrateFromSQLiteToDuckDb.js:11 (migrateStateRecursive) DuckDB : Device feature = 24e039f2-d497-468a-87ee-517a1e67923d has 10272 states to migrate.
2024-08-02T16:25:21+0200 <info> index.js:130 () DuckDB : Inserting chunk 0 for deviceFeature = 24e039f2-d497-468a-87ee-517a1e67923d.
2024-08-02T16:25:27+0200 <info> index.js:130 () DuckDB : Inserting chunk 1 for deviceFeature = 24e039f2-d497-468a-87ee-517a1e67923d.
2024-08-02T16:25:27+0200 <info> device.migrateFromSQLiteToDuckDb.js:8 (migrateStateRecursive) DuckDB : Migrating device feature = 24e039f2-d497-468a-87ee-517a1e67923d, offset = 40000
2024-08-02T16:25:27+0200 <info> device.migrateFromSQLiteToDuckDb.js:11 (migrateStateRecursive) DuckDB : Device feature = 24e039f2-d497-468a-87ee-517a1e67923d has 0 states to migrate.
2024-08-02T16:25:27+0200 <info> device.migrateFromSQLiteToDuckDb.js:76 (DeviceManager.migrateFromSQLiteToDuckDb) DuckDB: Finished migrating DuckDB.
Ma tâche « Supprimer les états dans SQlite » est peut-être trop aggressive, sur un Pi 3 sur carte SD ça rend Gladys difficilement utilisable pendant la migration, après ça reste un setup pas recommandé
@GBoulvin (et les autres!) Si tu veux tester cette fois-ci c’est bon, en revanche dispo uniquement sur architecture amd64 ou arm64 (pas de Pi Zero donc pour l’instant)
Ce que je te recommande si tu veux tester, c’est de faire ça totalement à côté de ta prod, le mieux ce serait sur une machine séparée de ta prod
Sinon, si tu n’as que ton Pi 4 de prod, il faut absolument faire ça sur un autre dossier que ta DB de prod, cette mise à jour est majeure et le rétropédalage sur l’image gladys:v4 actuellement en prod n’est pas possible
Je précise qu’ayant changé d’OS pour l’image Docker, certaines intégrations « natives » ne fonctionnent peut-être plus (ex: Bluetooth, ou autre), il y a de la QA à faire que je n’ai pas encore fait pour l’instant ^^
L’image fonctionne bien pour le moment. La migration de la base à pris environ 15 minutes.
Ma base de production sqlite fait 7Go, la duckdb 27Mo.
RPI4 8Go avec SSD
Premier retour, les valeurs ne sont pas tronquées / arrondies
Merci du retour @cicoub13 ! Tu l’as laissé tourner ou juste testé une fois ?
Pour les arrondis je suis au courant, j’avais fais une PR séparée car le souci est déjà présent en prod actuellement, mais je pense que je vais merger cette PR dans la PR DuckDB et refaire un build!