De-optimizing MySQL - mysql

Is there a simple command that will let me tweak a MySQL DB instance to run slower than normal?
I'm working on code that records and replays database interactions. One of the things it does is keep track of how long a given query/command takes to execute, and if it runs substantially slower during the replay, it throws a warning. Of course, If You Don't Test It, It Doesn't Work; I'm trying to come up with an automated test for this feature. Is there something I can do to my test DB that will screw up performance? All I need to do is reliably add 2+ milliseconds to any given query and I'm set.

If you just want to test long queries, do this: SELECT SLEEP(1);
It shouldn't matter what the query is itself if all you want to do is test if your duration detection works.
(I know this breaks the true "replay" aspect, but it should be trivial to add SLEEP(1) during "playback" to some select statements.)
EDIT:
A second idea, which you might like better: Create a lock on a table from another connection. Run the script. Wait a bit. Remove that lock. It won't involve messing with any of your playback queries.

Basic procedure like so:
begin transaction
do your sql stuff
sleep 2ms in perl or sql
commit
the key is the begin/commit part: it'll keep any locks you acquired, making things as slow as you want them.
Other test to consider:
begin transaction in two processes
do your sql stuff in first process
do your sql stuff in second process
do more sql stuff in each process
commit each process

Related

Mysql update query is in general log but data is not changed

I'm using Node.js and MySQL in a batch process. The process makes a lot of queries concurrently and consists of many jobs. I've noticed that update statement works from time to time.
UPDATE `Configuration` SET `Value`='2015-06-08 11:35:00' WHERE `ID`=6
I've turned on general log and found the query there but data at the table hasn't been changed. The query runs at the end of a job approx once per 5 min. But other jobs continue making queries.
Example:
jobA is making a lot of queries. At the same time jobC makes SELECT from Configuration table. Then jobC performs a bunch of queries not related to the Configuration table. Once jobC completes a bunch, it runs two queries against Configuration table: SELECT and then UPDATE.
Configuration table from the example isn't used in any other job or transaction.
I've found during testing that UPDATE Configuration table query is not working when jobA makes heavy load.
Can anyone suggest me what the problem is or where I should look further?
I suggest looking into isolation modes for MySQL.
I would need some more information about your problem (how often it doesn't update versus successfully updating and under what conditions) but if it is running too frequently the other transaction (if they are long?) may not have finished running and if it is not reading dirty data it may not execute an update. It all depends on the relative speed of the jobs and their isolation modes.

mysql: sequence of executed queries

I have to update a row into a table(InnoDB) and then right after select the last registry that I updated and make an insert. If the connection is too slow(for the update statement), can the select statement get the wrong row? Assuming that I'm using two different queries.
Are you using SQL to run your script or are you running it somewhere else? (ex PHP, Python, C#)
A Script from SQL should* always complete one line before moving on to the next but if you're unsure you could call something like the sleep function or the wait delay function to pause before you run your second line.
*I say should as I've seen some extremely rare random cases, usually with longer running queries that don't. If your first job takes a long time to complete it may be worth the effort to schedule the first job in Job Agent, then later that day schedule the second job.
MySQL does not keep records of row insertion order. Any algorithm that's based on last registry that I updated must implement its own means to gather the required information. If it doesn't, it will get the wrong row sooner or later. (Network speed is probably not as relevant as concurrent access.)

How can I find the bottleneck in my slow MySQL routine (stored procedure)?

I have a routine in MySQL that is very long and has multiple SELECT, INSERT, and UPDATE statements in it with some IFs and REPEATs. It's been running fine until lately, where it's hanging an taking over 20 seconds to complete (which is unacceptable considering it used to take 1 second or so).
What is the quickest and easiest way for me to find out where in the routine the bottleneck is coming from? Basically the routine is getting stopped up and some point... how can I find out where that is without breaking apart the routine and testing one-by-one each section?
If you use Percona Server (a free distribution of MySQL with many enhancements), you can make the slow-query log record times for individual queries, using the log_slow_sp_statements configuration variable. See http://www.percona.com/doc/percona-server/5.5/diagnostics/slow_extended_55.html
If you're using stock MySQL, you can add statements in the stored procedure to set a series of session variables to the value returned by the SYSDATE() function. Use a different session variable at different points in the SP. Then after you run the SP in a test execution, you can inspect the values of these session variables to see what section of the SP took the longest.
To analyze the query can see the execution plan of the same. It is not always an easy task but with a bit of reading will find the solution. I leave some useful links
http://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html
http://dev.mysql.com/doc/refman/5.0/en/explain.html
http://dev.mysql.com/doc/refman/5.0/en/using-explain.html
http://www.lornajane.net/posts/2011/explaining-mysqls-explain

What is the proper way to do multiple UPDATE statements?

I have a server which sends up to 20 UPDATE statements to a separate MySQL server every 3-5 seconds for a game. My question is, is it faster to concat them together(UPDATE;UPDATE;UPDATE). Is it faster to do them in a transaction then commit the transaction? Is it faster to just do each UPDATE individually?
Any insight would be appreciated!
It sort of depends on how the server connects. If the connection between the servers is persistent, you probably won't see a great deal of difference between concatenated statements or multiple separate statements.
However, if the execution involves establishing the connection, executing the SQL statement, then tearing down the connection, you will save a lot of resources on the database server by executing multiple statements at a time. The process of establishing the connection tends to be an expensive and time-consuming one, and has the added overhead of DNS resolution since the machines are separate.
It makes the most logical sense to me to establish the connection, begin a transaction, execute the statements individually, commit the transaction and disconnect from the database server. Whether you send all the UPDATE statements as a single concatenation or multiple individual statements is probably not going to make a big difference in this scenario, especially if this just involves regular communication between these two servers and you need not expect it to scale up with user load, for example.
The use of the transaction assumes that your 3-5 second periodic bursts of UPDATE statements are logically related somehow. If they are not interdependent, then you could skip the transaction saving some resources.
As with any question regarding performance, the best answer is if your current system is meeting your performance and scaling needs, you ought not pay too much attention to micro-optimizing it just yet.
It is always faster to wrap these UPDATEs into single transaction block.
Price for this is that if anything fails inside that block it would be that nothing happened at all - you will have to repeat your work again.
Aslo, keep in mind that transactions in MySQL only work when using InnoDB engine.

Extreme low-priority SELECT query in MySQL

Is it possible to issue an (expensive, but low-priority) SELECT query to mySQL in such a way that if an UPDATE query appears in the queue, mySQL will immediately terminate the query, and re-append it to the end of the queue?
If re-appending to the queue is not possible, I'm happy with simply killing the SELECT query.
No, not really.
I am not sure exactly what you need, but my guess is that you need to either optimize the SELECT to not lock an entire table, or get the replication going and do the SELECT on the slave rather than the master.
You could theoretically find out what the MySQL process ID is of the SELECT query, and in your application send a KILL before you do any update.
Well, sort of maybe.
A client runs an application which occasionally throws out queries that completely kill performance for everything else on the server. We have monitoring and if we've got a suitable person ready to react, we can deal to that query manually, and we learn about the problems in the app by doing things that way.
But to prevent major outages if noone is on the ball, we have an automated script which terminates long running queries, so the server does recover in the event that noone is available to intervene within 15 minutes.
Far from ideal, but that's where things are currently at with this project, and it does prevent the occasional extended outages that used to occur. We can only move just so fast with fixing up the problem queries.
Anyway, you could run something similar, that looks at the running queries and recognises when you have an update waiting on one of your large selects, and in that event it kills the select. Doing this sort of check a few times a minute is not overly expensive. I'd want to do a bit of testing before running.
So, whether you can solve your problem this way depends on what your tolerance is for how long an update can be delayed. Running this every minute (as we do) is no problem at all. Running it every second would noticeably add to the overall load. You'd need to test how far you can reasonably go in between those points.
This approach means some delay before the select gets pushed out of the way, but it saves you having to build this logic into potentially many different places in your application.
--
Regarding breaking up your query, you're most likely better off restricting the chunks by id range from one or more tables in your query rather than by offset and limit.
--
There may also be good solutions available based on partitioning your tables so that the queries don't collide as badly. Make sure you have a very good grasp on what you are doing for this though.