web-dev-qa-db-fra.com

Requête pour trouver des tables modifiées au cours de la dernière heure

Je veux savoir quelles tables ont été modifiées au cours de la dernière heure dans une base de données MySQL. Comment puis-je faire ceci?

30
agente_secreto

MySQL 5.x peut le faire via la base de données INFORMATION_SCHEMA. Cette base de données contient des informations sur les tables, les vues, les colonnes, etc.

SELECT * 
FROM `INFORMATION_SCHEMA`.`TABLES`
WHERE 
    DATE_SUB(NOW(), INTERVAL 1 HOUR) < `UPDATE_TIME`

Renvoie toutes les tables mises à jour (UPDATE_TIME) au cours de la dernière heure. Vous pouvez également filtrer par nom de base de données (colonne TABLE_SCHEMA).

Un exemple de requête:

SELECT 
    CONCAT(`TABLE_SCHEMA`, '.', `TABLE_NAME`) AS `Table`, 
    UPDATE_TIME AS `Updated`
FROM `INFORMATION_SCHEMA`.`TABLES`
WHERE
    DATE_SUB(NOW(), INTERVAL 3 DAY) < `UPDATE_TIME`
    AND `TABLE_SCHEMA` != 'INFORMATION_SCHEMA'
    AND `TABLE_TYPE` = 'BASE TABLE';
55
rjh

Pour chaque table que vous souhaitez détecter, une colonne contenant le dernier horodatage est nécessaire.

Pour chaque insertion ou mise à jour dans la table, vous devez mettre à jour cette colonne avec la date et l'heure actuelles.

Alternativement, vous pouvez configurer un trigger qui met à jour automatiquement la colonne à chaque insertion ou modification. De cette façon, vous n'avez pas à modifier toute votre requête.

Une fois que cela fonctionne, pour savoir si les lignes d’une table ont été modifiées au cours de la dernière heure, exécutez la requête.

select count(*) from mytable where datemod>subtime(now(),'1:0:0')

Répétez cette procédure pour chaque table à vérifier.

5
David V.

À l'heure actuelle, InnoDB ne dispose toujours pas d'un mécanisme natif pour récupérer ces informations. Dans la demande de fonctionnalité liée à MySQL , quelqu'un vous conseille de définir des déclencheurs AFTER [all events] sur chaque table à surveiller. Le déclencheur émettrait une déclaration telle que

INSERT INTO last_update VALUE ('current_table_name', NOW())
ON DUPLICATE KEY UPDATE update_time = NOW();

dans un tableau comme celui-ci:

CREATE TABLE last_update (
    table_name VARCHAR(64) PRIMARY KEY,
    update_time DATETIME
) ENGINE = MyISAM; -- no need for transactions here

Sinon, si une légère inexactitude dans ces données (de l'ordre d'une seconde) est acceptable et si vous avez un accès en lecture aux fichiers de données MySQL, vous pouvez passer à un paramètre où inndb_files_per_table = ON (recommandé dans tous les cas). et vérifiez la dernière heure de modification des fichiers de données sous-jacents.

Ces fichiers se trouvent sous /var/lib/mysql/[database_name]/*.ibd dans la plupart des installations par défaut.

Veuillez noter que si vous décidez de suivre cette voie, vous devez recréer des tables existantes pour que le nouveau paramètre soit appliqué.

4
RandomSeed

J'ai répondu à une question comme celle-ci dans DBA StackExchange il y a environ 1,5 ans: Le moyen le plus rapide de vérifier si la table InnoDB a changé

Sur la base de cette ancienne réponse, je recommande ce qui suit

Flushing écrit sur le disque

Ceci est une configuration unique. Vous devez définir innodb_max_dirty_pages_pct sur 0.

Tout d'abord, ajoutez ceci à /etc/my.cnf

[mysqld]
innodb_max_dirty_pages_pct=0

Ensuite, lancez ceci pour éviter de devoir redémarrer mysql:

mysql> SET GLOBAL innodb_max_dirty_pages_pct = 0;

Obtenir l'horodatage du .ibd file de la table InnoDB

ls a la possibilité de récupérer l'horodatage UNIX en secondes. Pour une table InnoDB mydb.mytable

$ cd /var/lib/mysql/mydb
$ ls -l --time-style="+%s" mytable.ibd | awk '{print $6}'

Vous pouvez ensuite calculer UNIX_TIMESTAMP (NOW ()) - (timestamp of the .ibd file) et voir s'il s'agit de 3600 ou moins.

Essaie !!!

3
RolandoMySQLDBA
SELECT *
FROM  information_schema.tables
WHERE UPDATE_TIME >= SYSDATE() - INTERVAL 1 DAY  && TABLE_TYPE != 'SYSTEM VIEW'

SELECT * 
FROM information_schema.tables
WHERE UPDATE_TIME >= DATE_SUB(CURDATE(), INTERVAL 1 DAY) && TABLE_TYPE != 'SYSTEM VIEW'
0
user1140237