rubydb 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitattributes +20 -0
- data/.github/ISSUE_TEMPLATE/bug.yml +0 -0
- data/.github/ISSUE_TEMPLATE/feature.yml +0 -0
- data/.github/ISSUE_TEMPLATE/performance.yml +0 -0
- data/.github/ISSUE_TEMPLATE/security.yml +0 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +15 -0
- data/.github/dependabot.yml +0 -0
- data/.github/workflows/benchmark.yml +26 -0
- data/.github/workflows/compatibility.yml +63 -0
- data/.github/workflows/fuzz.yml +33 -0
- data/.github/workflows/lint.yml +21 -0
- data/.github/workflows/operations.yml +24 -0
- data/.github/workflows/production-validation.yml +111 -0
- data/.github/workflows/release.yml +77 -0
- data/.github/workflows/security.yml +37 -0
- data/.github/workflows/test.yml +26 -0
- data/.github/workflows/workload.yml +58 -0
- data/.gitignore +43 -0
- data/.rspec +4 -0
- data/.rubocop.yml +44 -0
- data/.ruby-version +1 -0
- data/.standard.yml +14 -0
- data/ARCHITECTURE.md +21 -0
- data/CHANGELOG.md +31 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/CONTRIBUTING.md +29 -0
- data/GOVERNANCE.md +16 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +71 -0
- data/LICENSE +60 -0
- data/README.md +162 -0
- data/ROADMAP.md +27 -0
- data/Rakefile +71 -0
- data/SECURITY.md +54 -0
- data/SUPPORT.md +14 -0
- data/adapters/activerecord/Gemfile +11 -0
- data/adapters/activerecord/README.md +9 -0
- data/adapters/activerecord/lib/active_record/connection_adapters/rubydb_adapter.rb +887 -0
- data/adapters/activerecord/rubydb-activerecord.gemspec +27 -0
- data/adapters/activerecord/spec/rubydb_adapter_integration_spec.rb +151 -0
- data/adapters/ruby/README.md +18 -0
- data/adapters/sequel/README.md +11 -0
- data/bin/rubydb +19 -0
- data/bin/rubydb-server +126 -0
- data/config/development.yml +0 -0
- data/config/monitoring/prometheus-alerts.yml +39 -0
- data/config/production.yml +36 -0
- data/config/test.yml +0 -0
- data/docs/README.md +71 -0
- data/docs/architecture/concurrency.md +14 -0
- data/docs/architecture/current-state.md +125 -0
- data/docs/architecture/execution-engine.md +25 -0
- data/docs/architecture/indexes.md +19 -0
- data/docs/architecture/mvcc.md +19 -0
- data/docs/architecture/overview.md +13 -0
- data/docs/architecture/pages.md +11 -0
- data/docs/architecture/production-roadmap.md +82 -0
- data/docs/architecture/query-planner.md +20 -0
- data/docs/architecture/recovery.md +18 -0
- data/docs/architecture/sql-engine.md +12 -0
- data/docs/architecture/storage-engine.md +14 -0
- data/docs/architecture/transactions.md +10 -0
- data/docs/architecture/wal.md +28 -0
- data/docs/cli-cheatsheet.md +98 -0
- data/docs/cli.md +275 -0
- data/docs/contributing/architecture.md +9 -0
- data/docs/contributing/benchmarking.md +14 -0
- data/docs/contributing/development.md +16 -0
- data/docs/contributing/release-process.md +49 -0
- data/docs/contributing/testing.md +16 -0
- data/docs/debugging.md +229 -0
- data/docs/developer/branching.md +10 -0
- data/docs/developer/database-diff.md +10 -0
- data/docs/developer/local-development.md +17 -0
- data/docs/developer/snapshots.md +9 -0
- data/docs/developer/temporal-data.md +10 -0
- data/docs/developer-guide.md +297 -0
- data/docs/getting-started/first-database.md +16 -0
- data/docs/getting-started/first-query.md +13 -0
- data/docs/getting-started/installation.md +19 -0
- data/docs/getting-started/local-to-production.md +300 -0
- data/docs/getting-started/quickstart.md +17 -0
- data/docs/getting-started/rails.md +16 -0
- data/docs/hardening_backlog.md +93 -0
- data/docs/lessons-learned.md +112 -0
- data/docs/operations/backups.md +33 -0
- data/docs/operations/disaster-recovery.md +31 -0
- data/docs/operations/failover.md +30 -0
- data/docs/operations/monitoring.md +25 -0
- data/docs/operations/production-guide.md +295 -0
- data/docs/operations/production-runbook.md +45 -0
- data/docs/operations/replication.md +33 -0
- data/docs/operations/restore.md +6 -0
- data/docs/operations/runbook.md +34 -0
- data/docs/operations/upgrades.md +14 -0
- data/docs/operations/workload-testing.md +17 -0
- data/docs/production-readiness.md +118 -0
- data/docs/production_validation.md +150 -0
- data/docs/rails/active-record.md +11 -0
- data/docs/rails/compatibility-guide.md +90 -0
- data/docs/rails/database-yml.md +92 -0
- data/docs/rails/installation.md +17 -0
- data/docs/rails/migrations.md +17 -0
- data/docs/rails/production.md +82 -0
- data/docs/rails/troubleshooting.md +18 -0
- data/docs/release.md +59 -0
- data/docs/server/architecture.md +10 -0
- data/docs/server/authentication.md +10 -0
- data/docs/server/configuration.md +16 -0
- data/docs/server/connection-pooling.md +10 -0
- data/docs/server/deployment.md +10 -0
- data/docs/server/protocol.md +12 -0
- data/docs/sql/compatibility-guide.md +82 -0
- data/docs/sql/compatibility.md +39 -0
- data/docs/sql/data-types.md +10 -0
- data/docs/sql/functions.md +9 -0
- data/docs/sql/joins.md +9 -0
- data/docs/sql/operators.md +9 -0
- data/docs/sql/sqlite-compatibility.md +21 -0
- data/docs/sql/syntax.md +10 -0
- data/docs/sql/transactions.md +10 -0
- data/docs/troubleshooting.md +244 -0
- data/exe/rubydb +23 -0
- data/lib/rubydb/backup/archive.rb +334 -0
- data/lib/rubydb/backup/backup.rb +401 -0
- data/lib/rubydb/backup/incremental.rb +353 -0
- data/lib/rubydb/backup/restore.rb +290 -0
- data/lib/rubydb/backup/snapshot.rb +267 -0
- data/lib/rubydb/backup/verification.rb +279 -0
- data/lib/rubydb/branching/branch.rb +181 -0
- data/lib/rubydb/branching/branch_manager.rb +311 -0
- data/lib/rubydb/branching/branch_metadata.rb +140 -0
- data/lib/rubydb/branching/checkout.rb +166 -0
- data/lib/rubydb/branching/copy_on_write.rb +272 -0
- data/lib/rubydb/branching/diff.rb +138 -0
- data/lib/rubydb/branching/merge.rb +285 -0
- data/lib/rubydb/build_info.rb +15 -0
- data/lib/rubydb/catalog/catalog.rb +391 -0
- data/lib/rubydb/catalog/column.rb +112 -0
- data/lib/rubydb/catalog/constraint.rb +180 -0
- data/lib/rubydb/catalog/database.rb +184 -0
- data/lib/rubydb/catalog/index.rb +97 -0
- data/lib/rubydb/catalog/schema.rb +103 -0
- data/lib/rubydb/catalog/sequence.rb +90 -0
- data/lib/rubydb/catalog/system_catalog.rb +698 -0
- data/lib/rubydb/catalog/table.rb +178 -0
- data/lib/rubydb/catalog/trigger.rb +102 -0
- data/lib/rubydb/catalog/view.rb +66 -0
- data/lib/rubydb/cli/application.rb +163 -0
- data/lib/rubydb/cli/commands/backup.rb +81 -0
- data/lib/rubydb/cli/commands/branch.rb +72 -0
- data/lib/rubydb/cli/commands/checkout.rb +54 -0
- data/lib/rubydb/cli/commands/create.rb +58 -0
- data/lib/rubydb/cli/commands/diff.rb +77 -0
- data/lib/rubydb/cli/commands/doctor.rb +74 -0
- data/lib/rubydb/cli/commands/drop.rb +57 -0
- data/lib/rubydb/cli/commands/init.rb +102 -0
- data/lib/rubydb/cli/commands/inspect.rb +95 -0
- data/lib/rubydb/cli/commands/merge.rb +63 -0
- data/lib/rubydb/cli/commands/migrate.rb +62 -0
- data/lib/rubydb/cli/commands/restart.rb +39 -0
- data/lib/rubydb/cli/commands/restore.rb +121 -0
- data/lib/rubydb/cli/commands/shell.rb +365 -0
- data/lib/rubydb/cli/commands/snapshot.rb +79 -0
- data/lib/rubydb/cli/commands/start.rb +82 -0
- data/lib/rubydb/cli/commands/status.rb +92 -0
- data/lib/rubydb/cli/commands/stop.rb +47 -0
- data/lib/rubydb/cli/commands/vacuum.rb +58 -0
- data/lib/rubydb/cli/formatter.rb +221 -0
- data/lib/rubydb/cli/output.rb +168 -0
- data/lib/rubydb/client/client.rb +304 -0
- data/lib/rubydb/client/connection.rb +415 -0
- data/lib/rubydb/client/connection_pool.rb +168 -0
- data/lib/rubydb/client/connection_url.rb +96 -0
- data/lib/rubydb/client/prepared_statement.rb +60 -0
- data/lib/rubydb/client/result.rb +123 -0
- data/lib/rubydb/client/statement.rb +52 -0
- data/lib/rubydb/client/transaction.rb +130 -0
- data/lib/rubydb/concurrency/concurrency.rb +19 -0
- data/lib/rubydb/concurrency/deadlock_detector.rb +150 -0
- data/lib/rubydb/concurrency/latch.rb +101 -0
- data/lib/rubydb/concurrency/lock_graph.rb +165 -0
- data/lib/rubydb/concurrency/mutex.rb +183 -0
- data/lib/rubydb/concurrency/rw_lock.rb +180 -0
- data/lib/rubydb/concurrency/scheduler.rb +250 -0
- data/lib/rubydb/concurrency/worker_pool.rb +143 -0
- data/lib/rubydb/configuration/config.rb +170 -0
- data/lib/rubydb/configuration/defaults.rb +179 -0
- data/lib/rubydb/configuration/environment.rb +152 -0
- data/lib/rubydb/configuration/parser.rb +185 -0
- data/lib/rubydb/configuration/validation.rb +221 -0
- data/lib/rubydb/constants.rb +74 -0
- data/lib/rubydb/constraints/check.rb +181 -0
- data/lib/rubydb/constraints/constraint.rb +101 -0
- data/lib/rubydb/constraints/foreign_key.rb +130 -0
- data/lib/rubydb/constraints/not_null.rb +64 -0
- data/lib/rubydb/constraints/primary_key.rb +99 -0
- data/lib/rubydb/constraints/unique.rb +108 -0
- data/lib/rubydb/constraints/validator.rb +350 -0
- data/lib/rubydb/errors/authentication_error.rb +10 -0
- data/lib/rubydb/errors/authorization_error.rb +23 -0
- data/lib/rubydb/errors/client_error.rb +10 -0
- data/lib/rubydb/errors/configuration_error.rb +10 -0
- data/lib/rubydb/errors/connection_error.rb +10 -0
- data/lib/rubydb/errors/constraint_error.rb +23 -0
- data/lib/rubydb/errors/corruption_error.rb +10 -0
- data/lib/rubydb/errors/database_error.rb +10 -0
- data/lib/rubydb/errors/error.rb +20 -0
- data/lib/rubydb/errors/execution_error.rb +10 -0
- data/lib/rubydb/errors/parser_error.rb +10 -0
- data/lib/rubydb/errors/recovery_error.rb +10 -0
- data/lib/rubydb/errors/replication_error.rb +10 -0
- data/lib/rubydb/errors/server_error.rb +6 -0
- data/lib/rubydb/errors/storage_error.rb +10 -0
- data/lib/rubydb/errors/transaction_error.rb +10 -0
- data/lib/rubydb/execution/aggregate_executor.rb +138 -0
- data/lib/rubydb/execution/delete_executor.rb +112 -0
- data/lib/rubydb/execution/distinct_executor.rb +135 -0
- data/lib/rubydb/execution/executor.rb +1192 -0
- data/lib/rubydb/execution/expression.rb +193 -0
- data/lib/rubydb/execution/index_scan.rb +142 -0
- data/lib/rubydb/execution/insert_executor.rb +217 -0
- data/lib/rubydb/execution/join_executor.rb +249 -0
- data/lib/rubydb/execution/limit_executor.rb +85 -0
- data/lib/rubydb/execution/optimizer.rb +215 -0
- data/lib/rubydb/execution/plan.rb +361 -0
- data/lib/rubydb/execution/planner.rb +546 -0
- data/lib/rubydb/execution/predicate.rb +235 -0
- data/lib/rubydb/execution/scan.rb +49 -0
- data/lib/rubydb/execution/sequential_scan.rb +63 -0
- data/lib/rubydb/execution/sort_executor.rb +185 -0
- data/lib/rubydb/execution/update_executor.rb +162 -0
- data/lib/rubydb/functions/aggregate.rb +70 -0
- data/lib/rubydb/functions/date_functions.rb +278 -0
- data/lib/rubydb/functions/function.rb +85 -0
- data/lib/rubydb/functions/json_functions.rb +215 -0
- data/lib/rubydb/functions/numeric_functions.rb +346 -0
- data/lib/rubydb/functions/scalar.rb +52 -0
- data/lib/rubydb/functions/string_functions.rb +383 -0
- data/lib/rubydb/functions/system_functions.rb +246 -0
- data/lib/rubydb/history/as_of.rb +238 -0
- data/lib/rubydb/history/change.rb +105 -0
- data/lib/rubydb/history/history.rb +131 -0
- data/lib/rubydb/history/history_manager.rb +229 -0
- data/lib/rubydb/history/temporal_query.rb +202 -0
- data/lib/rubydb/history/timeline.rb +144 -0
- data/lib/rubydb/indexes/btree.rb +186 -0
- data/lib/rubydb/indexes/btree_cursor.rb +258 -0
- data/lib/rubydb/indexes/btree_node.rb +385 -0
- data/lib/rubydb/indexes/hash_index.rb +150 -0
- data/lib/rubydb/indexes/index.rb +71 -0
- data/lib/rubydb/indexes/index_manager.rb +406 -0
- data/lib/rubydb/indexes/index_scan.rb +470 -0
- data/lib/rubydb/migrations/migration.rb +254 -0
- data/lib/rubydb/migrations/migration_lock.rb +146 -0
- data/lib/rubydb/migrations/migration_manager.rb +176 -0
- data/lib/rubydb/migrations/migration_version.rb +71 -0
- data/lib/rubydb/migrations/schema_diff.rb +211 -0
- data/lib/rubydb/migrations/schema_version.rb +64 -0
- data/lib/rubydb/monitoring/events.rb +160 -0
- data/lib/rubydb/monitoring/health.rb +222 -0
- data/lib/rubydb/monitoring/logger.rb +193 -0
- data/lib/rubydb/monitoring/metrics.rb +359 -0
- data/lib/rubydb/monitoring/performance.rb +176 -0
- data/lib/rubydb/monitoring/statistics.rb +170 -0
- data/lib/rubydb/mvcc/garbage_collector.rb +199 -0
- data/lib/rubydb/mvcc/mvcc.rb +16 -0
- data/lib/rubydb/mvcc/snapshot.rb +147 -0
- data/lib/rubydb/mvcc/vacuum.rb +180 -0
- data/lib/rubydb/mvcc/version.rb +106 -0
- data/lib/rubydb/mvcc/version_store.rb +398 -0
- data/lib/rubydb/mvcc/visibility.rb +109 -0
- data/lib/rubydb/protocol/capabilities.rb +125 -0
- data/lib/rubydb/protocol/decoder.rb +145 -0
- data/lib/rubydb/protocol/encoder.rb +136 -0
- data/lib/rubydb/protocol/handshake.rb +305 -0
- data/lib/rubydb/protocol/message.rb +121 -0
- data/lib/rubydb/protocol/protocol.rb +277 -0
- data/lib/rubydb/protocol/version.rb +54 -0
- data/lib/rubydb/rails/adapter.rb +239 -0
- data/lib/rubydb/rails/connection.rb +314 -0
- data/lib/rubydb/rails/database_statements.rb +122 -0
- data/lib/rubydb/rails/migration.rb +131 -0
- data/lib/rubydb/rails/quoting.rb +109 -0
- data/lib/rubydb/rails/result.rb +120 -0
- data/lib/rubydb/rails/schema_statements.rb +339 -0
- data/lib/rubydb/rails/transaction.rb +105 -0
- data/lib/rubydb/rails/type.rb +126 -0
- data/lib/rubydb/recovery/checkpoint.rb +257 -0
- data/lib/rubydb/recovery/consistency.rb +467 -0
- data/lib/rubydb/recovery/corruption_detector.rb +5 -0
- data/lib/rubydb/recovery/crash_recovery.rb +387 -0
- data/lib/rubydb/recovery/recovery_manager.rb +206 -0
- data/lib/rubydb/recovery/redo.rb +237 -0
- data/lib/rubydb/recovery/undo.rb +206 -0
- data/lib/rubydb/replication/failover.rb +5 -0
- data/lib/rubydb/replication/fencing.rb +63 -0
- data/lib/rubydb/replication/primary.rb +450 -0
- data/lib/rubydb/replication/replica.rb +384 -0
- data/lib/rubydb/replication/replication_log.rb +200 -0
- data/lib/rubydb/replication/replication_manager.rb +308 -0
- data/lib/rubydb/replication/replication_slot.rb +295 -0
- data/lib/rubydb/replication/replication_stream.rb +201 -0
- data/lib/rubydb/rubydb.rb +560 -0
- data/lib/rubydb/security/access_control.rb +254 -0
- data/lib/rubydb/security/audit_log.rb +213 -0
- data/lib/rubydb/security/authentication.rb +302 -0
- data/lib/rubydb/security/authorization.rb +282 -0
- data/lib/rubydb/security/credentials.rb +196 -0
- data/lib/rubydb/security/password.rb +215 -0
- data/lib/rubydb/security/permissions.rb +74 -0
- data/lib/rubydb/security/role.rb +101 -0
- data/lib/rubydb/security/user.rb +86 -0
- data/lib/rubydb/server/connection.rb +366 -0
- data/lib/rubydb/server/connection_pool.rb +193 -0
- data/lib/rubydb/server/lifecycle.rb +228 -0
- data/lib/rubydb/server/listener.rb +136 -0
- data/lib/rubydb/server/request_handler.rb +276 -0
- data/lib/rubydb/server/server.rb +364 -0
- data/lib/rubydb/server/session.rb +369 -0
- data/lib/rubydb/server/worker.rb +210 -0
- data/lib/rubydb/server/worker_pool.rb +168 -0
- data/lib/rubydb/sql/ast/alter_table.rb +169 -0
- data/lib/rubydb/sql/ast/begin_transaction.rb +47 -0
- data/lib/rubydb/sql/ast/commit.rb +37 -0
- data/lib/rubydb/sql/ast/constraint.rb +83 -0
- data/lib/rubydb/sql/ast/create_database.rb +41 -0
- data/lib/rubydb/sql/ast/create_index.rb +61 -0
- data/lib/rubydb/sql/ast/create_schema.rb +52 -0
- data/lib/rubydb/sql/ast/create_table.rb +187 -0
- data/lib/rubydb/sql/ast/delete.rb +54 -0
- data/lib/rubydb/sql/ast/drop_database.rb +41 -0
- data/lib/rubydb/sql/ast/drop_index.rb +41 -0
- data/lib/rubydb/sql/ast/drop_schema.rb +49 -0
- data/lib/rubydb/sql/ast/drop_table.rb +49 -0
- data/lib/rubydb/sql/ast/explain.rb +64 -0
- data/lib/rubydb/sql/ast/expression.rb +604 -0
- data/lib/rubydb/sql/ast/insert.rb +82 -0
- data/lib/rubydb/sql/ast/node.rb +42 -0
- data/lib/rubydb/sql/ast/rollback.rb +63 -0
- data/lib/rubydb/sql/ast/savepoint.rb +59 -0
- data/lib/rubydb/sql/ast/select.rb +88 -0
- data/lib/rubydb/sql/ast/set_operation.rb +20 -0
- data/lib/rubydb/sql/ast/trigger.rb +29 -0
- data/lib/rubydb/sql/ast/update.rb +88 -0
- data/lib/rubydb/sql/ast/vacuum.rb +19 -0
- data/lib/rubydb/sql/ast/view.rb +32 -0
- data/lib/rubydb/sql/ast/with.rb +32 -0
- data/lib/rubydb/sql/grammar.rb +86 -0
- data/lib/rubydb/sql/keywords.rb +156 -0
- data/lib/rubydb/sql/lexer.rb +214 -0
- data/lib/rubydb/sql/operators.rb +100 -0
- data/lib/rubydb/sql/parser.rb +1185 -0
- data/lib/rubydb/sql/planner/analyzer.rb +302 -0
- data/lib/rubydb/sql/planner/binder.rb +550 -0
- data/lib/rubydb/sql/planner/type_checker.rb +431 -0
- data/lib/rubydb/sql/token.rb +210 -0
- data/lib/rubydb/storage/buffer_frame.rb +44 -0
- data/lib/rubydb/storage/buffer_pool.rb +155 -0
- data/lib/rubydb/storage/database_lock.rb +74 -0
- data/lib/rubydb/storage/deserializer.rb +342 -0
- data/lib/rubydb/storage/engine.rb +2338 -0
- data/lib/rubydb/storage/file_manager.rb +187 -0
- data/lib/rubydb/storage/free_space_map.rb +81 -0
- data/lib/rubydb/storage/page.rb +94 -0
- data/lib/rubydb/storage/page_allocator.rb +855 -0
- data/lib/rubydb/storage/page_header.rb +67 -0
- data/lib/rubydb/storage/page_manager.rb +131 -0
- data/lib/rubydb/storage/record.rb +58 -0
- data/lib/rubydb/storage/row.rb +78 -0
- data/lib/rubydb/storage/serializer.rb +51 -0
- data/lib/rubydb/storage/storage_layout.rb +151 -0
- data/lib/rubydb/storage/storage_manager.rb +114 -0
- data/lib/rubydb/storage/tuple.rb +461 -0
- data/lib/rubydb/storage/visibility_map.rb +984 -0
- data/lib/rubydb/transactions/commit_manager.rb +220 -0
- data/lib/rubydb/transactions/isolation.rb +98 -0
- data/lib/rubydb/transactions/lock.rb +76 -0
- data/lib/rubydb/transactions/lock_manager.rb +362 -0
- data/lib/rubydb/transactions/savepoint.rb +143 -0
- data/lib/rubydb/transactions/transaction.rb +215 -0
- data/lib/rubydb/transactions/transaction_id.rb +84 -0
- data/lib/rubydb/transactions/transaction_log.rb +257 -0
- data/lib/rubydb/transactions/transaction_manager.rb +435 -0
- data/lib/rubydb/types/bigint.rb +36 -0
- data/lib/rubydb/types/blob.rb +37 -0
- data/lib/rubydb/types/boolean.rb +34 -0
- data/lib/rubydb/types/date.rb +39 -0
- data/lib/rubydb/types/decimal.rb +48 -0
- data/lib/rubydb/types/float.rb +34 -0
- data/lib/rubydb/types/integer.rb +36 -0
- data/lib/rubydb/types/json.rb +41 -0
- data/lib/rubydb/types/null.rb +34 -0
- data/lib/rubydb/types/smallint.rb +36 -0
- data/lib/rubydb/types/text.rb +37 -0
- data/lib/rubydb/types/time.rb +46 -0
- data/lib/rubydb/types/timestamp.rb +39 -0
- data/lib/rubydb/types/type.rb +119 -0
- data/lib/rubydb/types/uuid.rb +47 -0
- data/lib/rubydb/types/varchar.rb +37 -0
- data/lib/rubydb/version.rb +33 -0
- data/lib/rubydb/wal/archive.rb +193 -0
- data/lib/rubydb/wal/checkpoint.rb +183 -0
- data/lib/rubydb/wal/lsn.rb +94 -0
- data/lib/rubydb/wal/reader.rb +260 -0
- data/lib/rubydb/wal/record.rb +105 -0
- data/lib/rubydb/wal/segment.rb +193 -0
- data/lib/rubydb/wal/wal.rb +452 -0
- data/lib/rubydb/wal/writer.rb +236 -0
- data/lib/rubydb.rb +7 -0
- data/packaging/docker/Dockerfile +36 -0
- data/packaging/docker/docker-compose.failover.yml +43 -0
- data/packaging/docker/entrypoint.sh +15 -0
- data/packaging/homebrew/rubydb.rb +19 -0
- data/packaging/systemd/rubydb.service +22 -0
- data/rubydb.gemspec +57 -0
- data/scripts/benchmark +7 -0
- data/scripts/durability_drill +37 -0
- data/scripts/format +0 -0
- data/scripts/fuzz +63 -0
- data/scripts/lint +0 -0
- data/scripts/release +50 -0
- data/scripts/release_check +43 -0
- data/scripts/replication_failover_drill +250 -0
- data/scripts/replication_network_failover_drill +255 -0
- data/scripts/restore_drill +45 -0
- data/scripts/security +0 -0
- data/scripts/setup +0 -0
- data/scripts/test +0 -0
- data/scripts/test-chaos +0 -0
- data/scripts/test-crash +0 -0
- data/scripts/test-integration +0 -0
- data/scripts/test-unit +0 -0
- data/visibility_map.json +1 -0
- metadata +538 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: b474095677d024d7aae488865411803476f0c5040d75fba89b063f0e9679a3d9
|
|
4
|
+
data.tar.gz: 18a4bbf0d5744c8e980a50ee4b6ee6a75133f299a96eabd458ca1bf40554bb78
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a719c2d1f1de9e98ac56a45ab3956ce5b216dd1987e510688af3d71cfe131f98463cbab9525ca96ef2cc34a4457d3475b65016f8595a9f4f3c9b5f621a503247
|
|
7
|
+
data.tar.gz: b0f0d139f3da9c4eb8bea8805cbefeff6c11dae8dcf47853b8a157b402e4c10103bbf8b94a84a8ef1d80c7fe07a63e2effa042bff21d6ac3591b7340ff6c1b55
|
data/.gitattributes
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Auto detect text files and perform LF normalization
|
|
2
|
+
* text=auto
|
|
3
|
+
|
|
4
|
+
# Ruby files
|
|
5
|
+
*.rb text diff=ruby
|
|
6
|
+
*.erb text diff=ruby
|
|
7
|
+
*.rake text diff=ruby
|
|
8
|
+
*.gemspec text diff=ruby
|
|
9
|
+
|
|
10
|
+
# Markdown
|
|
11
|
+
*.md text diff=markdown
|
|
12
|
+
|
|
13
|
+
# YAML
|
|
14
|
+
*.yml text diff=yaml
|
|
15
|
+
*.yaml text diff=yaml
|
|
16
|
+
|
|
17
|
+
# Binary formats
|
|
18
|
+
*.rdb binary
|
|
19
|
+
*.rdb-wal binary
|
|
20
|
+
*.rdb-shm binary
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
Describe the change and the user or operator problem it solves.
|
|
4
|
+
|
|
5
|
+
## Validation
|
|
6
|
+
|
|
7
|
+
- [ ] Tests added or updated for changed behavior
|
|
8
|
+
- [ ] `bundle exec rspec` passes, or failures are explained
|
|
9
|
+
- [ ] Documentation and compatibility claims are updated
|
|
10
|
+
- [ ] Production, security, migration, and rollback impact reviewed
|
|
11
|
+
|
|
12
|
+
## Operational impact
|
|
13
|
+
|
|
14
|
+
Describe storage-format, WAL, migration, configuration, protocol, replication,
|
|
15
|
+
security, and upgrade implications. Include rollback and observability notes.
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Workload smoke benchmark
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
workload:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: ruby/setup-ruby@v1
|
|
18
|
+
with:
|
|
19
|
+
ruby-version: "3.3"
|
|
20
|
+
bundler-cache: true
|
|
21
|
+
- name: Deterministic storage workload
|
|
22
|
+
run: RUBYDB_BENCHMARK_ITERATIONS=100 bundle exec ruby -Ilib benchmarks/basic_workload.rb
|
|
23
|
+
- name: Concurrent durability workload
|
|
24
|
+
run: RUBYDB_WORKLOAD_THREADS=4 RUBYDB_WORKLOAD_OPERATIONS=100 bundle exec ruby -Ilib benchmarks/concurrent_workload.rb
|
|
25
|
+
- name: Server protocol durability workload
|
|
26
|
+
run: RUBYDB_SERVER_WORKLOAD_CLIENTS=2 RUBYDB_SERVER_WORKLOAD_OPERATIONS=25 bundle exec ruby -Ilib benchmarks/server_workload.rb
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: Compatibility
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
ruby:
|
|
15
|
+
name: Ruby ${{ matrix.ruby }} on ${{ matrix.os }}
|
|
16
|
+
runs-on: ${{ matrix.os }}
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
21
|
+
ruby: ["3.3", "3.4"]
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- uses: ruby/setup-ruby@v1
|
|
25
|
+
with:
|
|
26
|
+
ruby-version: ${{ matrix.ruby }}
|
|
27
|
+
bundler-cache: true
|
|
28
|
+
- name: Run regression suite with coverage gate
|
|
29
|
+
env:
|
|
30
|
+
RUBYDB_COVERAGE: "1"
|
|
31
|
+
run: bundle exec rspec
|
|
32
|
+
|
|
33
|
+
- name: Validate SQLite compatibility profile
|
|
34
|
+
run: bundle exec rspec spec/sqlite_compatibility_spec.rb
|
|
35
|
+
|
|
36
|
+
rails:
|
|
37
|
+
name: ActiveRecord ${{ matrix.rails }}
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
strategy:
|
|
40
|
+
fail-fast: false
|
|
41
|
+
matrix:
|
|
42
|
+
rails: ["7.1", "7.2", "8.0"]
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v4
|
|
45
|
+
- uses: ruby/setup-ruby@v1
|
|
46
|
+
with:
|
|
47
|
+
ruby-version: "3.3"
|
|
48
|
+
bundler-cache: true
|
|
49
|
+
- name: Build current RubyDB gem
|
|
50
|
+
run: bundle exec rake build
|
|
51
|
+
- name: Install current RubyDB gem for adapter dependency
|
|
52
|
+
shell: bash
|
|
53
|
+
run: gem install "$(ls -t pkg/rubydb-*.gem | head -n 1)" --local --no-document
|
|
54
|
+
- name: Install adapter dependencies
|
|
55
|
+
working-directory: adapters/activerecord
|
|
56
|
+
env:
|
|
57
|
+
RUBYDB_RAILS_VERSION: ${{ matrix.rails }}
|
|
58
|
+
run: bundle install --jobs 4 --retry 3
|
|
59
|
+
- name: Run adapter integration suite
|
|
60
|
+
working-directory: adapters/activerecord
|
|
61
|
+
env:
|
|
62
|
+
RUBYDB_RAILS_VERSION: ${{ matrix.rails }}
|
|
63
|
+
run: bundle exec rspec
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Fuzz safety
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
schedule:
|
|
7
|
+
- cron: "17 3 * * 0"
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
inputs:
|
|
10
|
+
iterations:
|
|
11
|
+
description: "Iterations per fuzzer"
|
|
12
|
+
required: false
|
|
13
|
+
default: "1000"
|
|
14
|
+
type: string
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
fuzz:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
timeout-minutes: 15
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
- uses: ruby/setup-ruby@v1
|
|
26
|
+
with:
|
|
27
|
+
ruby-version: "3.3"
|
|
28
|
+
bundler-cache: true
|
|
29
|
+
- name: Run bounded fuzzers
|
|
30
|
+
env:
|
|
31
|
+
RUBYDB_FUZZ_ITERATIONS: ${{ inputs.iterations || '100' }}
|
|
32
|
+
RUBYDB_FUZZ_SEED: "20260909"
|
|
33
|
+
run: ruby scripts/fuzz
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Lint
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
rubocop:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: ruby/setup-ruby@v1
|
|
18
|
+
with:
|
|
19
|
+
ruby-version: "3.3"
|
|
20
|
+
bundler-cache: true
|
|
21
|
+
- run: bundle exec rubocop
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Operations drills
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "47 3 * * 1"
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
restore:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
timeout-minutes: 15
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: ruby/setup-ruby@v1
|
|
18
|
+
with:
|
|
19
|
+
ruby-version: "3.3"
|
|
20
|
+
bundler-cache: true
|
|
21
|
+
- name: Run backup and restore drill
|
|
22
|
+
run: ruby scripts/restore_drill
|
|
23
|
+
- name: Run durability fault and recovery drill
|
|
24
|
+
run: ruby scripts/durability_drill
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
name: Production validation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
schedule:
|
|
6
|
+
- cron: "19 4 * * 3"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
validate:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
timeout-minutes: 45
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: ruby/setup-ruby@v1
|
|
18
|
+
with:
|
|
19
|
+
ruby-version: "3.3"
|
|
20
|
+
bundler-cache: true
|
|
21
|
+
|
|
22
|
+
- name: Run production safety regression set
|
|
23
|
+
run: |
|
|
24
|
+
bundle exec rspec \
|
|
25
|
+
spec/server_protocol_spec.rb \
|
|
26
|
+
spec/server_concurrency_durability_spec.rb \
|
|
27
|
+
spec/concurrent_soak_harness_spec.rb \
|
|
28
|
+
spec/multiprocess_server_workload_spec.rb \
|
|
29
|
+
spec/filesystem_fault_injection_spec.rb \
|
|
30
|
+
spec/metadata_persistence_safety_spec.rb \
|
|
31
|
+
spec/index_persistence_spec.rb \
|
|
32
|
+
spec/compaction_persistence_spec.rb \
|
|
33
|
+
spec/backup_restore_spec.rb \
|
|
34
|
+
spec/replication_network_spec.rb \
|
|
35
|
+
spec/replication_partition_spec.rb \
|
|
36
|
+
spec/replication_failover_integration_spec.rb \
|
|
37
|
+
spec/fencing_spec.rb \
|
|
38
|
+
spec/corruption_repair_spec.rb
|
|
39
|
+
spec/sqlite_compatibility_spec.rb
|
|
40
|
+
|
|
41
|
+
- name: Run sustained threaded workload
|
|
42
|
+
shell: bash
|
|
43
|
+
run: |
|
|
44
|
+
set -euo pipefail
|
|
45
|
+
mkdir -p production-results
|
|
46
|
+
RUBYDB_SOAK_ROUNDS=3 \
|
|
47
|
+
RUBYDB_SOAK_THREADS=16 \
|
|
48
|
+
RUBYDB_SOAK_OPERATIONS=2000 \
|
|
49
|
+
RUBYDB_SOAK_PAYLOAD_BYTES=512 \
|
|
50
|
+
ruby benchmarks/concurrent_soak.rb | tee production-results/threaded.json
|
|
51
|
+
|
|
52
|
+
- name: Run server and independent-process workloads
|
|
53
|
+
shell: bash
|
|
54
|
+
run: |
|
|
55
|
+
set -euo pipefail
|
|
56
|
+
RUBYDB_SERVER_WORKLOAD_CLIENTS=16 \
|
|
57
|
+
RUBYDB_SERVER_WORKLOAD_OPERATIONS=1000 \
|
|
58
|
+
ruby -Ilib benchmarks/server_workload.rb | tee production-results/server.json
|
|
59
|
+
RUBYDB_SERVER_WORKLOAD_PROCESSES=8 \
|
|
60
|
+
RUBYDB_SERVER_WORKLOAD_OPERATIONS=1000 \
|
|
61
|
+
ruby benchmarks/multiprocess_server_workload.rb | tee production-results/multiprocess.json
|
|
62
|
+
|
|
63
|
+
- name: Run production concurrency and resilience soak
|
|
64
|
+
shell: bash
|
|
65
|
+
run: |
|
|
66
|
+
set -euo pipefail
|
|
67
|
+
RUBYDB_PRODUCTION_SOAK_CLIENTS=16 \
|
|
68
|
+
RUBYDB_PRODUCTION_SOAK_OPERATIONS=2000 \
|
|
69
|
+
RUBYDB_PRODUCTION_SOAK_CANCEL_ROWS=250000 \
|
|
70
|
+
ruby benchmarks/production_soak.rb | tee production-results/production-soak.json
|
|
71
|
+
|
|
72
|
+
- name: Run process-level replication failover drill
|
|
73
|
+
run: ruby scripts/replication_failover_drill | tee production-results/replication-failover.json
|
|
74
|
+
|
|
75
|
+
- name: Run network partition and promotion drill
|
|
76
|
+
run: ruby scripts/replication_network_failover_drill | tee production-results/replication-network-failover.json
|
|
77
|
+
|
|
78
|
+
- name: Run backup and restore drill
|
|
79
|
+
run: ruby scripts/restore_drill | tee production-results/restore.txt
|
|
80
|
+
|
|
81
|
+
- name: Run durability fault and recovery drill
|
|
82
|
+
run: ruby scripts/durability_drill | tee production-results/durability.txt
|
|
83
|
+
|
|
84
|
+
- name: Run bounded fuzzers
|
|
85
|
+
env:
|
|
86
|
+
RUBYDB_FUZZ_ITERATIONS: "250"
|
|
87
|
+
RUBYDB_FUZZ_SEED: "20260909"
|
|
88
|
+
run: ruby scripts/fuzz | tee production-results/fuzz.txt
|
|
89
|
+
|
|
90
|
+
- name: Build and verify release artifact
|
|
91
|
+
run: |
|
|
92
|
+
bundle exec rake build
|
|
93
|
+
ruby scripts/release | tee production-results/release.txt
|
|
94
|
+
|
|
95
|
+
- name: Upload validation evidence
|
|
96
|
+
if: always()
|
|
97
|
+
uses: actions/upload-artifact@v4
|
|
98
|
+
with:
|
|
99
|
+
name: rubydb-production-validation-${{ github.sha }}
|
|
100
|
+
path: production-results/
|
|
101
|
+
|
|
102
|
+
container-topology:
|
|
103
|
+
name: Multi-node container topology
|
|
104
|
+
runs-on: ubuntu-latest
|
|
105
|
+
timeout-minutes: 20
|
|
106
|
+
steps:
|
|
107
|
+
- uses: actions/checkout@v4
|
|
108
|
+
- name: Validate compose topology
|
|
109
|
+
run: docker compose -f packaging/docker/docker-compose.failover.yml config
|
|
110
|
+
- name: Build production image
|
|
111
|
+
run: docker compose -f packaging/docker/docker-compose.failover.yml build primary replica
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
name: Release gem
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: write
|
|
9
|
+
id-token: write
|
|
10
|
+
attestations: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build-and-publish:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 0
|
|
19
|
+
- uses: ruby/setup-ruby@v1
|
|
20
|
+
with:
|
|
21
|
+
ruby-version: "3.3"
|
|
22
|
+
bundler-cache: true
|
|
23
|
+
- name: Require protected release credentials
|
|
24
|
+
env:
|
|
25
|
+
RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
|
|
26
|
+
RUBYDB_GEM_SIGNING_KEY_B64: ${{ secrets.RUBYDB_GEM_SIGNING_KEY_B64 }}
|
|
27
|
+
RUBYDB_GEM_CERT_B64: ${{ secrets.RUBYDB_GEM_CERT_B64 }}
|
|
28
|
+
shell: bash
|
|
29
|
+
run: |
|
|
30
|
+
set -euo pipefail
|
|
31
|
+
test -n "$RUBYGEMS_API_KEY" || { echo "RUBYGEMS_API_KEY is required for a release tag" >&2; exit 1; }
|
|
32
|
+
test -n "$RUBYDB_GEM_SIGNING_KEY_B64" || { echo "RUBYDB_GEM_SIGNING_KEY_B64 is required for a release tag" >&2; exit 1; }
|
|
33
|
+
test -n "$RUBYDB_GEM_CERT_B64" || { echo "RUBYDB_GEM_CERT_B64 is required for a release tag" >&2; exit 1; }
|
|
34
|
+
|
|
35
|
+
- name: Configure RubyGems signing
|
|
36
|
+
env:
|
|
37
|
+
RUBYDB_GEM_SIGNING_KEY_B64: ${{ secrets.RUBYDB_GEM_SIGNING_KEY_B64 }}
|
|
38
|
+
RUBYDB_GEM_CERT_B64: ${{ secrets.RUBYDB_GEM_CERT_B64 }}
|
|
39
|
+
shell: bash
|
|
40
|
+
run: |
|
|
41
|
+
key_path="$RUNNER_TEMP/rubydb-gem-private-key.pem"
|
|
42
|
+
cert_path="$RUNNER_TEMP/rubydb-gem-public-cert.pem"
|
|
43
|
+
printf '%s' "$RUBYDB_GEM_SIGNING_KEY_B64" | base64 --decode > "$key_path"
|
|
44
|
+
printf '%s' "$RUBYDB_GEM_CERT_B64" | base64 --decode > "$cert_path"
|
|
45
|
+
chmod 600 "$key_path"
|
|
46
|
+
{
|
|
47
|
+
echo "RUBYDB_GEM_SIGNING_KEY=$key_path"
|
|
48
|
+
echo "RUBYDB_GEM_CERT=$cert_path"
|
|
49
|
+
} >> "$GITHUB_ENV"
|
|
50
|
+
- name: Verify tag matches gem version
|
|
51
|
+
shell: bash
|
|
52
|
+
run: test "${GITHUB_REF_NAME#v}" = "$(ruby -Ilib -rrubydb/version -e 'puts RubyDB::VERSION')"
|
|
53
|
+
- name: Verify changelog release entry
|
|
54
|
+
run: ruby scripts/release_check
|
|
55
|
+
- name: Test and build release artifact
|
|
56
|
+
run: |
|
|
57
|
+
bundle exec rspec
|
|
58
|
+
ruby scripts/release
|
|
59
|
+
- name: Sign release provenance
|
|
60
|
+
uses: actions/attest-build-provenance@v2
|
|
61
|
+
with:
|
|
62
|
+
subject-path: "pkg/*.gem"
|
|
63
|
+
- name: Publish to RubyGems
|
|
64
|
+
env:
|
|
65
|
+
GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
|
|
66
|
+
RUBYDB_PUBLISH: "1"
|
|
67
|
+
run: ruby scripts/release
|
|
68
|
+
- name: Publish GitHub release notes from changelog history
|
|
69
|
+
env:
|
|
70
|
+
GH_TOKEN: ${{ github.token }}
|
|
71
|
+
run: gh release create "$GITHUB_REF_NAME" --verify-tag --generate-notes --title "$GITHUB_REF_NAME"
|
|
72
|
+
- uses: actions/upload-artifact@v4
|
|
73
|
+
with:
|
|
74
|
+
name: rubydb-gem-${{ github.ref_name }}
|
|
75
|
+
path: |
|
|
76
|
+
pkg/*.gem
|
|
77
|
+
checksums/*.sha512
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Security
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
schedule:
|
|
9
|
+
- cron: "17 3 * * 1"
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
security-events: write
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
dependency-audit:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
- uses: ruby/setup-ruby@v1
|
|
21
|
+
with:
|
|
22
|
+
ruby-version: "3.3"
|
|
23
|
+
bundler-cache: true
|
|
24
|
+
- name: Audit Ruby dependencies
|
|
25
|
+
run: |
|
|
26
|
+
gem install bundler-audit --no-document
|
|
27
|
+
bundle audit check --update
|
|
28
|
+
|
|
29
|
+
codeql:
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
- uses: github/codeql-action/init@v3
|
|
34
|
+
with:
|
|
35
|
+
languages: ruby
|
|
36
|
+
build-mode: none
|
|
37
|
+
- uses: github/codeql-action/analyze@v3
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
rspec:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
ruby: ["3.3", "3.4"]
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- uses: ruby/setup-ruby@v1
|
|
22
|
+
with:
|
|
23
|
+
ruby-version: ${{ matrix.ruby }}
|
|
24
|
+
bundler-cache: true
|
|
25
|
+
- run: bundle exec rspec
|
|
26
|
+
- run: ruby benchmarks/concurrent_workload.rb
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name: Sustained workload validation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "31 3 * * 6"
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
workload:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
timeout-minutes: 30
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: ruby/setup-ruby@v1
|
|
18
|
+
with:
|
|
19
|
+
ruby-version: "3.3"
|
|
20
|
+
bundler-cache: true
|
|
21
|
+
- name: Run sustained threaded durability soak
|
|
22
|
+
shell: bash
|
|
23
|
+
run: |
|
|
24
|
+
set -euo pipefail
|
|
25
|
+
mkdir -p workload-results
|
|
26
|
+
RUBYDB_SOAK_ROUNDS=3 \
|
|
27
|
+
RUBYDB_SOAK_THREADS=16 \
|
|
28
|
+
RUBYDB_SOAK_OPERATIONS=2000 \
|
|
29
|
+
RUBYDB_SOAK_PAYLOAD_BYTES=512 \
|
|
30
|
+
ruby benchmarks/concurrent_soak.rb | tee workload-results/threaded.json
|
|
31
|
+
- name: Run sustained server/client latency workload
|
|
32
|
+
shell: bash
|
|
33
|
+
run: |
|
|
34
|
+
set -euo pipefail
|
|
35
|
+
RUBYDB_SERVER_WORKLOAD_CLIENTS=16 \
|
|
36
|
+
RUBYDB_SERVER_WORKLOAD_OPERATIONS=1000 \
|
|
37
|
+
ruby -Ilib benchmarks/server_workload.rb | tee workload-results/server.json
|
|
38
|
+
- name: Run sustained multi-process client workload
|
|
39
|
+
shell: bash
|
|
40
|
+
run: |
|
|
41
|
+
set -euo pipefail
|
|
42
|
+
RUBYDB_SERVER_WORKLOAD_PROCESSES=8 \
|
|
43
|
+
RUBYDB_SERVER_WORKLOAD_OPERATIONS=1000 \
|
|
44
|
+
ruby benchmarks/multiprocess_server_workload.rb | tee workload-results/multiprocess.json
|
|
45
|
+
- name: Run cancellation, capacity, and deadlock soak
|
|
46
|
+
shell: bash
|
|
47
|
+
run: |
|
|
48
|
+
set -euo pipefail
|
|
49
|
+
RUBYDB_PRODUCTION_SOAK_CLIENTS=8 \
|
|
50
|
+
RUBYDB_PRODUCTION_SOAK_OPERATIONS=500 \
|
|
51
|
+
RUBYDB_PRODUCTION_SOAK_CANCEL_ROWS=250000 \
|
|
52
|
+
ruby benchmarks/production_soak.rb | tee workload-results/production-soak.json
|
|
53
|
+
- name: Upload workload metrics
|
|
54
|
+
if: always()
|
|
55
|
+
uses: actions/upload-artifact@v4
|
|
56
|
+
with:
|
|
57
|
+
name: rubydb-workload-${{ github.sha }}
|
|
58
|
+
path: workload-results/
|
data/.gitignore
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Ruby
|
|
2
|
+
*.gem
|
|
3
|
+
*.rbc
|
|
4
|
+
/.config
|
|
5
|
+
/coverage/
|
|
6
|
+
/InstalledFiles
|
|
7
|
+
/pkg/
|
|
8
|
+
/checksums/
|
|
9
|
+
/spec/reports/
|
|
10
|
+
/spec/examples.txt
|
|
11
|
+
/test/tmp/
|
|
12
|
+
/test/version_tmp/
|
|
13
|
+
/tmp/
|
|
14
|
+
|
|
15
|
+
# RubyDB specific
|
|
16
|
+
*.rdb
|
|
17
|
+
*.rdb-wal
|
|
18
|
+
*.rdb-shm
|
|
19
|
+
*.rdb.metadata
|
|
20
|
+
*.rdb.mvcc
|
|
21
|
+
*.rdb.visibility
|
|
22
|
+
*.rdb.wal/
|
|
23
|
+
*.rdb.lock
|
|
24
|
+
/data/
|
|
25
|
+
/log/
|
|
26
|
+
*.log
|
|
27
|
+
/examples/server/tmp/
|
|
28
|
+
|
|
29
|
+
# Environment
|
|
30
|
+
/.bundle/
|
|
31
|
+
/vendor/bundle/
|
|
32
|
+
/.env
|
|
33
|
+
/.env.local
|
|
34
|
+
|
|
35
|
+
# IDE
|
|
36
|
+
/.idea/
|
|
37
|
+
/.vscode/
|
|
38
|
+
*.swp
|
|
39
|
+
*.swo
|
|
40
|
+
|
|
41
|
+
# OS
|
|
42
|
+
.DS_Store
|
|
43
|
+
Thumbs.db
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
inherit_gem:
|
|
2
|
+
standard: config/base.yml
|
|
3
|
+
|
|
4
|
+
AllCops:
|
|
5
|
+
TargetRubyVersion: 4.0
|
|
6
|
+
NewCops: enable
|
|
7
|
+
Exclude:
|
|
8
|
+
- 'bin/**/*'
|
|
9
|
+
- 'exe/**/*'
|
|
10
|
+
- 'tmp/**/*'
|
|
11
|
+
- 'vendor/**/*'
|
|
12
|
+
- 'test/fixtures/**/*'
|
|
13
|
+
- 'fuzz/**/*'
|
|
14
|
+
|
|
15
|
+
# Ruby 4.0 modern features
|
|
16
|
+
Style/HashSyntax:
|
|
17
|
+
EnforcedShorthandSyntax: either
|
|
18
|
+
|
|
19
|
+
Style/EndlessMethod:
|
|
20
|
+
Enabled: true
|
|
21
|
+
EnforcedStyle: allow_single_line
|
|
22
|
+
|
|
23
|
+
Style/PatternMatching:
|
|
24
|
+
Enabled: true
|
|
25
|
+
|
|
26
|
+
Lint/ShadowingOuterLocalVariable:
|
|
27
|
+
Enabled: false
|
|
28
|
+
|
|
29
|
+
Metrics/ClassLength:
|
|
30
|
+
Max: 200
|
|
31
|
+
|
|
32
|
+
Metrics/MethodLength:
|
|
33
|
+
Max: 25
|
|
34
|
+
|
|
35
|
+
Metrics/BlockLength:
|
|
36
|
+
Max: 50
|
|
37
|
+
Exclude:
|
|
38
|
+
- 'spec/**/*'
|
|
39
|
+
- 'test/**/*'
|
|
40
|
+
- '*.gemspec'
|
|
41
|
+
|
|
42
|
+
Naming/FileName:
|
|
43
|
+
Exclude:
|
|
44
|
+
- 'lib/rubydb.rb'
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4.0.6
|
data/.standard.yml
ADDED
data/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# RubyDB architecture
|
|
2
|
+
|
|
3
|
+
RubyDB is organized as a durable relational engine with optional server/client
|
|
4
|
+
and Rails integration layers:
|
|
5
|
+
|
|
6
|
+
1. SQL lexer/parser and AST
|
|
7
|
+
2. binder, planner, and executor
|
|
8
|
+
3. catalog, constraints, and indexes
|
|
9
|
+
4. transactions, MVCC, lock management, and WAL
|
|
10
|
+
5. page storage, checkpoints, recovery, backup, and compaction
|
|
11
|
+
6. server protocol, authentication, TLS, limits, and monitoring
|
|
12
|
+
7. logical replication, fencing, failover, and adapters
|
|
13
|
+
|
|
14
|
+
The architecture is deliberately modular so every durable boundary can be
|
|
15
|
+
tested independently and end to end. Start with the [architecture index](docs/README.md),
|
|
16
|
+
then read [current state](docs/architecture/current-state.md) and the
|
|
17
|
+
[production validation contract](docs/production_validation.md).
|
|
18
|
+
|
|
19
|
+
The embedded engine requires exclusive ownership. Server mode is the boundary
|
|
20
|
+
for multiple application processes. Automatic election is disabled until an
|
|
21
|
+
independent multi-host fencing authority is validated.
|