All Projects → mangoweb-backend → pg-deadlock-playground

mangoweb-backend / pg-deadlock-playground

Licence: other
Playground for verifying that queries cannot deadlock

Programming Languages

PHP
23972 projects - #3 most used programming language

Projects that are alternatives of or similar to pg-deadlock-playground

UInt256
An UInt256 library written in Swift 4
Stars: ✭ 20 (+17.65%)
Mutual labels:  playground
DoublePendulum
Double Pendulum Playground
Stars: ✭ 26 (+52.94%)
Mutual labels:  playground
WWDC17
WWDC 2017 Scholarship Submission by Phil Zet (Philipp Zakharchenko)
Stars: ✭ 14 (-17.65%)
Mutual labels:  playground
kotlin-playground-wp-plugin
WordPress plugin which allows to embed interactive Kotlin playground to any post via [kotlin] shortcode
Stars: ✭ 35 (+105.88%)
Mutual labels:  playground
getplay
The simplest way to integrate vue-play into your project
Stars: ✭ 13 (-23.53%)
Mutual labels:  playground
NNPlayground
神经网络 iPhone 版
Stars: ✭ 35 (+105.88%)
Mutual labels:  playground
bookshelf
My GraphQL playground
Stars: ✭ 64 (+276.47%)
Mutual labels:  playground
TransactionMaster
A tool for Windows that can make any program work within file-system transactions.
Stars: ✭ 49 (+188.24%)
Mutual labels:  transactions
gdb-automatic-deadlock-detector
Script adds new command to GDB which allows automatically detect C/C++ thread locking and deadlocks in GDB debugger
Stars: ✭ 60 (+252.94%)
Mutual labels:  deadlock
Apriori-and-Eclat-Frequent-Itemset-Mining
Implementation of the Apriori and Eclat algorithms, two of the best-known basic algorithms for mining frequent item sets in a set of transactions, implementation in Python.
Stars: ✭ 36 (+111.76%)
Mutual labels:  transactions
js-playground
A JS playground with some decent visualization
Stars: ✭ 85 (+400%)
Mutual labels:  playground
llpl
Low Level Persistence Library
Stars: ✭ 95 (+458.82%)
Mutual labels:  transactions
mongo-playground
Helps developers run mongo queries
Stars: ✭ 16 (-5.88%)
Mutual labels:  playground
A-Star
A* pathfinding library in Swift.
Stars: ✭ 34 (+100%)
Mutual labels:  playground
ontwik-ui
ontwik-ui - A headless UI library
Stars: ✭ 52 (+205.88%)
Mutual labels:  playground
nearley-playground
⛹ Write Grammars for the Nearley Parser!
Stars: ✭ 76 (+347.06%)
Mutual labels:  playground
tailwind-layouts
Collection of Tailwind Layouts
Stars: ✭ 53 (+211.76%)
Mutual labels:  playground
CodeINN
CodeINN is an instant code editor 📃, that makes programming and development easier. Practice quickly and directly from your web browser, without any setup needed. CodeINN gives the perfect environment to developers technologists, coders computers, and geeks 🤓 to do more with their tech.
Stars: ✭ 39 (+129.41%)
Mutual labels:  playground
horse-messaging
Open Source Messaging Framework. Queues, Channels, Events, Transactions, Distributed Cache
Stars: ✭ 65 (+282.35%)
Mutual labels:  transactions
KuiBaDB
Another OLAP database
Stars: ✭ 297 (+1647.06%)
Mutual labels:  transactions

PostgreSQL Deadlock Playground

A simple tool for playing with multiple concurrent PostgreSQL transactions and testing whether and under what circumstances they may result in deadlock. The verifier class can automatically test given scenario with all possible orderings.

Installation

composer require mangoweb/pg-deadlock-playground

Documentation

Creating Scenario

A scenario is an ordered sequence of steps. Every step is defined as a tuple of connection ID and query.

$scenario = new Mangoweb\PgDeadlockPlayground\Scenario();
$scenario->addStep(0, 'SELECT 123');     // first execute SELECT 123 on connection #0
$scenario->addStep(1, 'SELECT 456');     // then execute SELECT 456 on connection #1
$scenario->addStep(1, 'SELECT 789');     // then execute SELECT 789 on connection #1
$scenario->addStep(2, 'SELECT \'abc\''); // then execute SELECT 'abc' on connection #2
$scenario->addStep(0, 'SELECT NOW()');   // then execute SELECT NOW on connection #0

At any point you can dump the scenario with $scenario->dump() call. In this case it will print

SELECT 123
               SELECT 456
               SELECT 789
                            SELECT 'abc'
