1

I'm working on an automated system on LAMP stack and experiencing several query misses, i.e. the query gets executed by PHP but its not present in the database and there are no errors.

So I enabled logging all queries in mysql to see if the query reaches there at all and sure enough, the query is there. It happened right now so I'll explain with an example:

(BTW don't try to find errors in the queries. There aren't any. The same queries do execute most of the time)

PHP executes:

$saveOrderQ = "INSERT INTO orders (order_id, parent_order, date_created, status, type, phase, ticker, quantity, entry_price, tp1, tp2, strategy, relative_volume, distance_from_close) VALUES ({$order->order_id}, 0, '$now', 'OPEN', 'BUY', 0, '$ticker', $positionsSize, $price, $tp1, $tp2, {$tickerAttr['strategy']}, $relativeVol, $distanceFromClose)";
writeToLog($saveOrderQ); // I get the query in the log. This function's log is seperate from mysql log
$saveOrder = mysqli_query($connect, $saveOrderQ);
if(!$saveOrder){
    writeToLog("Failed to insert file 30daybreakout.php Line 59. Error: ".mysqli_error($connect)."\nQuery: $saveOrderQ"); // no error received
}

MySQL log around the same time:

2020-04-13T09:23:02.222315+05:30    127059 Query    SELECT order_id FROM orders WHERE ticker = 'NSE:BALMLAWRIE' AND DATE(date_created) = '2020-04-13' AND parent_order = 0 AND phase < 3
2020-04-13T09:23:02.356930+05:30    127059 Query    INSERT INTO orders (order_id, parent_order, date_created, status, type, phase, ticker, quantity, entry_price, tp1, tp2, strategy, relative_volume, distance_from_close) VALUES (200413000329794, 0, '2020-04-13 09:23:01', 'OPEN', 'BUY', 0, 'NSE:BALMLAWRIE', 54, 91.3, 94.95, 98.6, 1, 108.87022900763, 6.5966141272621)

This entry is simply not present in the orders table.

My best guess is that somehow the order table is locked but I don't know for sure. How do I troubleshoot it?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Whip
  • 1,891
  • 22
  • 43
  • 1
    What is your table structure (`SHOW CREATE TABLE orders`)? Please correct your [SQL injection](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php). `DATE(date_created)` is unnecessary to wrap a date in a date function. It can be compared to a `YYYY-MM-DD` value. – danblack Apr 13 '20 at 05:05
  • 1
    How is that related dude? Does the table structure or using the Date function determine if the query gets executed or missed? Focus on the question. – Whip Apr 13 '20 at 05:13
  • 3
    @VeeK The table structure is completely relevant because it determines what values are permissible to be inserted for each column. Also relevant are the indexes, which may, for example, prevent duplicate entries from being inserted in certain columns. Unless you provide us with that info, it's going to be difficult to help you. Also, please provide us with at least one example of a complete SQL statement which *should* have executed but which didn't. – kmoser Apr 13 '20 at 05:35
  • 1
    Like I said, there are no errors in the query and there is a complete query in the log I posted. Its the same query as above in PHP but with variables filled in. I've been researching transactions. I think that could help me but not sure. – Whip Apr 13 '20 at 05:43
  • What's the type of the `order_id` column, in particular? You're trying to save an integer value of `200413000329794` in there, but that's way bigger than a 32 bit integer can store. – Greg Schmidt Apr 13 '20 at 05:46
  • Guys the query is fine!!! That column is Varchar(20). The insert fails only some of the time. – Whip Apr 13 '20 at 05:46
  • Will adding the quotes fix the problem? – Whip Apr 13 '20 at 05:47
  • 2
    Probably not, we've been told several times now that the query is just fine. – Greg Schmidt Apr 13 '20 at 05:48
  • Yet I keep getting unsolicited advice about the query. – Whip Apr 13 '20 at 05:49
  • Maybe try it with the quotes, just to see? Is it possible that the people you've asked for help might actually be able to help? – Greg Schmidt Apr 13 '20 at 05:49
  • How can you be sure that there are no errors when you never ask the database? – Honk der Hase Apr 16 '20 at 09:48
  • @VeeK, maybe you're using transactions and the transaction is rolled back? So the query gets logged, but the result does not appear in the database as the transaction was not committed. – astax Apr 16 '20 at 12:52
  • The timestamps imply that the `INSERT` was after the `SELECT`?? – Rick James Apr 16 '20 at 15:56
  • @astax I'm not using transactions. – Whip Apr 17 '20 at 10:22
  • @Rick James That's intended behavior. I check if there isn't a similar order already in the system. – Whip Apr 17 '20 at 10:22
  • @VeeK - You might be able to avoid that check by using IODKU. – Rick James Apr 17 '20 at 15:52
  • No I do not wish to update – Whip Apr 18 '20 at 05:40
  • Side note 1: Using INSERT depending on SELECT without using transactions is a bad idea. IODKU might be really the way to go (it is just special INSERT syntax, nothing you should update to. https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html) Side note 2: Make sure your mysqli connection is configured to throw exceptions. More info here https://phpdelusions.net/mysqli/error_reporting – Filip Halaxa Apr 19 '20 at 16:27
  • execute the logged query into MySQL terminal then see the result. – Arnish gupta Apr 23 '20 at 04:15
  • Where's the `Error` part of the `writeToLog()`? You have it in your input, but it doesn't match the output. – Qirel Apr 23 '20 at 05:54
  • If I run the query in Mysql terminal or Phpmyadmin, it will insert fine. `writeToLog` function never runs. Like I've mentioned, I don't get any errors from anywhere. – Whip Apr 23 '20 at 10:26

