views:

98

answers:

5

I am looking for a way to know which rows in a database (mysql) are new (or updated) in order to fetch just those from the server and store locally in an application (client).

My initial thought was to add a timestamp to each row and have my application remember the time it last got an update, however I am worried of the server clock changing backwards (e.g. when going from summer to winter time) or a client updating while a transaction is in progress on the server -> example

Apart from time stamps (quite obvious and apparently common idea), is there a recommended best practice for these kinds of things?

A: 

Many databases use a timestamp for concurrency checking, so that would be the natural (and correct IMO) way to do it. Especially if there is already a timestamp field in use for concurrency checking.

During DST changes, you need a way to invalidate your records cache on the client, so that it will reload all of the records after the time change.

Or, as Daniel points out, just use UTC for the timestamp, and then you don't have to worry about time zone changes at all.

Robert Harvey
I am using a MySQL database (updated question) and never saw any such timestamp.
Steve
Have a look here:http://www.ardamis.com/2008/04/06/resolving-transaction-concurrency-issues-in-a-phpmysql-multi-user-environment/
Robert Harvey
This link does not really take away any of my concerns. Namely if at 10:15 the server would switch from DST to normal time (-1h), a save would be prevented (in the link's case). Also it does not guarantee that a read and a write transaction taking place at exactly the same time are not causing the problems outlined in the link I put in my question. At least AFAICS.
Steve
So your primary concern is DST. See Jerry Coffin's answer.
Robert Harvey
Would think/hope that something like a timestamp would be based on the UTC time, not local.
Daniel Schaffer
DST is a big concern but can probably be worked around. However clock drift (going too fast) and corrections (time moving backwards) are more troubling. Also the whole transaction issue.
Steve
Surely there are some conventional cache solutions out there that you can use. It's hard to imagine that this problem hasn't been solved a dozen times already, by people smarter than I am.
Robert Harvey
DST should not be an issue with a MySQL TIMESTAMP column -- they are stored internally as UTC, and displayed in local time. Clock drift, either fast or slow, can be solved with NTP, which will never (in normal operation) move the system clock in reverse.
Ian Clelland
+2  A: 

Other ideas:

  • for data that can only be inserted, an increasing id (e.g. generated by a sequence or similar concept) is sufficient - all you'd have to remember is the last id you copied
  • this can be extended by a column in each table that gets updated from a sequence whenever it is inserted or updated (set by a trigger)
  • instead of a column for each table it may be easier to have a central log table that collects the similar information (tricky to identify the releavant rows if you have composite keys)

Unless you have a good reason to work on such a scheme, I'd be very careful. This type of synchronisation may run into a number of tricky problems that may be harder to solve than they seem to be.

IronGoofy
At my company we use a similar approach for one of our apps. I'll second that you need to be careful with this approach. We haven't had any issues with it, but we did spent a great deal of time setting it up
Brian Vander Plaats
+1  A: 

Instead of a timestamp, put an autoincrement column in your table, and store the currently-largest value of that column. When you need to update, do your select on auto_column>my_largest_value.

Jerry Coffin
This would work only for inserts, but as the auto_column would not increment when I do an update, I would miss those changes.
Steve
A: 

Take a look at the Timestamp column type -- it automatically updates whenever you create or alter a record.

Time zone should not be an issue depending on how you query against it. It stores the value as UTC which has no daylight savings time.

Eli
But as far as I can tell, using this would not necessarily solve the transaction problem (in best case it does but is it guaranteed to stay that way, i.e. that the timestamp is always the exact time when the row is updated and visible to other processes?)
Steve
Not sure I follow. Yes, a Timestamp field can be set up to always show the last updated time of the record.
Eli
http://www.pervasync.com/faq#TOC-Q.-What-s-wrong-with-those-time-sta
Steve
A: 

Since there is no native Change Data Capture in MySQL, you can implement INSERT and UPDATE and DELETE triggers to capture what you need in an audit table and pull the data from there. Sort of a poor-man's replication technique.

Raj More