-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
oltp: inserts duplicate keys when using multiple threads #65
Comments
OK - i noticed that the key is deleted before it is re-inserted, and therefore there should never be a duplicate. |
The conflict occurs on the primary key. You are right, the With multiple concurrent sessions nothing guarantees multiple rows with the same IDs cannot be generated by concurrent transactions. In that case, conflicting transactions fail as they should, and sysbench tries to detect such failures and restarts the failed transactions. But exact behavior is implementation-specific, so it's not always detected by sysbench correctly. MySQL/InnoDB would fail with a deadlock error or a lock wait timeout, and sysbench handles those in the MySQL driver (drv_mysql.c). PostgreSQL fails with a duplicate key error in such cases due to a different MVCC behavior. See issue #10, especially links to StackExchange discussions for all the gory details. I fixed it by making the PostgreSQL driver handle duplicate key errors by restarting transactions rather than failing the benchmark. But the problem you are facing brings up a valid issue with the current approach: a non-InnoDB storage engine for MySQL may have a different MVCC behavior. For example, a PostgreSQL-like behavior, which I guess is the case here. I'm going to reopen the issue and commit an experimental fix for you to test. Thank you. |
My storage engine does not yet properly implement transactions. This leads to a race condition in oltp.lua, when two threads try to insert the same key:
A cheap way to fix this would be to make sure that each thread only has its own range of primary keys. If you come up with a fix then I'll test it. Thanks for all your efforts! |
Oh, I see. In this case you have two opions:
--- a/sysbench/tests/db/oltp.lua
+++ b/sysbench/tests/db/oltp.lua
@@ -5,7 +5,7 @@ dofile(pathtest .. "common.lua")
function thread_init(thread_id)
set_vars()
- if (((db_driver == "mysql") or (db_driver == "attachsql")) and mysql_table_engine == "myisam") then
+ if (((db_driver == "mysql") or (db_driver == "attachsql")) and (mysql_table_engine == "myisam") or mysql_table_engine == "yourengine") then
begin_query = "LOCK TABLES sbtest WRITE"
commit_query = "UNLOCK TABLES"
else
diff --git a/sysbench/tests/db/oltp.lua b/sysbench/tests/db/oltp.lua
index 985ca0c..9c87091 100644
--- a/sysbench/tests/db/oltp.lua
+++ b/sysbench/tests/db/oltp.lua
@@ -78,7 +78,7 @@ function event(thread_id)
for i=1, oltp_delete_inserts do
- i = sb_rand(1, oltp_table_size)
+ i = sb_rand_uniq(1, oltp_table_size)
rs = db_query("DELETE FROM " .. table_name .. " WHERE id=" .. i)
|
The first solution (using LOCK TABLES) works, but i had to change
to
Your second solution (using sb_rand_uniq) also works. I'll use this as a Thanks for your help! |
Thanks for the update. I'll fix the |
I use sysbench 1.0, and run oltp.lua with the following options:
Sometimes (but not always) I get the following message:
This error only appears when I use multiple threads. With just one thread everything works as expected.
In oltp.lua I found this:
From what I understand, each thread creates a random ID, but how do you make sure that they are always unique?
(Disclaimer: I am not using InnoDB but my own storage engine. I have never seen this behaviour with InnoDB. I'm trying to understand what exactly happends so I can figure out if the problem is in my storage engine or in sysbench.)
The text was updated successfully, but these errors were encountered: