Printing all the queries that mySql generates - php

I work with Workbench and phpMyAdmin with mySql, I use Procedures and Function etc...
Sometimes one procedure triggers another Function and so on... eventually something goes wrong somewhere.
Is there any tool known to anybody that can show all the queries mySql runs?
Like a command prompt that shows every command MySql runs
it would be a very helpful debugging tool

Run SET GLOBAL general_log = 'ON'; , all queries will be logged to a log-file. See here

I use on a very big site this function I made:
define(test, 3);
function my_query($SQL){//this is a layer over mysql_query to get interesting data while debugging
if(test == 3){ // paranoia
$query_start = get_microtime_ms();
$exp = mysql_query("EXPLAIN ".$SQL);
$query_end = get_microtime_ms();
$query_time = $query_end - $query_start;
$explain .="\n<table border=\"1\">";
$explain .="<tr><td>id</td><td>select_type</td><td>table</td><td>type</td><td>possible_keys</td><td>key</td><td>key_len</td><td>ref</td><td>rows</td><td>Extra</td></tr>";
while( $explain_r = mysql_fetch_array($exp)){
$explain .="\n\t<tr>";
for($i=0;$i<10;$i++){
$explain .= "\n\t\t<td>".$explain_r[$i]." </td>";
}
$explain .="\n\t</tr>";
}
$explain .="\n</table>";
$r = mysql_query($SQL)or die(mysql_error(),$SQL);
$returned = mysql_num_rows($r);
print("<pre>".trim($SQL)."\n".$explain."Time spent: ".$query_time."\nReturned rows: ".$returned."\n--------------\n</pre>");
return $r;
}
if(test == 2){ // hard debugging
print("<pre>\n\n".trim($SQL)."\n--------------\n</pre>");
$r = mysql_query($SQL)or die((mysql_error(),$SQL));
return $r;
}
elseif(test == 1){ // testing
$r = mysql_query($SQL)or die((mysql_error(),$SQL));
return $r;
}
elseif(test == 0){ //production
if($_SESSION['uid'] == 59){
$only_me = $SQL;
}
$r = mysql_query($SQL)or die(
mail("me#example.com",
"[Error http://".$_SERVER["HTTP_HOST"].$_SERVER['REQUEST_URI']."] Error on ".$_SERVER['SCRIPT_NAME'],
"From: ".$_SERVER['REMOTE_ADDR'].
"\nReferer: ".$_SERVER['HTTP_REFERER']."\nDate: ".date()."\nError:\n".mysql_error()."\n".$SQL.
"\nUsername: ".$_SESSION['username']."\nhttp://".$_SERVER["HTTP_HOST"].$_SERVER['REQUEST_URI'].
"\nRef: ".$_SERVER['HTTP_REFERER']).
" a query went wrong Please click here to go back to home page<br><br><pre>$only_me".mysql_error()."</pre>");
return $r;
}
}

