簡體   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