4 Answers4

1

Also check for "Warnings". Do this after you have checked for errors, and before running any other SQL, by executing SHOW WARNINGS LIMIT 11 and print results (if any). Warnings are not as severe as errors, but sometimes they give a clue that things are not as expected, thereby leading to discovering the real error.

Only recently did PHP switch from 32-bit builds to 64-bit. That is, it has been unsafe to represent large numbers in PHP. What version of PHP are you using? Since the problem occurs "sometimes", it may be that you are getting rounding errors above 31, 32, (INT sizes) or 53 bits (DOUBLE size). To help with that, please provide some specific numbers and say which worked and which failed. (200413000329794 takes 48 bits, so it won't loose anything if it goes through DOUBLE in PHP.)

Putting quotes around numbers in MySQL won't matter: WHERE foo = 123 and WHERE foo = "123" work the same if foo in integral, not char.

What value of autocommit do you use? In my opinion, OFF is error-prone because you must remember to COMMIT eventually. And it is too easy to forget to do so, or take a branch sometimes that avoids the COMMIT. Then, when the connection is closed, that open transaction is automatically ROLLBACKd.

(Some more "unsolicited advice") A Comment suggested a change to make the date "sargable". It needs some expansion:

AND date_created >= '2020-04-13'
AND date_created  < '2020-04-13' + INTERVAL 1 DAY

(Some more "unsolicited advice") With that, this might be the optimal index:

INDEX(ticker, parent, date_created)

More (Mostly "fishing as straws")

When inserting a numeric constant into a numeric field, or comparing such in a WHERE clause, it does not matter whether the numeric constant is quoted.

Suggest turning on the "general log". Although your logging mechanism seems equivalent, maybe there is something subtle that the general log will point out.

With autocommit=ON and no explicit transactions, I am having trouble imagining how a deadlock could occur. Please capture SHOW ENGINE INNODB STATUS; now and any time you suspect that the problem has recurred.

Please provide SHOW CREATE TABLE and the query that declares that the row is missing. Misuse of FLOAT when searching for non-integral numbers can lead to rounding issues.

Rick James
  • 135,179
  • 13
  • 127
  • 222
  • 1
    PHP version is 7.2. Do you suggest quoting the order id for php? `autocommit` is default, i.e. `ON`. I don't execute manual `COMMIT` and I'm not using transactions at all. `date_created` field is `DATETIME` type. Hope this helps. – Whip Apr 17 '20 at 10:31
  • @VeeK - I added some More. – Rick James Apr 17 '20 at 15:48
1

I think you must give your table structure or you can try to run this query log in your MySQL GUI,

INSERT INTO orders (order_id, parent_order, date_created, status, type, phase, ticker, quantity, entry_price, tp1, tp2, strategy, relative_volume, distance_from_close) VALUES (200413000329794, 0, '2020-04-13 09:23:01', 'OPEN', 'BUY', 0, 'NSE:BALMLAWRIE', 54, 91.3, 94.95, 98.6, 1, 108.87022900763, 6.5966141272621)

I think there is something error like your query doesn't fulfill the unique key table condition or something like that.

0

the problem in such cases can be one of the followings:

  1. data type mismatch
  2. primary key violation
  3. foreign key valuation the most likely to happen in your case is the 2nd or the 3rd one.

Just for testing :try to use INSERT ON DUPLICATE KEY UPDATE .... : instead of insert only in your SQL. .. let us know.

BelloSoft
  • 1
  • 1
-1

This is not a definitive solution but for now I've used the following code to build some redundancy in the system and hopefully get around the problem.

$saveOrderCount = 0;
do {
    $saveOrder = mysqli_query($connect, $saveOrderQ);
    $saveOrderCount++;
} while(!mysqli_affected_rows($connect) and $saveOrderCount < 3); //Will retry upto a max of 3 times

if($saveOrderCount >= 3){
    writeToLog("Failed to insert in file test.php Line 59. Error: ".mysqli_error($connect)."\nQuery: $saveOrderQ");
}
Whip
  • 1,891
  • 22
  • 43
  • Switch to MariaDB, MySQL is lost to Oracle. The first thing I loved about MariaDB was that it was MySQL without the politics. The *second* thing I loved about MariaDB is that it runs in **strict mode** by *default*. Error messages are your best friend. I run Hoo WinTail and for errors I have filters run `C:\cmdmp3win.exe "C:\ding_on.wav"` on my MariaDB queries log so I know when *any* error occurs with the program running otherwise quietly in the background. I don't have time to invest in delving in to this specific problem, I just hope my advice helps out. Good luck! – John Apr 23 '20 at 01:57