Archive for October, 2011
What SYSDATE is it?
I was looking into the history about why SYSDATE() and NOW() behave differently in MySQL, and it looks like in 4.0 and 4.1 they used to be the same. But as of MySQL 5.0, SYSDATE() was changed to emulate Oracle’s behavior, that is, it returns the time as of the function execution, not as of the statement start.
There are a number of bug reports related to this: 15101, 12480, 12481, and 12562.
I am not an Oracle expert. Does NOW() return a constant result within an Oracle query, like NOW() in MySQL does? Or is there no NOW() in Oracle, and you use SYSDATE() instead? Why is Oracle’s SYSDATE() functionality worth emulating? It looks to me like some people use SYSDATE() as a sort of cross-platform compatible NOW() function, but the saner behavior for me would be to have it be deterministic by default, for all the normal reasons that deterministic behavior is a Good Thing.
All of this is related to another topic I’ve been considering: should –sysdate-is-now be enabled in a “sane” default MySQL configuration, or is that just breaking something a lot of people rely on working the way it does? (It seems far more likely to me that it will unbreak things.)
When systems scale better than linearly
I’ve been seeing a few occasions where Neil J. Gunther’s Universal Scalability Law doesn’t seem to model all of the important factors in a system as it scales. Models are only models, and they’re not the whole truth, so they never match reality perfectly. But there appear to be a small number of cases where systems can actually scale a bit better than linearly over a portion of the domain, due to what I’ve been calling an “economy of scale.” I believe that the Universal Scalability Law might need a third factor (seriality, coherency, and the new factor, economy of scale). I don’t think that the results I’m seeing can be modeled adequately with only two parameters.
Here are two publicly available cases that appear to demonstrate this phenomenon: Robert Haas’s recent blog post on PostgreSQL, titled Scalability, in Graphical Form, Analyzed and Mikael Ronstrom’s post from May on MySQL (NDB) Cluster, titled Better than Linear Scaling is Possible.
Dr. Ronstrom’s post discusses the mechanics of the phenomenon, and speculates (I’m not sure it’s conclusive) that it is from a combination of partitioning and better use of CPU caches. Now someone needs to do the math to figure out how to include this factor into the equation.
The good thing about the Universal Scalability Law is how simple and applicable it is for many systems. It’s nice that this economy-of-scale factor seems to be unusual and the simpler model remains easy to apply for a large variety of tasks.
Fundamental performance and scalability instrumentation
This post is a followup to some promises I made at Postgres Open.
Instrumentation can be a lot of work to add to a server, and it can add overhead to the server too. The bits of instrumentation I’ll advocate in this post are few and trivial, but disproportionately powerful.
If all server software shipped with these metrics as the basic starting point, it would change the world forever:
- Time elapsed, in high resolution (preferably microseconds; milliseconds is okay; one-second is mostly useless). When I ask for this counter, it simply tells me either the time of day, or the server’s uptime, or something like that. It can be used to determine the boundaries of an observation interval, defined by two measurements. It needs to be consistent with the other metrics that I’ll explain next.
- The number of queries (statements) that have completed.
- The current number of queries being executed.
- The total execution time of all queries, including the in-progress time of currently executing queries, in high resolution. That is, if two queries executed with 1 second of response time each, the result is 2 seconds, no matter whether the queries executed concurrently or serially. If one query started executing .5 seconds ago and is still executing, it should contribute .5 second to the counter.
- The server’s total busy time, in high resolution. This is different from the previous point in that it only shows the portion of the observation interval during which queries were executing, regardless of whether they were concurrent or not. If two queries with 1-second response time executed serially, the counter is 2. If they executed concurrently, the counter is something less than 2, because the overlapping time isn’t double-counted.
In practice, these can be maintained as follows, in pseudo-code:
global timestamp;
global concurrency;
global busytime;
global totaltime;
global queries;
function run_query() {
local now = time();
if ( concurrency ) {
busytime += now - timestamp;
totaltime += (now - timestamp) * concurrency;
}
concurrency++;
timestamp = now;
// Execute the query, and when it completes...
now = time();
busytime += now - timestamp;
totaltime += (now - timestamp) * concurrency;
concurrency--;
timestamp = now;
queries++;
}
I may have missed something there; I’m writing this off the cuff. If I’ve messed up, let me know and I’ll fix it. In any case, these metrics can be used to derive all sorts of powerful things through applications of Little’s Law and queueing theory, as well as providing the inputs to the Universal Scalability Law. They should be reported by simply reading from the variables marked as “global” above, to provide a consistent view of the metrics.




