Message indiquant la fin d'une requete MYSQL

Fermé
Drone - 19 déc. 2022 à 15:02
 Drone - 4 janv. 2023 à 16:56

Bonjour,

J'essaie de faire un script qui restaure une base de données puis affiche un message après que la base de données ait été restaurée pour indiquer à l'utilisateur qu'il peut démarrer le logiciel utilisant cette base de données, mais je galère à trouver une solution pour indiquer la fin de la restauration. J'utilise le moteur Innodb.

Je cherche une solution qui fonctionne en batch, powershell ou VBscript.

J'ai essayé la commande SQL show processlist mais il y a aucun process de visible pendant le script de restauration, j'ai également essayé de me fier à la variables Queries du moteur de BDD mais celle ci se change immédiatement alors qu'il faut ensuite attendre longtemps avant que toutes les requêtes soient exécutées.

A ma dernière tentative je regardais la date de modification du fichier general_log mais la date du fichier ne change pas, sauf au moment ou je l'actualise, j'ai donc créé un script pour essayer de l'actualiser toutes les 10 secondes pour voir le changement mais j'ai également l'impression que toutes les requêtes se chargent avant même qu'elles soient finit d'être exécutée.

Si vous avez une idée..

Merci

:: ****************************************************************************
:: Init
@ECHO off
setlocal enableextensions disabledelayedexpansion
:: ****************************************************************************
:: Restauration MYSQL
:: Mise en variable du nom du dernier fichier SQL sauvegardé (qui sera restauré)
set "filename="
    for /f "delims=" %%a in ('dir /b /o-d "C:\ProgramData\MySQL\MySQL Server 5.7\backup\data\*.sql" 2^>nul') do (
        if not defined filename set "filename=%%a"
    )
set BDD=bdd_1
:: Mise en variable VAR de la date du fichier general_log et activation de la fonction general_log
for /f "delims=" %%i in ('"forfiles /p "C:\ProgramData\MySQL\MySQL Server 5.7\Data\general_log" /m CRYSTO_TEREOS_C.log /c "cmd /c echo @ftime" "') do set VAR=%%i
"C:\Program Files\MySQL\MySQL Server 5.7\bin\mysql.exe" -u user -pmdp -e "SET GLOBAL general_log = 'ON'"
"C:\Program Files\MySQL\MySQL Server 5.7\bin\mysql.exe" -u user -pmdp %BDD% < "DATA\%filename%"1>>Restore_log_BDD>txt && (
echo Avant la boucle
GOTO _BOUCLE
) || (
echo "%DATE% %TIME% - restore error type %ERRORLEVEL%" >> Restore_log_BDD.txt
msg "%username%" "The restoration was not completed successfully."
)


:_BOUCLE
::Boucle pour attendre une modification du fichier general_log indiquant la fin de la transaction SQL
timeout 10
::Script qui créé un script vbs temporaire pour l'executer ensuite puis le supprimer, ce script permet de simuler la touche F5 dans un dossier
> "%temp%\run_vbs.vbs" <nul (
      set /p "'=WScript.CreateObject("WScript.Shell").AppActivate WScript.CreateObject("WScript.Shell").CurrentDirectory : "
      set /p "'=WScript.Sleep 3000: WScript.CreateObject("WScript.Shell").SendKeys "{F5}""
    )  & cd /d "C:\ProgramData\MySQL\MySQL Server 5.7\Data\general_log\." && %__AppDir__%cscript.exe //nologo "%temp%\run_vbs.vbs"
2>nul del/q /f "%temp%\run_vbs.vbs"

for /f "delims=" %%i in ('"forfiles /p "C:\ProgramData\MySQL\MySQL Server 5.7\Data\general_log" /m CRYSTO_TEREOS_C.log /c "cmd /c echo @ftime" "') do set VAR2=%%i
echo %VAR2%
IF "%VAR2%" NEQ "%VAR%" GOTO _1
GOTO _BOUCLE

:_1
echo "%DATE% %TIME% - BDD %filename% Restore was successful on BDD %BDD%" >> Restore_log_BDD.txt
msg "%username%" "The Database was successfully recovering, you can click OK then launch software."

Windows / Firefox 107.0

A voir également:

9 réponses

jee pee Messages postés 39585 Date d'inscription mercredi 2 mai 2007 Statut Modérateur Dernière intervention 19 avril 2024 9 225
Modifié le 19 déc. 2022 à 16:32

