繁体   English   中英

如何判断 MySQL 表的上次更新时间?

[英]How can I tell when a MySQL table was last updated?

在我页面的页脚中,我想添加诸如“上次更新 xx/xx/200x”之类的内容,此日期是某个 mySQL 表的最后一次更新时间。

最好的方法是什么? 是否有检索上次更新日期的功能? 每次需要这个值时都应该访问数据库吗?

在更高版本的 MySQL 中,您可以使用information_schema数据库告诉您另一个表何时更新:

SELECT UPDATE_TIME
FROM   information_schema.tables
WHERE  TABLE_SCHEMA = 'dbname'
   AND TABLE_NAME = 'tabname'

这当然意味着打开与数据库的连接。


另一种选择是在更新 MySQL 表时“触摸”特定文件:

关于数据库更新:

  • O_RDRW模式打开时间戳文件
  • 再次close

或者

  • 使用touch() ,PHP 等效于utimes()函数,来更改文件时间戳。

页面显示:

  • 使用stat()回读文件修改时间。

我很惊讶没有人建议跟踪每行的上次更新时间:

mysql> CREATE TABLE foo (
  id INT PRIMARY KEY
  x INT,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP 
                     ON UPDATE CURRENT_TIMESTAMP,
  KEY (updated_at)
);

mysql> INSERT INTO foo VALUES (1, NOW() - INTERVAL 3 DAY), (2, NOW());

mysql> SELECT * FROM foo;
+----+------+---------------------+
| id | x    | updated_at          |
+----+------+---------------------+
|  1 | NULL | 2013-08-18 03:26:28 |
|  2 | NULL | 2013-08-21 03:26:28 |
+----+------+---------------------+

mysql> UPDATE foo SET x = 1234 WHERE id = 1;

即使我们没有在 UPDATE 中提到它,这也会更新时间戳。

mysql> SELECT * FROM foo;
+----+------+---------------------+
| id | x    | updated_at          |
+----+------+---------------------+
|  1 | 1235 | 2013-08-21 03:30:20 | <-- this row has been updated
|  2 | NULL | 2013-08-21 03:26:28 |
+----+------+---------------------+

现在您可以查询 MAX():

mysql> SELECT MAX(updated_at) FROM foo;
+---------------------+
| MAX(updated_at)     |
+---------------------+
| 2013-08-21 03:30:20 |
+---------------------+

诚然,这需要更多的存储空间(TIMESTAMP 每行 4 个字节)。
但这适用于MySQL 5.7.15 版本之前的InnoDB 表,而INFORMATION_SCHEMA.TABLES.UPDATE_TIME则不行。

我没有 information_schema 数据库,使用 mysql 4.1.16 版,所以在这种情况下你可以查询:

SHOW TABLE STATUS FROM your_database LIKE 'your_table';

它将返回这些列:

| Name      | Engine | Version | Row_format | Rows | Avg_row_length 
| Data_length | Max_data_length | Index_length | Data_free | Auto_increment
| Create_time | Update_time | Check_time | Collation
| Checksum | Create_options | Comment |

如您所见,有一列名为“ Update_time ”的列显示了your_table的上次更新时间。

最简单的方法是检查磁盘上表文件的时间戳。 例如,您可以在您的数据目录下检查

cd /var/lib/mysql/<mydatabase>
ls -lhtr *.ibd

这应该首先为您提供最后一次修改表的所有表的列表。

有关最近表更改的列表,请使用:

SELECT UPDATE_TIME, TABLE_SCHEMA, TABLE_NAME
FROM information_schema.tables
ORDER BY UPDATE_TIME DESC, TABLE_SCHEMA, TABLE_NAME

我会创建一个触发器来捕获所有更新/插入/删除并在自定义表中写入时间戳,例如 tablename | 时间戳

只是因为我不喜欢直接读取数据库服务器内部系统表的想法

尽管有一个公认的答案,但我不认为这是正确的答案。 这是实现所需内容的最简单方法,但即使已经在 InnoDB 中启用(实际上文档告诉您仍然应该获取 NULL ...),如果您阅读 MySQL文档,即使在当前版本 (8.0) 中使用 UPDATE_TIME 也是不是正确的选择,因为:

当服务器重新启动或表从 InnoDB 数据字典缓存中被驱逐时,时间戳不会持久化。

如果我理解正确(现在无法在服务器上验证它),服务器重启后时间戳会重置。

至于真正的(而且,成本高昂)的解决方案,您有 Bill Karwin 的 CURRENT_TIMESTAMP解决方案,我想提出一个不同的解决方案,它基于触发器(我正在使用那个)。

