I'd like to have some explanation about information_schema and its behaviours.
Let's say I want to know when a myisam table has been modified.
I write this query
select update_time from information_schema.tables
where table_schema = 'my_db' and table_name = 'my_table'
Even though I apply some change to my table nothing happens in it until I run a flush tables.
Unluckily it seems to me that update_time stores date and time of the moment that I run flush tables, not the one when table changes really occur. Is it true?
Thanks in advance.
I personally prefer to add a last_change timestamp to each of my tables, then define it as "DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP", which means that mysql will automatically update it each time the row is modified.
With this, you could just query the table directly and know not only that the table was touched, but also which rows were touched.
It doesn't work to detect deleted rows though.
Related
Is it possible to update the INFORMATION_SCHEMA.TABLES UPDATE_TIME for a specific table when a specific column is changed in this table?
I know that MySQL saves its cache to the TABLES on a timeout specified in the information_schema_stats_expiry variable and the timeout is 24h by default which is ok for me. Also I know I can query ANALYZE TABLE 'table_name_1', ... 'table_name_N' to force MySQL update the TABLES. But it will cause the update with no conditions. So is it possible to call ANALYZE TABLE only for specific columns? Thanks
I have the need to get last id (primary key) of a table (InnoDB), and to do so I perform the following query:
SELECT (SELECT `AUTO_INCREMENT` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = 'mySchema' AND `TABLE_NAME` = 'myTable') - 1;
which returns the wrong AUTO_INCREMENT. The problem is the TABLES table of information_schema is not updated with the current value, unless I run the following query:
ANALYZE TABLE `myTable`;
Why doesn't MySQL update information_schema automatically, and how could I fix this behavior?
Running MySQL Server 8.0.13 X64.
Q: Why doesn't MySQL update information_schema automatically, and how could I fix this behavior?
A: InnoDB holds the auto_increment value in memory, and doesn't persist that to disk.
Behavior of metadata queries (e.g. SHOW TABLE STATUS) is influenced by setting of innodb_stats_on_metadata and innodb_stats_persistent variables.
https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_stats_on_metadata
Forcing an ANALYZE everytime we query metadata can be a drain on performance.
Other than the settings of those variables, or forcing statistics to be collected by manually executing the ANALYZE TABLE, I don't think there's a "fix" for the issue.
(I think that mostly because I don't think it's a problem that needs to be fixed.)
To get the highest value of an auto_increment column in a table, the normative pattern is:
SELECT MAX(`ai_col`) FROM `myschema`.`mytable`
What puzzles me is why we need to retrieve this particular piece of information. What are we going to use it for?
Certainly, we aren't going to use that in application code to determine a value that was assigned to a row we just inserted. There's no guarantee that the highest value isn't from a row that was inserted by some other session. And we have LAST_INSERT_ID() mechanism to retrieve the value of a row our session just inserted.
If we go with the ANALYZE TABLE to refresh statistics, there's still a small some time between that and a subsequent SELECT... another session could slip in another INSERT so that the value we get from the gather stats could be "out of date" by the time we retrieve it.
SELECT * FROM tbl ORDER BY insert_datetime DESC LIMIT 1;
will get you all the data from, the "latest" inserted row. No need to deal with AUTO_INCREMENT, no need to use subqueries, no ANALYZE, no information_schema, no extra fetch once you have the id, no etc, etc.
Yes, you do need an index on the column that you use to determine what is "latest". Yes, id could be used, but it should not be. AUTO_INCREMENT values are guaranteed to be unique, but nothing else.
How to see the create time of a MySql user?
I want to know the create time of a MySql user called "local".
Therefore, I have queried the mysql.user table, but that does not display the creation time for the user. Furthremore, there are no MySql logs in /var/log.
I need the information for doing forensics analysis on the system.
Is there any way to obtain the create time for MySql users?
You would query the information_schema for the create_time of the table.
For instance:
SELECT create_time FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = 'your_schema'
AND table_name = 'your_table'
Reference: http://dev.mysql.com/doc/refman/5.0/en/tables-table.html
If you want to get the user creation date then you can add a timestamp column in mysql.user table and set it to CURRENT_TIMESTAMP as default. So next time when a user is created, you will get the timestamp.
Is there any way to know the time when last select statement has been performed on a table? I am using the InnoDB storage engine.
I have tried with the following query:
select update_time,table_name from information_schema.tables where table_schema='databasename';
..but I'm receiving NULL in the update_time column.
Unless you manually update a last_accessed-field on the table, my best bet would be to add query logging and parse the log-files.
I googled and found these relates questions:
When was the last time a mysql table was accessed?
How do you get the last access (and/or write) time of a MySQL database?
SELECT UPDATE_TIME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'dbname'
AND TABLE_NAME = 'tabname'`
I have InnoDB based tables that I can checksum with:
checksum table _table_name_
That is slow in case millions of records reside in the table. I wonder if there is any way to recognize, whether a table was altered or not?
I needed something that is fast and cheap to request, and changes every time a change is made to any of the records of a table. I do not find anything for InnoDB tables. Is there something?
Regards
Felix
If you have a timestamp (say LastUpdateTS) on the table, created with default settings, and an index on it, then this should be rather fast. It will catch only Inserts and Updates but not Deletes though:
SELECT MAX(LastUpdateTS)
FROM TableX
From MySQL Docs, Timestamp Properties:
In a CREATE TABLE statement, the first TIMESTAMP column can be declared in any of the following ways:
With both DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses, the column has the current timestamp for its default value, and is automatically updated.
If you want to catch any change in the table (Deletes included), a trigger may be the best solution. Every time an INSERT, UPDATE or DELETE statement acts on the table, the trigger can update an auxilary table.
Later versions of MySQL stores a timestamp for each update to the table:
SELECT UPDATE_TIME
FROM information_schema.tables
WHERE TABLE_SCHEMA = 'dbname'
AND TABLE_NAME = 'tabname'