Bonjour,

Je me pose d'abord une question, est-ce que mysql.exe rend la main au script immédiatement, ou à la fin d'exécution du chargement ?

Car une commande simple Windows ne rend la main à la suite du script que quand elle est terminée. Exemple il faut fermer le bloc-notes pour terminer ce script .cmd

notepad.exe
echo fin notepad 1
pause

Si mysql.exe fonctionne ainsi tu ne devrais pas avoir de soucis.

Tu devrais le tester avec un script du style et des fichiers .sql assez conséquents pour durer assez longtemps.

mysql.exe ...... <import1.sql
echo %time%
mysql.exe ...... <import2.sql
echo %time%
pause


Après il est difficile de bien suivre ton script, mais sortir d'une boucle FOR par un GOTO c'est une horreur (ou une erreur ;-) je ne vois pas comment tu réintègres la boucle initiale


1
jee pee Messages postés 39585 Date d'inscription mercredi 2 mai 2007 Statut Modérateur Dernière intervention 19 avril 2024 9 225
19 déc. 2022 à 16:56

En réétudiant ton script, je comprends que tu ne charges qu'un seul .sql, le dernier. Mon interrogation sur mysql.exe redonne la main au script immédiatement ou quand le sql est exécuté demeure.

0
jee pee Messages postés 39585 Date d'inscription mercredi 2 mai 2007 Statut Modérateur Dernière intervention 19 avril 2024 9 225
20 déc. 2022 à 19:03

J'ai effectué un test. Chargé une table avec un .csv de 3G0 et 20 millions de lignes. Les commandes d'export et d'import se terminent après exécution de l'opération, en respectivement 1 et 6 minutes. La commande dans le script attend la fin de l'exécution du programme.

D:\Dev\BDD\script>export.cmd
D:\Dev\BDD\script>SET prog=D:\Dev\UwAmp\bin\database\mysql-5.7.11\bin\mysqldump.exe
D:\Dev\BDD\script>SET host=LOCALHOST
D:\Dev\BDD\script>SET user=root
D:\Dev\BDD\script>SET mdp=root
D:\Dev\BDD\script>SET base=AUTO
D:\Dev\BDD\script>echo 18:03:36,69
18:03:36,69
D:\Dev\BDD\script>D:\Dev\UwAmp\bin\database\mysql-5.7.11\bin\mysqldump.exe -hLOCALHOST -uroot -proot AUTO auto  1>auto.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
D:\Dev\BDD\script>echo 18:04:35,72
18:04:35,72
______________________________________________________________________________________________
D:\Dev\BDD\script>import.cmd
D:\Dev\BDD\script>SET prog=D:\Dev\UwAmp\bin\database\mysql-5.7.11\bin\mysql.exe
D:\Dev\BDD\script>SET host=LOCALHOST
D:\Dev\BDD\script>SET user=root
D:\Dev\BDD\script>SET mdp=root
D:\Dev\BDD\script>SET base=AUTO
D:\Dev\BDD\script>echo 18:12:16,75
18:12:16,75
D:\Dev\BDD\script>D:\Dev\UwAmp\bin\database\mysql-5.7.11\bin\mysql.exe -hLOCALHOST -uroot -proot AUTO  0<auto.sql 1>auto.log
mysql: [Warning] Using a password on the command line interface can be insecure.
D:\Dev\BDD\script>echo 18:18:22,23
18:18:22,23

1

Bonjour et merci pour ta réponse Jee Pee !

Mysql.exe redonne la main immédiatement, j'ai essayé ton script avec le %time% et la réponse est immédiate, sous linux ils utilise une commande pipe viewer, ils font passer le fichier SQL d'abord dans le pipe viewer puis le pipe viewer transmet à la commande mysql, mais je n'ai pas vu d'équivalent sur Windows, certain utilise Cygwin mais je pensais pouvoir trouver une autre solution..

Oui je suis d'accord que c'est une horreur le Goto, il y a une seule base de données, du coup quand mysql n'est pas en défaut je sors sur le jeu de goto, c'est moche mais ça me permettait de faire rapidement ce que je voulais.. mise à part que le fichier general_log ne s'actualise pas tout seul..

0

Re bonjour,

J'ai trouvé une commande qui me satisfait, la commande call me permet d'obtenir la taille du fichier general_log avec la variable %~z1 que je compare toutes les minutes, il me suffit d'attendre 5min après la fin de la modification general_log pour être certain que toutes les requêtes ont fini d'être executées. (Je n'aurai pas d'autre requêtes mise à part la restauration)

