Skip to content

Commit

Permalink
Issue#111: mysqld sometimes crashes
Browse files Browse the repository at this point in the history
Summary:
When get_row_by_rowid() call in ha_rocksdb::secondary_index_read
returns an error, then the error must be returned from
ha_rocksdb::secondary_index_read, too.

Test Plan: mtr

Reviewers: jtolmer, jkedgar, yoshinorim, hermanlee4

Reviewed By: hermanlee4

Subscribers: webscalesql-eng

Differential Revision: https://reviews.facebook.net/D52113
  • Loading branch information
spetrunia authored and jtolmer committed Jan 5, 2016
1 parent dda5c5a commit 2d5d49f
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 5 deletions.
32 changes: 32 additions & 0 deletions mysql-test/suite/rocksdb/r/issue111.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
create table t1 (
pk int not null primary key,
col1 int not null,
col2 int not null,
key(col1)
) engine=rocksdb;
create table ten(a int primary key);
insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table one_k(a int primary key);
insert into one_k select A.a + B.a* 10 + C.a * 100 from ten A, ten B, ten C;
insert into t1 select a,a,a from one_k;
# Start the transaction, get the snapshot
begin;
select * from t1 where col1<10;
pk col1 col2
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
9 9 9
# Connect with another connection and make a conflicting change
begin;
update t1 set col2=123456 where pk=0;
commit;
update t1 set col2=col2+1 where col1 < 10 limit 5;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
drop table t1, ten, one_k;
38 changes: 38 additions & 0 deletions mysql-test/suite/rocksdb/t/issue111.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
--source include/have_rocksdb.inc

connect (con2,localhost,root,,);
connection default;

create table t1 (
pk int not null primary key,
col1 int not null,
col2 int not null,
key(col1)
) engine=rocksdb;

create table ten(a int primary key);
insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);

create table one_k(a int primary key);
insert into one_k select A.a + B.a* 10 + C.a * 100 from ten A, ten B, ten C;

insert into t1 select a,a,a from one_k;

--echo # Start the transaction, get the snapshot
begin;
select * from t1 where col1<10;

--echo # Connect with another connection and make a conflicting change
connection con2;

begin;
update t1 set col2=123456 where pk=0;
commit;

connection default;

--error ER_LOCK_DEADLOCK
update t1 set col2=col2+1 where col1 < 10 limit 5;

disconnect con2;
drop table t1, ten, one_k;
13 changes: 8 additions & 5 deletions storage/rocksdb/ha_rocksdb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3757,6 +3757,9 @@ int ha_rocksdb::secondary_index_read(int keyno, uchar *buf)
{
stats.rows_requested++;

/* Use STATUS_NOT_FOUND when record not found or some error occurred */
table->status= STATUS_NOT_FOUND;

if (scan_it->Valid())
{
rocksdb::Slice key= scan_it->key();
Expand Down Expand Up @@ -3790,11 +3793,10 @@ int ha_rocksdb::secondary_index_read(int keyno, uchar *buf)
stats.rows_read++;
stats.rows_index_next++;
update_row_stats(table, ROWS_READ);
return rc;
}
return rc;
}
}
table->status= STATUS_NOT_FOUND;
return HA_ERR_END_OF_FILE;
}

Expand Down Expand Up @@ -4193,7 +4195,7 @@ int ha_rocksdb::index_read_map_impl(uchar *buf, const uchar *key,

if (rc)
{
table->status= STATUS_NOT_FOUND; /* Only not found error is possible */
table->status= STATUS_NOT_FOUND; /* This status is returned on any error */
io_perf_end_and_record();
DBUG_RETURN(rc);
}
Expand Down Expand Up @@ -4634,19 +4636,20 @@ int ha_rocksdb::get_row_by_rowid(uchar *buf, const char *rowid, uint rowid_size)
}
found= !s.IsNotFound();

table->status= STATUS_NOT_FOUND;
if (found)
{
last_rowkey.copy((const char*)rowid, rowid_size, &my_charset_bin);
rc= convert_record_from_storage_format(&key_slice, buf);
table->status= 0;
if (!rc)
table->status= 0;
}
else
{
/*
Note: we don't need to unlock the row. It is intentional that we keep
locks on rows that don't exist.
*/
table->status= STATUS_NOT_FOUND;
rc= HA_ERR_KEY_NOT_FOUND;
}

Expand Down

0 comments on commit 2d5d49f

Please sign in to comment.