Edit your MySQL configuration file (my.cnf or my.ini) and add a log="/path/to/yourlog.log" line in the [mysqld] section. Make sure you restart MySQL to have it pick up the changes in the config file.
This should log all queries that are executed (though I'm not sure it will log the queries executed inside stored procedures).

In your database abstraction class, the best way to do it is to add a debug option that logs queries and debug information to a file, or if there is enough overhead in your application, keep it all available in a variable you can inspect at runtime. Once you've got all this information there, you can output it to a hidden div with a control, or inspect it directly with something like xdebug and netbeans.
On a general note - if you have a large application which you wish to debug, it's really worth spending a bit of time investigating breakpoints, and interactive debugging - it's not so complex to setup and extremely useful. I asked about this recently, and it's really helped me with this kind of stuff!
If your database calls aren't abstracted (shame!) then you can override core PHP functions to include a debug call as demonstrated in this useful example on the PHP site, using the APD extension. Very useful! For example, you can override mysql_query() with your own code to log the query.

Related

PHP DB caching, without including files

I've been searching for a suitable PHP caching method for MSSQL results.
Most of the examples I can find suggest storing the results in an array, which would then get included to page. This seems great unless a request for the content was made at the same time as it being updated/rebuilt.
I was hoping to find something similar to ASP's application level variables, but far as I'm aware, PHP doesn't offer this functionality?
The problem I'm facing is I need to perform 6 queries on page to populate dropdown boxes. This happens on the vast majority of pages. It's also not an option to combine the queries. The cached data will also need to be rebuilt sporadically, when the system changes. This could be once a day, once a week or a month. Any advice will be greatly received, thanks!
You can use Redis server and phpredis PHP extension to cache results fetched from database:
$redis = new Redis();
$redis->connect('/tmp/redis.sock');
$sql = "SELECT something FROM sometable WHERE condition";
$sql_hash = md5($sql);
$redis_key = "dbcache:${sql_hash}";
$ttl = 3600; // values expire in 1 hour
if ($result = $redis->get($redis_key)) {
$result = json_decode($result, true);
} else {
$result = Db::fetchArray($sql);
$redis->setex($redis_key, $ttl, json_encode($result));
}
(Error checks skipped for clarity)

Yii2 db getStats (db queries number)

There is useful method getStats in Db-component Yii
$sql_stats = YII::app()->db->getStats();
echo $sql_stats[0] //the number of SQL statements executed
echo $sql_stats[1] //total time spent
Official documentation link
Is there method in Yii2 to get this information?
Here is equivalent for Yii 2:
$profiling = Yii::getLogger()->getDbProfiling();
$profiling[0] contains total count of DB queries, $profiling[1] - total execution time.
Note that if you want to get information about all queries at the end of request you should execute this code in right place, for example in afterAction():
public function afterAction($action, $result)
{
$result = parent::afterAction($action, $result);
$profiling = Yii::getLogger()->getDbProfiling();
...
return $result;
}
Otherwise you will get the information according to the moment of execution this command.
Official documentation:
getDbProfiling()
afterAction()
If you enable the debugging toolbar you get a lot more info, it is much much better than this. Also you can enable logging that should also get you much more info.
More info on the debugging toolbar here http://www.yiiframework.com/doc-2.0/ext-debug-index.html and more info about the logging here http://www.yiiframework.com/doc-2.0/guide-runtime-logging.html

Possible MySQL sudden error

Hello friends from SO!
Alright, this time I have a little bit more complex problem. We have a web crawler running and functioning normally during most of the day and time.
However, from time to time, it just stops: the link which is supposed to be analyzed next, never change it's state (from pending to scanning), and of course this stops the whole cycle.
We're logging all PHP errors using:
//errores producción
#ini_set('error_reporting', -1);
#ini_set('log_errors','On');
#ini_set('display_errors','Off');
#ini_set('error_log','/var/www/vhosts/xxx.com/xxx.com/xxx');
There's no evidence of anything that could cause the problem described. 0 anomalies.
Therefore, I believe the problem might be related to some kind of MySQL issues?
Every single MySQL query we do, is done using MySQLi by custome made functions, so my question here is:
Is there any simple approach to record every single MySQL error on the same file where we are storing the PHP errors?
Here are some of the functions used to query the MySQL:
Function db_ob($db_link, $ask) {
$feedback = mysqli_fetch_object(mysqli_query($db_link, $ask));
return $feedback;
}
and:
Function db_ob_all($db_link, $ask) {
$feedback = mysqli_query($db_link, $ask);
while ($row = mysqli_fetch_object($feedback)) { $value[] = $row; }
return $value;
}
So what I'm looking for, is a one or two lines solution, that I could add into these functions, in order to store and track any issue or error in the same file where I'm currently storing the PHP errors.
Thanks in advance!
Chris;
Solved:
1) make a function to track the errors into the PHP error_log:
Function informar_error_db($db_link) {
error_log("Dreadful SQL error: ". mysqli_error($db_link)." in ".$_SERVER["SCRIPT_FILENAME"]);
}
2) If there's MySQLi issues, save em:
Function db_ask($db_link, $ask) {
$feedback = mysqli_query($db_link, $ask);
if (mysqli_error($db_link)) { informar_error_db($db_link); }
return $feedback;
}
Here:
if (mysqli_error($db_link)) { informar_error_db($db_link); }

