我想查找在MySQL数据库中最近一小时内被修改过的表。我该怎么做?
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';
对于每个您想要检测更改的表,您需要有一个保存上次更改时间戳的列。
对于表中的每个插入或更新,您需要使用当前日期和时间更新该列。
或者,您可以设置一个触发器,在每次插入或修改时自动更新该列。这样,您就不必修改所有查询。
一旦这样做了,要查找最近一小时内表中行是否已被修改,请执行查询
select count(*) from mytable where datemod>subtime(now(),'1:0:0')
对于您想要检查的每个表格都重复此操作。
InnoDB目前仍缺乏本地机制来检索此信息。在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
inndb_files_per_table = ON
(无论如何都建议这样做),并检查基础数据文件的最后修改时间。
在大多数默认安装中,这些文件位于/var/lib/mysql/[database_name]/*.ibd
下。
请注意,如果您决定采用此方法,您需要重新创建现有表格以应用新的设置。
update_time
TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP”,如果省略,则在插入数据时会自动设置它。 - DustWolf大约1.5年前,我在DBA StackExchange上回答过类似的问题:如何快速检查InnoDB表是否已更改。
基于那篇旧文章的答案,我建议采取以下措施:
这是一次性设置。您需要将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;
ls
命令有一个选项可以以秒为单位检索UNIX时间戳。对于InnoDB表mydb.mytable
$ cd /var/lib/mysql/mydb
$ ls -l --time-style="+%s" mytable.ibd | awk '{print $6}'
您可以计算UNIX_TIMESTAMP(NOW()) - (.ibd文件的时间戳
),并查看它是否小于或等于3600秒。
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'
UPDATE_TIME
,但该值不会在mysqld
重新启动后持续存在。 - dotancohen