Understanding the update_time Field in information_schema.tables and Its Reliability in MySQL 8.0
This article explains how the update_time column in the information_schema.tables view is populated, why its values can be unreliable, and details the mechanisms of active and passive persistence of table statistics in MySQL 8.0, including source‑code walkthroughs.
The update_time column in information_schema.tables records the timestamp of the last DML transaction commit for a table, but its reliability is questionable because the value is derived from in‑memory structures that are not always persisted promptly.
Two key questions are explored:
Where does the recorded last‑modification time come from?
Why can it be unreliable?
1. Preparation
Create a test table and insert data:
USE `test`;
CREATE TABLE `t1` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`i1` int DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
INSERT INTO `t1`(i1) VALUES (10),(20),(30);Query the view to see the current UPDATE_TIME:
SET information_schema_stats_expiry = 0;
SELECT * FROM information_schema.tables WHERE table_schema='test' AND table_name='t1'\GThe displayed UPDATE_TIME corresponds to the commit time of the transaction that inserted the rows.
2. How the Timestamp Is Set
2.1 Marking Modified Tables
During undo logging, trx_undo_report_row_operation() adds the affected table's dict_table_t* pointer to trx->mod_tables (a std::set).
// storage/innobase/trx/trx0rec.cc
bool is_temp_table = index->table->is_temporary();
if (!is_temp_table) {
trx->mod_tables.insert(index->table);
}Only non‑temporary tables are tracked.
2.2 Determining the Modification Time
When a read‑write transaction commits, trx_commit_for_mysql() calls trx_update_mod_tables_timestamp(), which assigns the current system time to each table's dict_table_t::update_time field.
// storage/innobase/trx/trx0trx.cc
static void trx_update_mod_tables_timestamp(trx_t *trx) {
const auto now = std::chrono::system_clock::from_time_t(time(nullptr));
for (auto it = trx->mod_tables.begin(); it != trx->mod_tables.end(); ++it) {
(*it)->update_time = now;
}
trx->mod_tables.clear();
}At this point the timestamp exists only in memory.
2.3 Persistence
The in‑memory update_time is eventually written to the mysql.table_stats table via two paths:
Active persistence : Executing ANALYZE TABLE <tbl> triggers ha_innobase::analyze(), which calls ha_innobase::info_low() to copy dict_table_t::update_time into a ha_statistics structure, then into a Table_stat object, and finally stores it in mysql.table_stats.
Passive persistence : When information_schema.tables is queried, MySQL checks whether the cached statistics are expired (using the system variable information_schema_stats_expiry). If expired, it fetches fresh statistics from InnoDB and writes them back to mysql.table_stats.
Both paths involve the same series of transfers:
// dict_table_t -> ha_statistics -> Table_stat -> mysql.table_stats3. Why the Value Is Unreliable
Two main reasons:
The timestamp is not persisted immediately; it only reaches mysql.table_stats after an ANALYZE TABLE or after the expiration interval (default 86400 s) triggers passive persistence.
Before persistence, the timestamp lives solely in memory. A server crash, power loss, or eviction of the dict_table_t object from the InnoDB cache (controlled by table_definition_cache) causes the value to be lost.
Consequently, the UPDATE_TIME shown by information_schema.tables may be stale or NULL, which the MySQL developers consider expected behavior rather than a bug.
4. The mysql.table_stats Table
By default users cannot read mysql.table_stats. Enabling the debug session variable skip_dd_table_access_check allows inspection, revealing columns such as schema_name, table_name, update_time, and cached_time.
5. Summary
During DML, InnoDB marks the affected table, and on transaction commit the current time is stored in the table's in‑memory dict_table_t. This value is later persisted to mysql.table_stats either actively (via ANALYZE TABLE) or passively (when statistics expire). Because persistence is not instantaneous and the in‑memory copy can be lost, the UPDATE_TIME reported by information_schema.tables is not always reliable.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Aikesheng Open Source Community
The Aikesheng Open Source Community provides stable, enterprise‑grade MySQL open‑source tools and services, releases a premium open‑source component each year (1024), and continuously operates and maintains them.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