SELECT NOW()

Alternatively you can create the same scenario with Scenario::fromArray

$scenario = Mangoweb\PgDeadlockPlayground\Scenario::fromArray([
    ['SELECT 123',   NULL,        NULL            ],
    [NULL,          'SELECT 456', NULL            ],
    [NULL,          'SELECT 789', NULL            ],
    [NULL,           NULL,        'SELECT \'abc\''],
    ['SELECT NOW()', NULL,        NULL            ],
]);

Generating All Scenario Step Orderings

To get all possible step orderings for given scenario call $scenario->getAllOrderings(). For example the following code

$scenario = Mangoweb\PgDeadlockPlayground\Scenario::fromArray([
	['SELECT 123',   NULL       ],
	[NULL,          'SELECT 456'],
	[NULL,          'SELECT 789'],
]);

foreach ($scenario->getAllOrderings() as $scenarioVariant) {
    $scenarioVariant->dump();
}

will output

SELECT 123
             SELECT 456
             SELECT 789
-----------------------
             SELECT 456
SELECT 123
             SELECT 789
-----------------------
             SELECT 456
             SELECT 789
SELECT 123

Executing Scenario

To execute a scenario you need an instance of ScenarioExecutor.

$executor = Mangoweb\PgDeadlockPlayground\ScenarioExecutor::create([
    'dbname' => 'deadlock_playground',
    'user' => 'postgres',
    'password' => '',
]);

Calling $executor->execute($scenario) will always return instance of ScenarioExecutionResult. You can inspect the result by calling $result->dump().

$result = $executor->execute($scenario);
$result->dump();

Understanding Results

The output of $result->dump() is similar to $scenario->dump() but each step is prefixed with important tag.

Tag Meaning
OK Query was successfully completed
FAILED Query failed
WAITING... Query execution has started but cannot be completed because it is waiting on a lock
...SUCCESS A previously waiting query was successfully completed
...FAILURE A previously waiting query failed
DELAYED Query cannot yet be executed because the previous query is still waiting on a lock

Example

Usage

$config = [
    'host' => '127.0.0.1',
    'dbname' => 'deadlock_playground',
    'user' => 'postgres',
    'password' => '',
];

$initQueries = [
    'DROP TABLE IF EXISTS users',
    'CREATE TABLE users (id INTEGER NOT NULL, name TEXT NOT NULL)',
    'INSERT INTO users VALUES (1, \'Logan\')'
];

$executor = Mangoweb\PgDeadlockPlayground\ScenarioExecutor::create($config, $initQueries);
$verifier = new Mangoweb\PgDeadlockPlayground\ScenarioExpectationVerifier($executor);
$verifier->setVerbose();

$verifier->expectAlwaysOk(
    Scenario::fromArray([
        ['START TRANSACTION ISOLATION LEVEL REPEATABLE READ',   NULL],
        ['LOCK users IN SHARE MODE',                            NULL],
        ['SELECT * FROM users WHERE id = 1 FOR UPDATE',         NULL],
        ['COMMIT',                                              NULL],
        [NULL,                                                  'START TRANSACTION ISOLATION LEVEL REPEATABLE READ'],
        [NULL,                                                  'UPDATE users SET name = \'John\' WHERE id = 1'],
        [NULL,                                                  'COMMIT'],
    ])
);

Output

...
SUCCESS: completed without error
in C:\Projects\deadlock-playground\examples\readme.php:25

   [OK]         START TRANSACTION ISOLATION LEVEL REPEATABLE READ
   [OK]         LOCK users IN SHARE MODE
   [OK]         SELECT * FROM users WHERE id = 1 FOR UPDATE
                                                                    [OK]         START TRANSACTION ISOLATION LEVEL REPEATABLE READ
   [OK]         COMMIT
                                                                    [OK]         UPDATE users SET name = 'John' WHERE id = 1
                                                                    [OK]         COMMIT
----------------------------------------------------------------------------------------------------------------------------------

SUCCESS: completed without error
in C:\Projects\deadlock-playground\examples\readme.php:25

   [OK]         START TRANSACTION ISOLATION LEVEL REPEATABLE READ
   [OK]         LOCK users IN SHARE MODE
   [OK]         SELECT * FROM users WHERE id = 1 FOR UPDATE
                                                                    [OK]         START TRANSACTION ISOLATION LEVEL REPEATABLE READ
                                                                    [WAITING...] UPDATE users SET name = 'John' WHERE id = 1
   [OK]         COMMIT
                                                                    [...SUCCESS]
                                                                    [OK]         COMMIT
...
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].