Skip to content

Use MySQL 8.0 from Docker #2

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

Merged
merged 1 commit into from
Jan 23, 2023
Merged

Use MySQL 8.0 from Docker #2

merged 1 commit into from
Jan 23, 2023

Conversation

rosa
Copy link
Member

@rosa rosa commented Jan 23, 2023

So it doesn't interfere with local MySQL 5.7 used in most of our apps, as the DBs and the options aren't compatible.

This is mostly taken from @djmb's setup for solid_cache πŸ™‡β€β™€οΈ

So it doesn't interfere with local MySQL 5.7 used in most of our
apps, as the DBs and the options aren't compatible.
@rosa rosa merged commit d8963f4 into main Jan 23, 2023
@rosa rosa deleted the use-docker-for-mysql-8 branch January 23, 2023 17:13
hms added a commit to ikyn-inc/solid_queue that referenced this pull request Aug 5, 2024
Postgres only Issue:
Jobs that meet all of the following conditions will result in the database connection entering an invalid and
unrecoverable state, requiring a rollback before any further database requests (reads or writes) can be made:

1. Use SolidQueue's 'limits_concurrency' macro
2. Are enqueued inside an application-level transaction
3. The limits_concurrency key already exists in the Semaphore table (i.e., this is job 2 - N for a given key)

SolidQueue uses the following design pattern to implement the conflict detection of the limits_concurrency
macro which works 100% correctly, 100% of the time, with MySQL and SQLite:
  begin
    Semaphore.create!(...)
      no_conflict_path()
    rescue ActiveRecord::RecordNotUnique
      handle_concurrency_conflict()
    end

The problem is Postgres:
It's not possible to rescue and recover from an insert failing due to an conflict on unique index (or any other
database constraint). Until a rollback is executed, the database connection is in an invalid state and unusable.

Possible Solutions:
1. Nested transactions
   + Easiest to implement
   + Portable across all three standard Rails databases
   - Has significant performance issues, especially for databases under load or replicated databases with
     long-running queries (Postgres specific)
   - Requires using Raise and Rescue for flow of control (performance, less than ideal coding practice)
   - Requires issuing a rollback (performance, additional command that must round trip from the client to
     database and back)

2. Insert into the Semaphore table using 'INSERT INTO table (..) VALUES (...) ON CONFLICT DO NOTHING' syntax
   + ANSI standard syntax (not a Postgres 'one off' solution)
   + Rails natively supports identifying database adaptors that support this syntax, making the implementation
     portable and maintainable
   + Supported by Postgres and allows this issue to be addressed
   + Does not require Raise and Rescue for flow of control
   + Performant (native, fast path database functionality)

Solution:
Leverage Rails connection adaptors allowing code to easily identifying supported database features/functionality to
implement strategy rails#2 (INSERT ON CONFLICT) for those databases that support it (i.e., Postgres) and leave the
original implementation of rescuing RecordNotUnique for those that do not.

Note: Although I'd love to take credit for the "quality" of this implementation, all that credit belongs to @rosa who's
excellent feedback on an earlier implementation resulted in this significantly better implementation.
hms added a commit to ikyn-inc/solid_queue that referenced this pull request Aug 5, 2024
Postgres only Issue:
Jobs that meet all of the following conditions will result in the database connection entering an invalid and
unrecoverable state, requiring a rollback before any further database requests (reads or writes) can be made:

1. Use SolidQueue's 'limits_concurrency' macro
2. Are enqueued inside an application-level transaction
3. The limits_concurrency key already exists in the Semaphore table (i.e., this is job 2 - N for a given key)

SolidQueue uses the following design pattern to implement the conflict detection of the limits_concurrency
macro which works 100% correctly, 100% of the time, with MySQL and SQLite:
  begin
    Semaphore.create!(...)
      no_conflict_path()
    rescue ActiveRecord::RecordNotUnique
      handle_concurrency_conflict()
    end

The problem is Postgres:
It's not possible to rescue and recover from an insert failing due to an conflict on unique index (or any other
database constraint). Until a rollback is executed, the database connection is in an invalid state and unusable.

Possible Solutions:
1. Nested transactions
   + Easiest to implement
   + Portable across all three standard Rails databases
   - Has significant performance issues, especially for databases under load or replicated databases with
     long-running queries (Postgres specific)
   - Requires using Raise and Rescue for flow of control (performance, less than ideal coding practice)
   - Requires issuing a rollback (performance, additional command that must round trip from the client to
     database and back)

2. Insert into the Semaphore table using 'INSERT INTO table (..) VALUES (...) ON CONFLICT DO NOTHING' syntax
   + ANSI standard syntax (not a Postgres 'one off' solution)
   + Rails natively supports identifying database adaptors that support this syntax, making the implementation
     portable and maintainable
   + Supported by Postgres and allows this issue to be addressed
   + Does not require Raise and Rescue for flow of control
   + Performant (native, fast path database functionality)

Solution:
Leverage Rails connection adaptors allowing code to easily identifying supported database features/functionality to
implement strategy rails#2 (INSERT ON CONFLICT) for those databases that support it (i.e., Postgres) and leave the
original implementation of rescuing RecordNotUnique for those that do not.

Note: Although I'd love to take credit for the "quality" of this implementation, all that credit belongs to @rosa who's
excellent feedback on an earlier implementation resulted in this significantly better implementation.
hms pushed a commit to ikyn-inc/solid_queue that referenced this pull request Aug 5, 2024
List failed jobs and jobs in a given queue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant