我想知道在MySQL数据库的最后一小时内修改了哪些表。我怎么能这样做?
答案 0 :(得分:57)
MySQL 5.x可以通过INFORMATION_SCHEMA数据库完成此操作。此数据库包含有关表,视图,列等的信息。
SELECT *
FROM `INFORMATION_SCHEMA`.`TABLES`
WHERE
DATE_SUB(NOW(), INTERVAL 1 HOUR) < `UPDATE_TIME`
返回过去一小时内已更新的所有表(UPDATE_TIME)。您还可以按数据库名称(TABLE_SCHEMA列)进行筛选。
示例查询:
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';
答案 1 :(得分:5)
对于要检测更改的每个表,您需要一个包含最后一个更改时间戳的列。
对于表格中的每个插入或更新,您需要使用当前日期和时间更新该列。
或者,您可以设置trigger,在每次插入或自动修改时自动更新列。这样您就不必修改所有查询。
一旦这样做,要查明表中的行是否在过去一小时内被修改,请执行查询
select count(*) from mytable where datemod>subtime(now(),'1:0:0')
对要检查的每个表重复。
答案 2 :(得分:4)
InnoDB目前仍缺乏本地机制来检索此信息。在related feature request at MySQL中,有人建议在每个要监控的表上设置AFTER [all events]
个触发器。触发器将发出声明,例如
INSERT INTO last_update VALUE ('current_table_name', NOW())
ON DUPLICATE KEY UPDATE update_time = NOW();
在这样的表中:
CREATE TABLE last_update (
table_name VARCHAR(64) PRIMARY KEY,
update_time DATETIME
) ENGINE = MyISAM; -- no need for transactions here
或者,如果此数据中的轻微不准确(在一秒范围内)是可接受的,并且您对MySQL数据文件具有读取权限,则可以切换到inndb_files_per_table = ON
的设置(推荐用于任何情况)并检查基础数据文件的最后修改时间。
在大多数默认安装中,这些文件位于/var/lib/mysql/[database_name]/*.ibd
下。
请注意,如果您决定采用此路线,则需要recreate existing tables才能应用新设置。
答案 3 :(得分:4)
大约1。5年前,我在DBA StackExchange中回答了类似这样的问题:Fastest way to check if InnoDB table has changed。
基于那个旧答案,我推荐以下
这是一次性设置。您需要将innodb_max_dirty_pages_pct设置为0。
首先,将其添加到/etc/my.cnf
[mysqld]
innodb_max_dirty_pages_pct=0
然后,运行此命令以避免重启mysql:
mysql> SET GLOBAL innodb_max_dirty_pages_pct = 0;
.ibd file
ls
可以选择以秒为单位检索UNIX时间戳。对于InnoDB表mydb.mytable
$ cd /var/lib/mysql/mydb
$ ls -l --time-style="+%s" mytable.ibd | awk '{print $6}'
然后,您可以计算UNIX_TIMESTAMP(NOW()) - (timestamp of the .ibd file
)并查看它是否为3600或更低。
答案 4 :(得分: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'