Cet article concerne principalement l'utilisation des capacités SQL de JMP, mais également XML, Linux, MythTV.
Documentation du générateur de requêtes SQL : https://www.jmp.com/support/help/14/query-builder.shtml#
Mythe TV https://www.mythtv.org/ est un programme open source (TANSTAAFL) qui peut enregistrer des émissions de télévision en direct à l'aide d'une carte tuner dans un PC (et un tas d'autres choses aussi). C'est un excellent moyen d'en apprendre davantage sur Linux et MySQL/MariaDB et d'éviter de regarder la télévision. L'implémentation utilise deux ordinateurs, un backend (ou plusieurs) qui fait l'enregistrement et un frontend (ou plusieurs) qui fait la surveillance. Une base de données SQL garde une trace de ce qu'il faut enregistrer et de ce qui a été enregistré.
https://code.mythtv.org/trac/ticket/12974#no1 décrit une raison pour laquelle il y a beaucoup de fichiers très anciens et très volumineux sur le disque backend MythTV qui ne sont pas visibles dans le frontend MythTV. Il indique qu'il existe un bogue MythTV autour du champ de base de données en attente de suppression qui empêche la suppression du fichier si MythTV plante entre le moment où le champ est défini et le fichier est supprimé.
Par exemple, en utilisant Linux ls commande pour répertorier certains fichiers, voici un exemple de 3 Go (nous sommes en décembre 2019 ; seulement environ deux semaines de fichiers tiennent sur le disque 3T ; ces fichiers devraient avoir disparu depuis longtemps.)
-rw-r--r-- 1 mythtv mythtv 3.1G 21 mars 2018 1051_20180321073000.ts
Ou, après avoir effectué une importation de base de données,
JMP data table imported from database showing old, large filesTable de données JMP importée de la base de données montrant les anciens fichiers volumineux
L'importation de la base de données semble utile ; il place les colonnes (ou champs) les unes à côté des autres qui ont des valeurs liées et combine les informations de plusieurs tables de la base de données. Voici les étapes pour le faire.
Localisez les informations d'identification de la base de données.
Sur un système Linux exécutant l'interface MythTV, il y aura un fichier ~/.mythtv/config.xml .
<CONFIGURATION>
<LOCALHOSTNAME>my-unique-identifier-goes-here</LOCALHOSTNAME>
<DATABASE>
<PINGHOST>1</PINGHOST>
<HOST>closet.local</HOST>
<USERNAME>mythtv</USERNAME>
<PASSWORD>this is the pw</PASSWORD>
<DATABASENAME>mythconverg</DATABASENAME>
<PORT>3306</PORT>
</DATABASE>
<WAKEONLAN>
<ENABLED>0</ENABLED>
<SQLRECONNECTWAITTIME>0</SQLRECONNECTWAITTIME>
<SQLCONNECTRETRY>5</SQLCONNECTRETRY>
<COMMAND>echo 'WOLsqlServerCommand not set'</COMMAND>
</WAKEONLAN>
<UPNP>
<UDN>
<MEDIARENDERER>52d20477-fda1-4e42-9edd-5992bd0ca45f</MEDIARENDERER>
</UDN>
</UPNP>
</CONFIGURATION>
Copiez le fichier à un endroit où votre copie de JMP peut le lire et, avec JMP 15, ouvrez-le comme ceci :
// grab user name and password from the XML config file
dtConfig = Open( "F:\mythconfig.xml", invisible, XML Wizard( 0, guess( "huge" ) ) );
qui fera une table cachée comme celle-ci
JMP data table loaded from XML file with one row and columns for UserName, Password, and DatabaseNameTable de données JMP chargée à partir d'un fichier XML avec une ligne et des colonnes pour le nom d'utilisateur, le mot de passe et le nom de la base de données
Closet.local est le nom de l'hôte principal, mythtv est le nom d'utilisateur SQL qui a accès à la base de données mythconverg et le 3306 est le port par défaut, il ne sera donc pas nécessaire.
Créez un DSN à l'aide de l'administrateur de source de données ODBC de Windows.
Vous avez probablement besoin des pilotes 64 bits et vous devrez peut-être les télécharger. https://dev.mysql.com/downloads/connector/odbc/ ou peut-être https://downloads.mariadb.org/connector-odbc/+releases/ . Je suis à peu près sûr d'exécuter MariaDB sur mon serveur principal et d'utiliser le connecteur MySQL sur le frontend. https://www.google.com/search?q=mysql+vs+mariadb
The Windows ODBC Data Source Administrator sets up a DSNL'administrateur de source de données ODBC de Windows configure un DSN
Appuyez sur configurer et ajoutez quelques champs ; Je pense que ceux-ci peuvent tous être remplacés via une chaîne de connexion plus tard. Mon VirtualBox, mon réseau et mon serveur ne sont pas satisfaits de closet.local pour le nom du serveur, donc l'adresse IP en pointillé est utilisée. Vous pouvez saisir l'utilisateur et le mot de passe, tester la connexion et voir les noms de bases de données disponibles. Le JSL ci-dessous va remplacer ceux-ci.
The ODBC Connector dialog supplies some information that can be overridden laterLa boîte de dialogue Connecteur ODBC fournit des informations qui peuvent être remplacées ultérieurement
Découvrez les noms de table dans les bases de données MythTV
Grâce à un exemple de @briancorcoran pour montrer la voie avec le prochain morceau de JSL.
https://community.jmp.com/t5/Discussions/How-do-I-get-the-list-of-the-databases-available-on-a-designated/mp/10589
// DSN=Mythtv comes from the windows ODBC Data Source Administrator applet
dt = Open Database(
"DSN=Mythtv;UID=" || dtConfig:UserName[1] || ";PWD=" || dtConfig:Password[1],
"SHOW tables from " || dtConfig:DatabaseName[1] || ";",
"tables in " || dtConfig:DatabaseName[1]
);
Ce JSL utilise la table de données dtConfig JMP ouverte à partir du fichier de configuration XML, ci-dessus, pour obtenir le mot de passe réel et d'autres informations pour remplacer le DSN (qui est également nommé mythtv, sans rapport avec le nom d'utilisateur.) L'exemple de Brian utilisait SHOW DATABASES. Cette JSL utilise SHOW TABLES FROM mythconverg pour obtenir les plus de 80 tables de la base de données mythtv nommée mythconverg.
(SQL peut avoir plusieurs bases de données et une base de données peut avoir plusieurs tables. Les bases de données n'interagissent pas entre elles, mais les tables d'une base de données ont souvent des clés en commun qui permettent de joindre deux tables. Donc, une base de données pour les animaux de compagnie, une base de données pour les recettes et une base de données pour MythTV. Dans la base de données MythTV, des tableaux qui décrivent les programmes à enregistrer et des tableaux qui décrivent les programmes qui ont été enregistrés et plein d'autres tableaux...)
A JMP data table from Open Database(...) showing the 88 table names in the databaseUne table de données JMP d'Open Database(...) montrant les 88 noms de table dans la base de données
commencer à réfléchir à la forme de la base de données
Si vous faites cela mal ET écrivez dans la base de données, vous corromprez la base de données. Tu pourrais aller lire le code source pour MythTV et peut-être même trouver un document expliquant le fonctionnement des tableaux, ou vous pouvez poser la question passionnante : pourrai-je encore regarder la télévision enregistrée demain ? Ce qui suit est la voie passionnante.
Parcourez les noms de table de la base de données dans la table de données ci-dessus et voyez s'il y en a des intéressants. Il y en a, mais on ne sait pas encore ce qu'ils représentent.
two of the high lighted table names, record and recorded, look promisingdeux des noms de table en surbrillance, record et enregistré, semblent prometteurs
Voici un moyen facile de jeter un coup d'œil sur les tables et leurs colonnes et un peu de leurs données.
Fichier→Base de données→OpenTable
The OpenTable dialog opens one database table into a JMP data tableLa boîte de dialogue OpenTable ouvre une table de base de données dans une table de données JMP
Il y a 50 colonnes dans ce tableau, mais celle qui saute est la description :
The record table seems to describe what to recordLe tableau d'enregistrement semble décrire ce qu'il faut enregistrer
Ce qui est une description de ce qu'il faut enregistrer (ou peut-être de ce qu'il ne faut pas enregistrer… j'ai écrit cette règle.) Ce n'est pas le tableau dont j'ai besoin.
Qu'en est-il de la table nommée enregistrée ?
The recorded table seems to be a list of programs that were recordedLe tableau enregistré semble être une liste de programmes qui ont été enregistrés
Cela ressemble à un tableau de programmes enregistrés. Ce sera un point de départ.
Rejoignez quelques tables pour obtenir tout ce dont vous avez besoin au même endroit
Fichier → Base de données → Query Builder, choisissez la table enregistrée...
Query Builder starts by choosing a single tableQuery Builder commence par choisir une seule table
Lorsque vous appuyez sur SUIVANT, vous obtenez cet incroyable @Eric_Hill fenêtre intermédiaire :
The amazing Select Tables windows can view other tables and join them to the first tableLes étonnantes fenêtres de sélection de tables peuvent afficher d'autres tables et les joindre à la première table
Cette fenêtre sert à explorer les tables. Ne cliquez pas encore sur Build Query, cela vous amènera à une fenêtre où vous sélectionnerez des colonnes. Avant cela, utilisez cette fenêtre pour vous joindre à d'autres tables.
(Vous pouvez revenir à cette fenêtre plus tard, mais vous devriez pouvoir trouver tout ce dont vous aurez besoin plus tard lors de votre première visite... peut-être.)
Clicking a table shows a snapshotCliquer sur un tableau affiche un instantané
Voici ce que j'ai fini par utiliser (presque, voir ci-dessous pour un autre changement):
Three more tables joined with the firstTrois autres tables jointes à la première
J'ai utilisé le fichier enregistré (sélectionné ci-dessus) pour obtenir la taille de fichier dont la base de données se souvient. Je pense que cette base de données n'est pas normalisée car le nom de base apparaît dans le fichier enregistré et enregistré ... https://en.wikipedia.org/wiki/Database_normalization
(Les boutons en bas sont différents parce que j'ai utilisé le bouton triangle rouge pour sélectionner plus de tables dans Build Query pour obtenir cette image... en appuyant sur OK, vous reviendrez à la fenêtre Build Query.)
Il y a beaucoup de puissance ici : vous pouvez contrôler la jointure avec le bouton du cercle bleu, vous pouvez voir un instantané de n'importe quelle table dans la colonne et vous pouvez prévisualiser le résultat de la jointure. Et toutes les tables sont répertoriées ! C'est là que l'énigme est résolue : quelles tables sont nécessaires et comment sont-elles reliées entre elles. Choisissez l'onglet Tableau instantané, sélectionnez un tableau dans la colonne de gauche et utilisez la flèche vers le bas pour afficher chaque tableau. Beaucoup de tables MythTV sont vides, ce qui signifie que je peux les ignorer.
Sélectionnez les colonnes à conserver
Il est temps de cliquer sur le bouton Créer une requête. Cette fenêtre vous permet de choisir les colonnes souhaitées et d'essayer la requête :
Build Query window chooses columns to keep in the JMP data tableLa fenêtre de création de requête choisit les colonnes à conserver dans la table de données JMP
Ce bouton double X supprime toutes les sélections de colonnes ; vous voudrez probablement cliquer sur le simple X pour supprimer uniquement la colonne sélectionnée. Déplacez les lignes décrivant les colonnes vers le haut et vers le bas pour ordonner les colonnes, et sélectionnez une colonne pour pré-trier les données.
choisissez Exécuter la requête, étudiez la table, repensez…
dans la boîte de dialogue ci-dessus, le triangle rouge à côté de Tables vous ramènera à la boîte de dialogue ajouter une autre table (l'incroyable). J'avais besoin d'une autre table pour vraiment comprendre ce qui se passait.
Added another table, recgroupAjout d'une autre table, recgroup
Le tableau recgroups a l'indicateur Groupe supprimé. Voici un peu le résultat (similaire au tableau original en haut.) Tous ces noms de base sont dans le groupe par défaut, pas le groupe supprimé.
The filesize column suggests there is a lot of space I might recoverLa colonne de taille de fichier suggère qu'il y a beaucoup d'espace que je pourrais récupérer
Que d'espace perdu !
Voici le JSL/SQL du script source dans le tableau. Remplacez <<
New SQL Query(
Connection( "ODBC:DSN=mythtv;SERVER=192.168.0.39;UID=mythtv;DATABASE=mythconverg;PORT=3306;PWD=%_PWD_%;"
),
QueryName( "recorded" ),
Select(
Column( "callsign", "t3" ),
Column( "channum", "t3" ),
Column( "starttime", "t1", Numeric Format( "m/d/y h:m:s", "0", "NO", "" ) ),
Column( "endtime", "t1", Numeric Format( "m/d/y h:m:s", "0", "NO", "" ) ),
Column( "title", "t1" ),
Column( "description", "t1" ),
Column( "autoexpire", "t1" ),
Column( "preserve", "t1" ),
Column( "deletepending", "t1" ),
Column( "recgroup", "t4" ),
Column( "basename", "t2" ),
Column( "filesize", "t2" ),
Column( "width", "t2" ),
Column( "height", "t2" ),
Column( "fps", "t2" ),
Column( "videoprop", "t5" ),
Column( "subtitletypes", "t5" )
),
From(
Table( "recorded", Alias( "t1" ) ),
Table( "recgroups", Alias( "t4" ),
Join( Type( Left Outer ),
EQ( Column( "recgroupid", "t1" ), Column( "recgroupid", "t4" ) )
)
),
Table( "recordedprogram", Alias( "t5" ),
Join(
Type( Left Outer ),
EQ( Column( "chanid", "t1" ), Column( "chanid", "t5" ) ) &
EQ(
Column("starttime","t1",Numeric Format( "m/d/y h:m:s", "0", "NO", "" ) ),
Column("starttime","t5",Numeric Format( "m/d/y h:m:s", "0", "NO", "" ) )
)
)
),
Table( "recordedfile", Alias( "t2" ),
Join( Type( Left Outer ),
EQ( Column( "recordedid", "t1" ), Column( "recordedid", "t2" ) )
)
),
Table( "channel", Alias( "t3" ),
Join( Type( Left Outer ),
EQ( Column( "chanid", "t1" ), Column( "chanid", "t3" ) )
)
)
),
Order By( Column( "starttime", "t1", Numeric Format( "m/d/y h:m:s", "0", "NO", "" ),
Order( "Ascending" ) )
)
) << Run;
J'ai donc besoin de faire un petit test : pour un seul fichier bloqué, appuyez sur la base de données pour réactiver l'expiration automatique et désactiver la suppression en attente. Et peut-être arrêter et redémarrer le backend. Ensuite, regardez et voyez si le fichier est supprimé, au cours des prochaines heures ou des prochains jours... cette partie du comportement de MythTV, la suppression juste à temps, est également déroutante.
H mmm. Mieux vaut y aller doucement. La taille totale du fichier dans la base de données est deux fois plus grand que le disque.Supprimons celui-ci : 1171_20180321043700.ts
Tout d'abord, faites une requête pour le trouver, à l'aide d'un filtre. Je vais dans cette voie parce que JMP peut faire la plupart du travail pour moi dans une interface graphique et je ne suis pas tout à fait à l'aise pour écrire le SQL sans aide. Je modifierai le SQL après que JMP ait fait le plus dur pour moi.
Add a filter to select a single basename (file)Ajouter un filtre pour sélectionner un seul nom de base (fichier)
Bon! Le filtre a ajouté la clause WHERE au SQL et exactement une ligne a été trouvée. Je pense qu'il est temps de copier le SQL du Générateur de requêtes dialogue; besoin d'ajouter le mythconverg. avant chaque nom de table :
// grab user name and password from the XML config file
dtConfig = Open( "F:\mythconfig.xml", invisible, XML Wizard( 0, guess( "huge" ) ) );
//https://community.jmp.com/t5/Discussions/How-do-I-get-the-list-of-the-databases-available-on-a-designated/m-p/10589
// dtConfig:UserName,Password,DatabaseName
//
// DSN=Mythtv comes from the windows ODBC Data Source Administrator applet
dbc=CreateDatabaseConnection("DSN=Mythtv;UID=" || dtConfig:UserName[1] || ";PWD=" || dtConfig:Password[1]);
rc=executesql(dbc,"\[
SELECT t3.callsign, t3.channum, t1.starttime, t1.endtime,
t1.title, t1.description, t1.autoexpire, t1.preserve,
t1.deletepending, t4.recgroup, t2.basename, t2.filesize,
t2.width, t2.height, t2.fps, t5.videoprop,
t5.subtitletypes
FROM mythconverg.recorded t1
LEFT OUTER JOIN mythconverg.recgroups t4
ON ( t1.recgroupid = t4.recgroupid )
LEFT OUTER JOIN mythconverg.recordedprogram t5
ON ( ( t1.chanid = t5.chanid ) AND ( t1.starttime = t5.starttime ) )
LEFT OUTER JOIN mythconverg.recordedfile t2
ON ( t1.recordedid = t2.recordedid )
LEFT OUTER JOIN mythconverg.channel t3
ON ( t1.chanid = t3.chanid )
WHERE ( ( ( t2.basename="1171_20180321043700.ts" ) ) )
ORDER BY t1.starttime ASC;
]\","one row");
Close Database Connection(dbc);
close(dtConfig,nosave);
show(nrows(rc)==1); // better only be one row
ATTENTION, UN CODE DANGEREUX SUIT, VOUS POURRIEZ EFFACER VOTRE BASE DE DONNÉES AVEC LA MISE À JOUR ET LE RÉGLAGE.
et remplacer SELECT... DEPUIS avec UPDATE et ajoutez une clause SET et supprimez ORDER BY :
// grab user name and password from the XML config file
dtConfig = Open( "F:\mythconfig.xml", invisible, XML Wizard( 0, guess( "huge" ) ) );
dbc=CreateDatabaseConnection("DSN=Mythtv;UID=" || dtConfig:UserName[1] || ";PWD=" || dtConfig:Password[1]);
rc=executesql(dbc,"\[
UPDATE mythconverg.recorded t1
LEFT OUTER JOIN mythconverg.recgroups t4
ON ( t1.recgroupid = t4.recgroupid )
LEFT OUTER JOIN mythconverg.recordedprogram t5
ON ( ( t1.chanid = t5.chanid ) AND ( t1.starttime = t5.starttime ) )
LEFT OUTER JOIN mythconverg.recordedfile t2
ON ( t1.recordedid = t2.recordedid )
LEFT OUTER JOIN mythconverg.channel t3
ON ( t1.chanid = t3.chanid )
SET t1.autoexpire=1, t1.deletepending=0
WHERE ( ( ( t2.basename="1171_20180321043700.ts" ) ) );
]\","update");
Close Database Connection(dbc);
close(dtConfig,nosave);
la récupération de la table montre à nouveau la mise à jour :
The UPDATE and SET workedLe UPDATE et le SET ont fonctionné
Je ne sais pas comment obtenir le statut de la mise à jour ; le rc était une valeur manquante et aucune table n'a été créée, ce qui est logique. Mais ça a marché…
Quelques minutes plus tard, le fichier est toujours présent. Je vais redémarrer le backend. Redémarré. Le fichier apparaît maintenant dans le frontend.
Part of the frontend GUI shows the ancient file is visible againUne partie de l'interface graphique frontale montre que l'ancien fichier est à nouveau visible
Je vais m'asseoir et voir s'il disparaît sur disque dans quelques jours. Ensuite, je travaillerai sur les autres comme celui-ci, et je verrai pourquoi la base de données semble penser qu'il y a 6T sur un disque 3T...
Quelques heures plus tard: ls : impossible d'accéder à '1171_20180321043700.ts' : aucun fichier ou répertoire de ce type
Comme indiqué ci-dessus (commentaire normalisé), le nom de fichier apparaît dans plusieurs tableaux. Mon plan pour nettoyer le 6T en un 3T plus réaliste suppose qu'il y a des entrées dans la table enregistrée qui font référence à des fichiers qui ne sont plus sur le disque. Plutôt que d'essayer de supprimer des enregistrements des deux tables (et peut-être plus ?), Je pense que je vais créer un fichier factice s'il n'y en a pas et laisser le code existant le traiter de la manière habituelle. Peut-être qu'une bonne première étape serait simplement d'ouvrir les tables de base de données enregistrées et enregistrées dans les tables de données JMP et d'identifier où il y a des fichiers manquants sur le disque et incohérents entre les tables.
Fichier → Base de données → OpenTable le fera. Supprimez toutes les colonnes à l'exception du nom de base et de l'ID enregistré, triez par ID enregistré, comparez les tables de données. Trois diffs sur lesquels cliquer. Facile.
Curieux : 1171_20180317233200.ts est enregistré, mais pas enregistré
et existe en tant que fichier de 0 octet -rw-rw-r-- 1 mythtv mythtv 0 4 avril 2018 1171_20180317233200.ts
Et il y a deux entrées avec un nom entièrement vide dans le fichier enregistré qui n'ont pas d'identifiant enregistré correspondant dans enregistré. Je ne veux probablement pas les nettoyer, je ne sais pas à quoi d'autres tables pourraient s'y référer.
Le fichier supprimé ci-dessus, 1171_20180321043700.ts , n'apparaît dans aucun des tableaux. Yay!
J'utiliserai enregistré comme vérité puisqu'il n'a pas d'enregistrements vierges. Je vais utiliser une formule de colonne avec la fonction fileexists() pour aider à voir ce qui se passe.
Graph; points at top represent real files on disk, points at bottom are files that are not on diskGraphique; les points en haut représentent de vrais fichiers sur le disque, les points en bas sont des fichiers qui ne sont pas sur le disque
Il est possible que je récupère beaucoup d'espace disque, mais il peut y avoir beaucoup de fichiers de longueur nulle ou proche de zéro dans ce cluster que je veux supprimer. C'est l'heure d'une pause, ça ne devrait pas commencer à 21h.
Pour répondre au « combien ? question, utilisez filesize() plutôt que fileexists(). Beaucoup de fichiers existent, mais sont de zéro octet, il n'y a donc qu'environ 0,3T (10% !) d'espace récupérable.
Phase 1 : ajouter des fichiers factices pour les fichiers inexistants afin que MythTV puisse les nettoyer plus tard. La raison pour laquelle les enregistrements restent dans la base de données lorsque MythTV ne trouve pas les fichiers est que MythTV suppose que les fichiers peuvent se trouver sur un disque indisponible et qu'ils deviendraient orphelins si l'entrée de la base de données était supprimée.
// actualsize is this formula:
// File Size( "f:/closet/" || :basename )
For Each Row(
If( :basename != "" & Is Missing( actualsize ),
If( !File Exists( "f:/closet/" || :basename ),
Show( :basename );
Save Text File( "f:/closet/" || :basename, "hi there" );// use “touch” on Linux
, // else
Throw( "oops" )
)
)
);
Write( "\!ndone" );
Phase 2 : récupérer une nouvelle copie de la base de données dans une table de données. Ça à l'air bon. Il est temps de retravailler le SQL pour voir si nous pouvons sélectionner uniquement les enregistrements à mettre à jour :
// grab user name and password from the XML config file
dtConfig = Open( "F:\mythconfig.xml", invisible, XML Wizard( 0, guess( "huge" ) ) );
dbc=CreateDatabaseConnection("DSN=Mythtv;UID=" || dtConfig:UserName[1] || ";PWD=" || dtConfig:Password[1]);
rc=executesql(dbc,"\[
SELECT t3.callsign, t3.channum, t1.starttime, t1.endtime,
t1.title, t1.description, t1.autoexpire, t1.preserve,
t1.deletepending, t4.recgroup, t2.basename, t2.filesize,
t2.width, t2.height, t2.fps, t5.videoprop,
t5.subtitletypes
FROM mythconverg.recorded t1
LEFT OUTER JOIN mythconverg.recgroups t4
ON ( t1.recgroupid = t4.recgroupid )
LEFT OUTER JOIN mythconverg.recordedprogram t5
ON ( ( t1.chanid = t5.chanid ) AND ( t1.starttime = t5.starttime ) )
LEFT OUTER JOIN mythconverg.recordedfile t2
ON ( t1.recordedid = t2.recordedid )
LEFT OUTER JOIN mythconverg.channel t3
ON ( t1.chanid = t3.chanid )
WHERE ( ( ( t1.deletepending=1 ) ) )
ORDER BY t1.starttime ASC;
]\","one row");
Close Database Connection(dbc);
close(dtConfig,nosave);
show(nrows(rc)==1);
Cela sélectionne environ la moitié des enregistrements, tous assez anciens, qui sont suspendus avec suppression en attente. Il est temps de devenir audacieux…
Phase 3 : faites-le.
ATTENTION, UN CODE DANGEREUX SUIT, VOUS POURRIEZ EFFACER VOTRE BASE DE DONNÉES AVEC LA MISE À JOUR ET LE RÉGLAGE.
// grab user name and password from the XML config file
dtConfig = Open( "F:\mythconfig.xml", invisible, XML Wizard( 0, guess( "huge" ) ) );
dbc=CreateDatabaseConnection("DSN=Mythtv;UID=" || dtConfig:UserName[1] || ";PWD=" || dtConfig:Password[1]);
rc=executesql(dbc,"\[
UPDATE mythconverg.recorded t1
LEFT OUTER JOIN mythconverg.recgroups t4
ON ( t1.recgroupid = t4.recgroupid )
LEFT OUTER JOIN mythconverg.recordedprogram t5
ON ( ( t1.chanid = t5.chanid ) AND ( t1.starttime = t5.starttime ) )
LEFT OUTER JOIN mythconverg.recordedfile t2
ON ( t1.recordedid = t2.recordedid )
LEFT OUTER JOIN mythconverg.channel t3
ON ( t1.chanid = t3.chanid )
SET t1.autoexpire=1, t1.deletepending=0
WHERE ( ( ( t1.deletepending=1 ) ) );
]\","update");
Close Database Connection(dbc);
close(dtConfig,nosave);
Les suppressions ne sont plus en attente et l'expiration automatique est de retour. Il est temps d'attendre et de voir.
Le lendemain matin : je pense que ça marche ; aurait dû prendre de meilleures notes. Voici les fichiers les plus anciens qui traînent encore avant que les émissions d'information du matin ne soient enregistrées (6h50 lundi):
-rw-r--r-- 1 mythtv mythtv 1.9G 22 mars 2018 1111_20180322080000.ts
-rw-r--r-- 1 mythtv mythtv 3.2G 22 mars 2018 1051_20180322080000.ts
-rw-rw-rw- 1 mythtv mythtv 1.1M 22 mars 2018 1111_20180322043700.ts.png
-rw-r--r-- 1 mythtv mythtv 11G 22 mars 2018 1171_20180322060700.ts
-rw-r--r-- 1 mythtv mythtv 5.6G 22 mars 2018 1111_20180322063000.ts
-rw-rw-rw- 1 mythtv mythtv 1.4M 22 mars 2018 1051_20180322033500.ts.png
-rw-r--r-- 1 mythtv mythtv 3.2G 22 mars 2018 1051_20180322070000.ts
-rw-r--r-- 1 mythtv mythtv 5.7G 22 mars 2018 1051_20180322060700.ts
-rw-r--r-- 1 mythtv mythtv 3.2G 22 mars 2018 1051_20180322053700.ts
-rw-r--r-- 1 mythtv mythtv 1.6G 22 mars 2018 1111_20180322053700.ts
-rw-r--r-- 1 mythtv mythtv 6.4G 22 mars 2018 1051_20180322043700.ts
-rw-r--r-- 1 mythtv mythtv 5.4G 22 mars 2018 1171_20180322043700.ts
-rw-rw-rw- 1 mythtv mythtv 1.4M 22 mars 2018 1171_20180322030000.ts.png
-rw-rw-rw- 1 mythtv mythtv 3.4M 22 mars 2018 1051_20180322030100.ts.png
-rw-r--r-- 1 mythtv mythtv 2.1G 22 mars 2018 1111_20180322043700.ts
-rw-rw-rw- 1 mythtv mythtv 511K 22 mars 2018 1111_20180322030000.ts.png
-rw-r--r-- 1 mythtv mythtv 6.6G 22 mars 2018 1051_20180322033500.ts
-rw-r--r-- 1 mythtv mythtv 3.8G 22 mars 2018 1111_20180322033500.ts
-rw-r--r-- 1 mythtv mythtv 3.3G 21 mars 2018 1171_20180322030000.ts
-rw-r--r-- 1 mythtv mythtv 3.7G 21 mars 2018 1051_20180322030100.ts
-rw-r--r-- 1 mythtv mythtv 2.4G 21 mars 2018 1111_20180322030000.ts
-rw-r--r-- 1 mythtv mythtv 3.3G 21 mars 2018 1051_20180321233000.ts
-rw-rw-rw- 1 mythtv mythtv 725K 21 mars 2018 1111_20180321200000.ts.png
-rw-rw-rw- 1 mythtv mythtv 2.6M 21 mars 2018 1051_20180321200000.ts.png
-rw-r--r-- 1 mythtv mythtv 2.9G 21 mars 2018 1051_20180321200000.ts
-rw-r--r-- 1 mythtv mythtv 1.8G 21 mars 2018 1111_20180321200000.ts
-rw-rw-rw- 1 mythtv mythtv 897K 21 mars 2018 1111_20180321163000.ts.png
-rw-r--r-- 1 mythtv mythtv 3.2G 21 mars 2018 1051_20180321163000.ts
-rw-r--r-- 1 mythtv mythtv 2.0G 21 mars 2018 1111_20180321163000.ts
-rw-r--r-- 1 mythtv mythtv 2.0G 21 mars 2018 1111_20180321160000.ts
-rw-r--r-- 1 mythtv mythtv 102M 21 mars 2018 1171_20180321160000.ts
-rw-r--r-- 1 mythtv mythtv 26G 21 mars 2018 1051_20180321110000.ts
-rw-r--r-- 1 mythtv mythtv 8.1G 21 mars 2018 1111_20180321110000.ts
-rw-r--r-- 1 mythtv mythtv 3.3G 21 mars 2018 1171_20180321100000.ts
-rw-r--r-- 1 mythtv mythtv 6.2G 21 mars 2018 1051_20180321100000.ts
-rw-r--r-- 1 mythtv mythtv 3.9G 21 mars 2018 1111_20180321100000.ts
-rw-rw-rw- 1 mythtv mythtv 743K 20 mars 2018 1281_20180321010000.ts.png
-rw-rw-rw- 1 mythtv mythtv 867K 20 mars 2018 1281_20180321002000.ts.png
drwxr-xr-x 12 racine racine 4.0K 20 mars 2018 ..
drwx------ 2 racine racine 16K 28 février 2018 perdu+trouvé
Programs recorded Friday will be recorded again today (Monday)Les programmes enregistrés vendredi seront enregistrés à nouveau aujourd'hui (lundi)
Ces trois programmes ont utilisé environ 40 Go vendredi dernier. A 9h30, les derniers 13.4G du tableau enregistré ont été supprimés. Je ne sais pas d'où vient l'autre 15G. Peut-être que la file d'attente de suppression contenait déjà des fichiers. Peut-être que ceux-ci ont été ajoutés dans l'ordre le plus ancien, après quelques autres ... J'essaie de ne pas enregistrer la télévision pendant la journée, donc ce sera peut-être ce soir avant de voir plus de fichiers supprimés. (Oui, ça arrive!) J'espère que les vignettes png (géantes) prennent soin d'elles aussi, trop tôt pour le dire.
Ce que j'ai appris sur JMP et SQL : il existe un moyen très simple de charger une table SQL dans une table de données JMP si aucune jointure n'est nécessaire (Fichier → Base de données → Ouvrir une table.) Il existe un très bon outil puissant pour lire des tables qui doivent être joint (Fichier → Base de données → Générateur de requêtes.) Les deux génèrent également un script JSL dans la table qui peut être réutilisé. Et, si vous avez besoin de mettre à jour la base de données, vous devrez utiliser la fonction ExecueSQL(), mais vous pouvez demander au générateur de requêtes de créer le SQL qui correspond presque à ce dont vous avez besoin, puis modifiez-le en faisant un UPDATE/SET.
J'ai effectué une partie du travail SQL en dehors de JMP dans le passé. J'ai trouvé très agréable d'utiliser JSL pour effectuer des travaux non SQL (créer des fichiers factices, créer des graphiques d'utilisation du disque) qui m'ont aidé à mieux comprendre la base de données.
https://code.mythtv.org/cgit/mythtv/tree/mythtv/programs/mythbackend/autoexpire.cpp point de départ pour le code source MythTV lié au nettoyage des anciens fichiers
https://en.wikipedia.org/wiki/Cord-cutting
On dirait que tout est revenu à la normale. Ce dernier graphique montre comment différentes stations ont optimisé leur bande passante disponible. La bande passante peut être divisée en un ou plusieurs canaux ; plus de canaux réduit signifie moins de données pour faire une image de haute qualité. L'une des stations locales a également choisi d'utiliser 720 60FPS plutôt que 1080 30FPS, ce qui signifie qu'il ne s'agit peut-être pas d'une comparaison de pommes à pommes. Chacun des canaux en surbrillance a probablement un ou plusieurs autres canaux de la même station avec laquelle il partage la bande passante. Les stations grisées en bas peuvent diffuser plusieurs vieux films en même temps ou des chaînes d'achat. Ils ont été retirés de la légende.
Lines with bigger slope have more bandwidth allocated to the pictureLes lignes avec une plus grande pente ont plus de bande passante allouée à l'image