:: récupération taille du fichier general_log
:_BOUCLE
timeout 60
call :setsize "C:\ProgramData\MySQL\MySQL Server 5.7\Data\general_log"
:setsize
IF "%VAR1%" EQ %~z1 GOTO _ESCAPE
set VAR1=%~z1
GOTO _BOUCLE

:_ESCAPE
timeout 300
echo "OK.."

Merci

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
jee pee Messages postés 39585 Date d'inscription mercredi 2 mai 2007 Statut Modérateur Dernière intervention 19 avril 2024 9 225
20 déc. 2022 à 15:14

J'ai du mal à comprendre que pour savoir si l'import est terminé il faille passer par de tels expédients. Mais je ne suis pas vraiment utilisateur de Mysql. J'ai un environnement uWamp pour répondre à des questions html, php ou sql. Je viens pour la première fois de faire du sql en ligne de commande, mais avec des tables de 3 lignes le temps de traitement de quelques millisecondes n'est pas probant. Je vais essayer de charger une grosse table, et peut être tester l'import/export, où il est possible que le sql contienne des commandes particulières lançant l'opération en arrière plan.


0

Si ça peut t'aider voici les informations que j'ai :
Mysql innodb traite les requetes dans un cache en mémoire RAM qui discute avec un fichier ibdata et deux fichiers de log (transactions de données), le fichier ibdata est une zone de stockage contenant plein d'information (tampon de données, tampon de modification, journaux d'annulation, il peut même contenir par les index et données des tables si l'innodb n'est pas configuré en file_per_table.
https://dev.mysql.com/doc/refman/8.0/en/innodb-architecture.html

De mon point de vue, ce système de cache et de fichier ibd conteneur masque facilement les requêtes.

Il y a des requêtes SQL comme show processlist qui sont censé aidé à voir ou en est la requete mais de mes essais ça n'affichait rien..

La version SQL entreprise d'oracle a des outils pour vérifier des métriques comme les opérations d'écriture en attente, mais pas dans la version gratuite.

0

Bonsoir, Merci je réessaierai de nouveau des que possible (pas avant janvier à cause d'autres tâches urgentes. ????)

Est ce que les fichiers ibd dans programdata/mysql/mysql 5.7/data/databasename/*.idb ont également une date de modification qui correspond à la date trouvé dans le code ?

Merci en tout cas ????

0
jee pee Messages postés 39585 Date d'inscription mercredi 2 mai 2007 Statut Modérateur Dernière intervention 19 avril 2024 9 225
21 déc. 2022 à 11:47

Pour tester, réalise un script basique comme moi,

echo %TIME%
mysql.exe <save.sqql
echo %TIME%

0

Bonjour,

Je reviens après avoir pu faire quelques tests.

Effectivement mysql attend d'avoir mis ses requêtes en mémoire avant de donner la main.

J'avais un problème avec l'ancien fichier SQL qui me faisait une erreur "Incorrect string value: '\xC3\xA9ratu", du coup ça me redonnait la main immédiatement  bien que les requêtes continuaient...

J'ai pris une BDD de plus de 1.8go pour bien observer, j'obtiens au minimum 5 min de différence entre l'heure de modification du fichier et l'heure du deuxième %TIME%, cela signifie qu'il y a un temps pour que les requêtes mises en mémoire se finissent..

SHOW FULL PROCESSLIST ne renvoit plus rien et mon export de log dans general_log se finit également même si ça continue à écrire sur les fichiers..

Du coup j'ai trouvé une solution, je compare la date de modification toutes les x minutes du fichiers ibdata, si ça ne se modifie plus c'est qu'il n'y a plus d'écriture. J'ai vu que 30 secondes étaient suffisant pour observer une modification de la date du fichier ibdata.

for /f "delims=" %%i in ('"forfiles /p "C:\ProgramData\MySQL\MySQL Server 5.7\Data" /m ibdata1 /c "cmd /c echo @ftime" "') do set VAR=%%i
timeout 30
for /f "delims=" %%i in ('"forfiles /p "C:\ProgramData\MySQL\MySQL Server 5.7\Data" /m ibdata1 /c "cmd /c echo @ftime" "') do set VAR2=%%i
IF "%VAR2%" EQU "%VAR%" echo "Requête fini"

Merci de m'avoir aidé.

0