2010-03-22 19 views
30

Quiero averiguar qué tablas se han modificado en la última hora en una base de datos MySQL. ¿Cómo puedo hacer esto?Consulta para buscar tablas modificadas en la última hora

+1

hacer sus tablas tienen una columna de marca de tiempo cuando los datos se cambian? – TomTom

+0

Creo que la mayoría de ellos, si no todos, tienen un campo "creado". No estoy seguro si eso responde su pregunta; la base de datos es de un sitio web que no desarrollé pero que tengo que mantener, así que estoy un poco perdido. –

+0

¿Puedes describir el caso de uso? podría haber una mejor solución a lo que quiere lograr –

Respuesta

54

MySQL 5.x puede hacerlo a través de la base de datos INFORMATION_SCHEMA. Esta base de datos contiene información sobre las tablas, vistas, columnas, etc.

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

devuelve todas las tablas que se han actualizado (UPDATE_TIME) en la última hora. También puede filtrar por nombre de base de datos (columna TABLE_SCHEMA).

una consulta de ejemplo:

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'; 
+0

¡Gracias! Eso hace exactamente lo que necesitaba –

+0

+1, una buena manera de hacerlo. –

+23

Tenga en cuenta que este enfoque solo funciona para las tablas MyISAM, no para InnoDB. –

5

Para cada tabla que se desea detectar el cambio, es necesario tener una columna que tiene marca de tiempo del último cambio.

Por cada inserción o actualización en la tabla, es necesario actualizar esa columna con la fecha y la hora actuales.

Alternativamente, se puede configurar un trigger que actualiza la columna automáticamente en cada inserción o modificar. De esta manera, no tiene que modificar toda su consulta.

Una vez que esto funciona, para averiguar si las filas de una tabla se han modificado en la última hora, realizar la consulta

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

Repetir para cada tabla que desea comprobar.

4

InnoDB aún carece actualmente de un mecanismo nativo es posible recuperar esta información. En el related feature request at MySQL, alguien aconseja configurar AFTER [all events] desencadenantes en cada tabla que se va a supervisar. El gatillo emitiría una instrucción como

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

en una tabla como esta:

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

Alternativamente, si una ligera inexactitud en estos datos (en el intervalo de un segundo) es aceptable, y si ha leído el acceso a los archivos de datos MySQL, puede cambiar a una configuración donde inndb_files_per_table = ON (recomendado en cualquier caso) y comprobar la última hora de modificación de los archivos de datos subyacentes.

Estos archivos se encuentran bajo /var/lib/mysql/[database_name]/*.ibd en la mayoría de las instalaciones por defecto.

Atención, si usted decide tomar esta ruta, es necesario recreate existing tables para la nueva configuración de aplicar.

+0

Es posible que desee utilizar el tipo de datos TIMESTAMP en lugar de DATETIME. Definirlo como "' update_time' TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP" ... y se ajustará automáticamente al insertar los datos si se omite. – DustWolf

0
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' 
3

que han respondido a una pregunta de este tipo en el DBA StackExchange hace alrededor de 1,5 años; Fastest way to check if InnoDB table has changed.

Con base en esa vieja respuesta, recomiendo el siguiente

Flushing le escriba disco

Esta es la configuración de una sola vez. Es necesario establecer innodb_max_dirty_pages_pct a 0.

En primer lugar, añadir esto a/etc/mi.CNF

[mysqld] 
innodb_max_dirty_pages_pct=0 

A continuación, ejecute esto para evitar tener que reiniciar MySQL:

mysql> SET GLOBAL innodb_max_dirty_pages_pct = 0; 

Obtener Marca de tiempo de la tabla InnoDB de .ibd file

ls tiene la opción de recuperar la marca de tiempo UNIX en segundos. Para una tabla InnoDB mydb.mytable

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

A continuación, puede calcular UNIX_TIMESTAMP(NOW()) - (timestamp of the .ibd file) y ver si es 3600 o menos.

darle una oportunidad !!!

+0

¡Gracias, Rolando! Esto fue muy útil e informativo. – dotancohen

Cuestiones relacionadas