Ajax calling memcache functions always querying Db

I'm experiencing a strange problem. I'm caching the output of a query using memcache functions in a file named count.php. This file is called by an ajax every second when a user is viewing a particular page. The output is cached for 5 seconds, so within this time if there will be 5 hits to this file i expect the cached result to be returned 3-4 times atleast. However this is not happening, instead everytime a query is going to db as evidenced from a echo statement, but if the file is called from the browser directly by typing the url (like http://example.com/help/count.php) repeatedly many times within 5 seconds data is returned from cache (again evidenced from the echo statement). Below is the relevant code of count.php
mysql_connect(c_dbhost, c_dbuname, c_dbpsw) or die(mysql_error());
mysql_select_db(c_dbname) or die("Coud Not Find Database");
$product_id=$_POST['product_id'];
echo func_total_bids_count($product_id);
function func_total_bids_count($product_id)
{
$qry="select count(*) as bid_count from tbl_userbid where userbid_auction_id=".$product_id;
$row_count=func_row_count_only($qry);
return $row_count["bid_count"];
}
function func_row_count_only($qry)
{
if($_SERVER["HTTP_HOST"]!="localhost")
{
$o_cache = new Memcache;
$o_cache->connect('localhost', 11211) or die ("Could not connect to memcache");
//$key="total_bids" . md5($product_id);
$key = "KEY" . md5($qry);
$result = $o_cache->get($key);
if (!$result)
{
$qry_result = mysql_query($qry);
while($row=mysql_fetch_array($qry_result))
{
$row_count = $row;
$result = $row;
$o_cache->set($key, $result, 0, 5);
}
echo "From DB <br/>";
}
else
{
echo "From Cache <br/>";
}
$o_cache->close();
return $row_count;
}
}
I'm confused as to why when an ajax calls this file, DB is hit every second, but when the URL is typed in the browser cached data is returned. To try the URL method i just replaced $product_id with a valid number (Eg: $product_id=426 in my case). I'm not understanding whats wrong here as i expect data to be returned from cache within 5 seconds after the 1st hit. I want the data to be returned from cache. Can some one please help me understand whats happening ?
If you're using the address bar, you're doing a GET, but your code is looking for $_POST['...'], so you will end up with an invalid query. So for a start, the results using the address bar won't be what you're expecting. Is your Ajax call actually doing a POST?
Please also note that you've got a SQL injection vulnerability there. Make sure $product_id is an integer.
There are many problems with your code, first of all you always connect to the database and select a table, even if you don't need it. Second, you should check $result with !empty($result) which is more reliable as just !$result, because it's also covers empty objects.
As above noted, if the 'product_id' is not in the $_POST array, you could use $_REQUEST to also cover $_GET (but you shouldn't, if you are certain it's coming via $_POST).

How to view how many MySQL queries ran on page load

I'm testing performance on a CMS I'm making, and I'm wondering is it possible to view what queries were ran on a page load. For example, let's say I run 'test.php'. When I go to it, a list of queries ran by mySQL show at the bottom of the page - is this possible? I've seen sites do this before.
Thanks
The function SHOW FULL PROCESSLIST will show the real-time and past history of all processes.
SHOW FULL PROCESSLIST
If you are using a server on which you have the rights to install packages, you can install mysqltop and test in real time file and MySQL resource usage and queries.
Well, if all your queries go through a function then it should be easy, but if each only uses the standard call, then it won't be. This also let's you switch to a different database type or something like that easily.
For instance on the CMS's I modified to be a library program, I have a DB Query function:
function db_query($qstring, $conn) {
$dbh = mysql_db_query($dbname,$qstring, $conn);
// this is where I would add some incrementing code, but it has to be global.
// or just do something like
if($_GET["debug"]=="debuginSQLcount"){
echo $qstring
}
return $dbh;
}
then to use it, I just do something like
$sql = "SELECT stuff";
}
$result = db_query($sql, $link);
if (!$result || db_numrows($result) < 1) {
If you do it like this, then just add a line to the function which increments a $GLOBALS variable or something like that. Read more at PHP global or $GLOBALS

Categories