您首先创建一个单独的表(或者您可能有其他一些可用于此目的的表),它将像存储全局变量(这里是时间戳)一样工作。 您需要存储两个字段 - 表名(或您想在此处保留为表 ID 的任何值)和时间戳。 拥有后,您应该使用此表 ID + 开始日期对其进行初始化(NOW() 是一个不错的选择 :))。

现在,您移动到要观察的表并使用以下或类似过程在 INSERT/UPDATE/DELETE 之后添加触发器:

CREATE PROCEDURE `timestamp_update` ()
BEGIN
    UPDATE `SCHEMA_NAME`.`TIMESTAMPS_TABLE_NAME`
    SET `timestamp_column`=DATE_FORMAT(NOW(), '%Y-%m-%d %T')
    WHERE `table_name_column`='TABLE_NAME';
END

操作系统层面分析:

查找数据库在磁盘上的存储位置:

grep datadir /etc/my.cnf
datadir=/var/lib/mysql

检查最近的修改

cd /var/lib/mysql/{db_name}
ls -lrt

应该适用于所有数据库类型。

a) 它将显示所有表格和最后更新日期

SHOW TABLE STATUS FROM db_name;

然后,您可以进一步询问特定表:

SHOW TABLE STATUS FROM db_name like 'table_name';

b) 在上面的例子中,你不能对 'Update_time' 使用排序,但使用 SELECT 你可以:

SELECT * FROM information_schema.tables WHERE TABLE_SCHEMA='db_name' ORDER BY UPDATE_TIME DESC;

进一步询问特定表:

SELECT * FROM information_schema.tables WHERE TABLE_SCHEMA='db_name' AND table_name='table_name' ORDER BY UPDATE_TIME DESC';

我让它在本地工作,但不是在我的公共网站的共享主机上(我认为是权利问题)。

SELECT last_update FROM mysql.innodb_table_stats WHERE table_name = 'yourTblName';

'2020-10-09 08:25:10'

MySQL 5.7.20-登录 Win 8.1

只需获取从文件系统修改的文件日期。 用我的语言是:

 tbl_updated = file.update_time(
        "C:\ProgramData\MySQL\MySQL Server 5.5\data\mydb\person.frm")

输出:

1/25/2013 06:04:10 AM

如果您运行的是 Linux,您可以使用 inotify 查看表或数据库目录。 inotify 可从 PHP、node.js、perl 获得,我怀疑大多数其他语言。 当然,您必须已经安装了 inotify 或让您的 ISP 安装了它。 很多ISP不会。

不确定这是否会引起任何兴趣。 在 mysql 和客户端之间使用 mysqlproxy,并使用 lua 脚本根据有趣的表更改更新 memcached 中的键值 UPDATE、DELETE、INSERT 是我最近做的解决方案。 如果包装器支持 php 中的钩子或触发器,这可能会更容易。 到目前为止,没有任何包装器会这样做。

我按名称创建了一个列:phpMyAdmin 中的 update-at 并从我的代码 (nodejs) 中的 Date() 方法获取当前时间。 表中的每一次更改,此列都包含更改的时间。

和其他人一样,但有一些我使用过的条件,以节省时间:

SELECT
  UPDATE_TIME,
  TABLE_SCHEMA,
  TABLE_NAME
FROM
  information_schema.tables
WHERE
  1 = 1
  AND UPDATE_TIME > '2021-11-09 00:00:00'
  AND TABLE_SCHEMA = 'db_name_here'
  AND TABLE_NAME not in ('table_name_here',)
ORDER BY
  UPDATE_TIME DESC,
  TABLE_SCHEMA,
  TABLE_NAME;

这就是我所做的,我希望它有所帮助。

<?php
    mysql_connect("localhost", "USER", "PASSWORD") or die(mysql_error());
    mysql_select_db("information_schema") or die(mysql_error());
    $query1 = "SELECT `UPDATE_TIME` FROM `TABLES` WHERE
        `TABLE_SCHEMA` LIKE 'DataBaseName' AND `TABLE_NAME` LIKE 'TableName'";
    $result1 = mysql_query($query1) or die(mysql_error());
    while($row = mysql_fetch_array($result1)) {
        echo "<strong>1r tr.: </strong>".$row['UPDATE_TIME'];
    }
?>

当查询不可用时,将查询缓存在全局变量中。

创建一个网页以在您更新缓存时强制重新加载缓存。

将重新加载页面的调用添加到您的部署脚本中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM