Skip to content

Java deadlock in test with multiple simultaneous transactions #7556

@archiecobbs

Description

@archiecobbs

As part of a separate project, I'm running unit tests that check database behavior when conflicting and non-conflicting transactions are run at the same time.

In the case of CockroachDB, one of these tests deadlocks and hangs forever. Instead, some sort of retry exception should be thrown.

Interestingly, it is a non-conflicting transaction test that is hanging (the conflicting transaction test is correctly throwing a retry exception).

The version I'm testing:

build:     beta-20160616 @ 2016/06/30 13:57:29 (go1.6.2)
admin:     http://localhost:9696
sql:       postgresql://root@localhost:26257?sslmode=disable
logs:      /usr/local/var/cockroach/logs
store[0]:  path=/usr/local/var/cockroach

Test setup:

CREATE TABLE IF NOT EXISTS "KV" (
  "kv_key" BYTES PRIMARY KEY NOT NULL,
  "kv_value" BYTES NOT NULL
);
DELETE FROM "KV";

Unit test that hangs: testNonconflictingTransactions():

What this test does:

Open 10 transactions T1, T2, ..., T10

T1: SELECT "kv_key", "kv_value" FROM "KV" WHERE "kv_key" >= ?1 ORDER BY "kv_key" ASC LIMIT 1 [?1 = 00]
T1: UPSERT INTO "KV" ("kv_key", "kv_value") VALUES (?1, ?2) [?1 = 80, ?2 = 02]
T2: SELECT "kv_key", "kv_value" FROM "KV" WHERE "kv_key" >= ?1 ORDER BY "kv_key" ASC LIMIT 1 [?1 = 01]
T2: UPSERT INTO "KV" ("kv_key", "kv_value") VALUES (?1, ?2) [?1 = 81, ?2 = 02]
T3: SELECT "kv_key", "kv_value" FROM "KV" WHERE "kv_key" >= ?1 ORDER BY "kv_key" ASC LIMIT 1 [?1 = 02]

The test hangs at this point. The stuck thread is here:

"pool-1-thread-10" prio=5 tid=0x00007fbb7e037000 nid=0x6703 runnable [0x000000012259d000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:152)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:143)
    at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:112)
    at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:70)
    at org.postgresql.core.PGStream.ReceiveChar(PGStream.java:283)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1799)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:200)
    - locked <0x00000007adec7888> (a org.postgresql.core.v3.QueryExecutorImpl)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:424)
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:161)
    at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:114)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.postgresql.ds.PGPooledConnection$StatementHandler.invoke(PGPooledConnection.java:426)
    at com.sun.proxy.$Proxy13.executeQuery(Unknown Source)
    at org.jsimpledb.kv.sql.SQLKVTransaction.query(SQLKVTransaction.java:279)
    at org.jsimpledb.kv.sql.SQLKVTransaction.queryKVPair(SQLKVTransaction.java:250)
    at org.jsimpledb.kv.sql.SQLKVTransaction.getAtLeast(SQLKVTransaction.java:100)
    - locked <0x00000007aded3008> (a org.jsimpledb.kv.cockroach.CockroachKVTransaction)
    at org.jsimpledb.kv.test.KVDatabaseTest$Reader.call(KVDatabaseTest.java:862)
    at org.jsimpledb.kv.test.KVDatabaseTest$Reader.call(KVDatabaseTest.java:842)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

To run these tests yourself:

  1. git clone git@github.com:archiecobbs/jsimpledb
  2. cd jsimpledb
  3. git checkout 89937aa672efd9ab833e28809259d2836bb3e8cb
  4. mvn install -Dmaven.javadoc.skip=true -Dmaven.test.skip=true
  5. Edit pom.xml, and uncomment the <cockroachURL> line (edit to suit)
  6. cd jsimpledb-kv-cockroach
  7. cockroach sql -e 'create database if not exists jsimpledb'
  8. mvn test
  9. When test hangs, hit CTRL-\ to see Java stack trace

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions