rubydb 0.1.4 → 0.1.6
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 +4 -4
- data/.github/PULL_REQUEST_TEMPLATE.md +15 -15
- data/.github/workflows/benchmark.yml +26 -26
- data/.github/workflows/compatibility.yml +63 -63
- data/.github/workflows/fuzz.yml +33 -33
- data/.github/workflows/lint.yml +21 -21
- data/.github/workflows/operations.yml +24 -24
- data/.github/workflows/production-validation.yml +111 -111
- data/.github/workflows/release.yml +77 -77
- data/.github/workflows/security.yml +39 -37
- data/.github/workflows/test.yml +26 -26
- data/.github/workflows/workload.yml +58 -58
- data/.gitignore +16 -5
- data/.rubocop.yml +50 -44
- data/.standard.yml +9 -14
- data/ARCHITECTURE.md +21 -21
- data/CHANGELOG.md +57 -27
- data/CODE_OF_CONDUCT.md +13 -13
- data/CONTRIBUTING.md +29 -29
- data/GOVERNANCE.md +16 -16
- data/Gemfile +18 -17
- data/Gemfile.lock +125 -71
- data/README.md +168 -12
- data/ROADMAP.md +27 -27
- data/Rakefile +76 -71
- data/SECURITY.md +54 -54
- data/SUPPORT.md +14 -14
- data/accelerator/bin/SHA256SUMS +6 -0
- data/accelerator/bin/rubydb-accelerator-darwin-amd64 +0 -0
- data/accelerator/bin/rubydb-accelerator-darwin-arm64 +0 -0
- data/accelerator/bin/rubydb-accelerator-linux-amd64 +0 -0
- data/accelerator/bin/rubydb-accelerator-linux-arm64 +0 -0
- data/accelerator/bin/rubydb-accelerator-windows-amd64.exe +0 -0
- data/accelerator/bin/rubydb-accelerator-windows-arm64.exe +0 -0
- data/accelerator/cmd/rubydb-accelerator/main.go +11 -0
- data/accelerator/go.mod +3 -0
- data/accelerator/internal/execution/aggregate.go +94 -0
- data/accelerator/internal/execution/distinct.go +22 -0
- data/accelerator/internal/execution/filter.go +73 -0
- data/accelerator/internal/execution/join.go +79 -0
- data/accelerator/internal/execution/operators.go +167 -0
- data/accelerator/internal/execution/scan.go +20 -0
- data/accelerator/internal/execution/sort.go +62 -0
- data/accelerator/internal/execution/types.go +136 -0
- data/accelerator/internal/execution/value.go +67 -0
- data/accelerator/internal/memory/arena.go +47 -0
- data/accelerator/internal/memory/reuse.go +22 -0
- data/accelerator/internal/metrics/registry.go +67 -0
- data/accelerator/internal/parallel/bounded_queue.go +56 -0
- data/accelerator/internal/parallel/scheduler.go +47 -0
- data/accelerator/internal/parallel/worker_pool.go +53 -0
- data/accelerator/internal/protocol/cancellation.go +48 -0
- data/accelerator/internal/protocol/columnar.go +263 -0
- data/accelerator/internal/protocol/frame.go +187 -0
- data/accelerator/internal/runtime/worker.go +521 -0
- data/accelerator/internal/storage/page_reader.go +81 -0
- data/accelerator/internal/storage/snapshot_scan.go +539 -0
- data/accelerator/internal/wal/checksum.go +13 -0
- data/accelerator/internal/wal/compression.go +41 -0
- data/accelerator/internal/wal/group_commit.go +24 -0
- data/accelerator/internal/wal/record_encoder.go +40 -0
- data/adapters/activerecord/Gemfile +11 -11
- data/adapters/activerecord/README.md +8 -3
- data/adapters/activerecord/lib/active_record/connection_adapters/rubydb_adapter.rb +881 -879
- data/adapters/activerecord/rubydb-activerecord.gemspec +21 -21
- data/adapters/activerecord/spec/rubydb_adapter_integration_spec.rb +143 -143
- data/adapters/ruby/README.md +18 -18
- data/adapters/sequel/README.md +11 -11
- data/config/monitoring/prometheus-alerts.yml +39 -39
- data/config/production.yml +36 -36
- data/docs/README.md +77 -71
- data/docs/architecture/concurrency.md +14 -14
- data/docs/architecture/current-state.md +125 -125
- data/docs/architecture/execution-engine.md +25 -25
- data/docs/architecture/go-accelerator.md +179 -0
- data/docs/architecture/indexes.md +19 -19
- data/docs/architecture/mvcc.md +19 -19
- data/docs/architecture/overview.md +13 -13
- data/docs/architecture/pages.md +11 -11
- data/docs/architecture/production-roadmap.md +82 -82
- data/docs/architecture/query-planner.md +20 -20
- data/docs/architecture/recovery.md +18 -18
- data/docs/architecture/sql-engine.md +12 -12
- data/docs/architecture/storage-engine.md +14 -14
- data/docs/architecture/transactions.md +10 -10
- data/docs/architecture/wal.md +28 -28
- data/docs/cli-cheatsheet.md +98 -98
- data/docs/cli.md +299 -275
- data/docs/contributing/architecture.md +9 -9
- data/docs/contributing/benchmarking.md +30 -14
- data/docs/contributing/development.md +16 -16
- data/docs/contributing/release-process.md +49 -49
- data/docs/contributing/testing.md +16 -16
- data/docs/debugging.md +229 -229
- data/docs/developer/branching.md +10 -10
- data/docs/developer/database-diff.md +10 -10
- data/docs/developer/local-development.md +49 -17
- data/docs/developer/snapshots.md +9 -9
- data/docs/developer/temporal-data.md +10 -10
- data/docs/developer-guide.md +297 -297
- data/docs/getting-started/first-database.md +16 -16
- data/docs/getting-started/first-query.md +13 -13
- data/docs/getting-started/installation.md +19 -19
- data/docs/getting-started/local-to-production.md +300 -300
- data/docs/getting-started/quickstart.md +17 -17
- data/docs/getting-started/rails.md +16 -16
- data/docs/hardening_backlog.md +93 -93
- data/docs/lessons-learned.md +112 -112
- data/docs/operations/backups.md +33 -33
- data/docs/operations/disaster-recovery.md +31 -31
- data/docs/operations/failover.md +30 -30
- data/docs/operations/monitoring.md +25 -25
- data/docs/operations/production-guide.md +295 -295
- data/docs/operations/production-runbook.md +45 -45
- data/docs/operations/replication.md +33 -33
- data/docs/operations/restore.md +6 -6
- data/docs/operations/runbook.md +34 -34
- data/docs/operations/upgrades.md +14 -14
- data/docs/operations/workload-testing.md +17 -17
- data/docs/production-readiness.md +118 -118
- data/docs/production_validation.md +150 -150
- data/docs/rails/active-record.md +11 -11
- data/docs/rails/compatibility-guide.md +90 -90
- data/docs/rails/database-yml.md +92 -92
- data/docs/rails/installation.md +17 -17
- data/docs/rails/migrations.md +17 -17
- data/docs/rails/production.md +82 -82
- data/docs/rails/troubleshooting.md +18 -18
- data/docs/release.md +25 -25
- data/docs/server/architecture.md +10 -10
- data/docs/server/authentication.md +10 -10
- data/docs/server/configuration.md +16 -16
- data/docs/server/connection-pooling.md +10 -10
- data/docs/server/deployment.md +10 -10
- data/docs/server/protocol.md +12 -12
- data/docs/sql/compatibility-guide.md +82 -82
- data/docs/sql/compatibility.md +39 -39
- data/docs/sql/data-types.md +10 -10
- data/docs/sql/functions.md +9 -9
- data/docs/sql/joins.md +9 -9
- data/docs/sql/operators.md +9 -9
- data/docs/sql/sqlite-compatibility.md +21 -21
- data/docs/sql/syntax.md +10 -10
- data/docs/sql/transactions.md +10 -10
- data/docs/troubleshooting.md +244 -244
- data/lessons/01-foundations.md +73 -0
- data/lessons/02-local-development.md +121 -0
- data/lessons/03-embedded-rubydb.md +99 -0
- data/lessons/04-rails-complex-apps.md +138 -0
- data/lessons/05-rubydb-production-server.md +237 -0
- data/lessons/06-postgresql-massive-apps.md +96 -0
- data/lessons/07-hybrid-microservices.md +179 -0
- data/lessons/08-migrations-backups-recovery.md +86 -0
- data/lessons/09-observability-security-scale.md +87 -0
- data/lessons/10-release-readiness.md +192 -0
- data/lessons/11-community-adapter.md +323 -0
- data/lessons/12-rails-ecommerce-pressure.md +263 -0
- data/lib/rubydb/accelerator/client.rb +451 -0
- data/lib/rubydb/accelerator/error.rb +22 -0
- data/lib/rubydb/accelerator/manager.rb +606 -0
- data/lib/rubydb/accelerator.rb +13 -0
- data/lib/rubydb/backup/archive.rb +332 -334
- data/lib/rubydb/backup/backup.rb +400 -401
- data/lib/rubydb/backup/incremental.rb +349 -353
- data/lib/rubydb/backup/restore.rb +289 -290
- data/lib/rubydb/backup/snapshot.rb +265 -267
- data/lib/rubydb/backup/verification.rb +276 -279
- data/lib/rubydb/branching/branch.rb +181 -181
- data/lib/rubydb/branching/branch_manager.rb +307 -311
- data/lib/rubydb/branching/branch_metadata.rb +140 -140
- data/lib/rubydb/branching/checkout.rb +165 -166
- data/lib/rubydb/branching/copy_on_write.rb +272 -272
- data/lib/rubydb/branching/diff.rb +137 -138
- data/lib/rubydb/branching/merge.rb +282 -285
- data/lib/rubydb/build_info.rb +15 -15
- data/lib/rubydb/catalog/catalog.rb +391 -391
- data/lib/rubydb/catalog/column.rb +112 -112
- data/lib/rubydb/catalog/constraint.rb +180 -180
- data/lib/rubydb/catalog/database.rb +184 -184
- data/lib/rubydb/catalog/index.rb +97 -97
- data/lib/rubydb/catalog/schema.rb +103 -103
- data/lib/rubydb/catalog/sequence.rb +90 -90
- data/lib/rubydb/catalog/system_catalog.rb +698 -698
- data/lib/rubydb/catalog/table.rb +178 -178
- data/lib/rubydb/catalog/trigger.rb +102 -102
- data/lib/rubydb/catalog/view.rb +66 -66
- data/lib/rubydb/cli/application.rb +168 -163
- data/lib/rubydb/cli/commands/accelerator.rb +72 -0
- data/lib/rubydb/cli/commands/backup.rb +80 -81
- data/lib/rubydb/cli/commands/branch.rb +72 -72
- data/lib/rubydb/cli/commands/checkout.rb +54 -54
- data/lib/rubydb/cli/commands/create.rb +58 -58
- data/lib/rubydb/cli/commands/diff.rb +76 -77
- data/lib/rubydb/cli/commands/doctor.rb +77 -74
- data/lib/rubydb/cli/commands/drop.rb +57 -57
- data/lib/rubydb/cli/commands/init.rb +101 -102
- data/lib/rubydb/cli/commands/inspect.rb +95 -95
- data/lib/rubydb/cli/commands/merge.rb +63 -63
- data/lib/rubydb/cli/commands/migrate.rb +62 -62
- data/lib/rubydb/cli/commands/restart.rb +42 -39
- data/lib/rubydb/cli/commands/restore.rb +121 -121
- data/lib/rubydb/cli/commands/shell.rb +365 -365
- data/lib/rubydb/cli/commands/snapshot.rb +79 -79
- data/lib/rubydb/cli/commands/start.rb +88 -82
- data/lib/rubydb/cli/commands/status.rb +96 -92
- data/lib/rubydb/cli/commands/stop.rb +47 -47
- data/lib/rubydb/cli/commands/vacuum.rb +58 -58
- data/lib/rubydb/cli/formatter.rb +221 -221
- data/lib/rubydb/cli/output.rb +168 -168
- data/lib/rubydb/client/client.rb +309 -304
- data/lib/rubydb/client/connection.rb +429 -415
- data/lib/rubydb/client/connection_pool.rb +168 -168
- data/lib/rubydb/client/connection_url.rb +96 -96
- data/lib/rubydb/client/prepared_statement.rb +60 -60
- data/lib/rubydb/client/result.rb +127 -123
- data/lib/rubydb/client/statement.rb +52 -52
- data/lib/rubydb/client/transaction.rb +130 -130
- data/lib/rubydb/concurrency/concurrency.rb +19 -19
- data/lib/rubydb/concurrency/deadlock_detector.rb +148 -150
- data/lib/rubydb/concurrency/latch.rb +101 -101
- data/lib/rubydb/concurrency/lock_graph.rb +163 -165
- data/lib/rubydb/concurrency/mutex.rb +181 -183
- data/lib/rubydb/concurrency/rw_lock.rb +180 -180
- data/lib/rubydb/concurrency/scheduler.rb +248 -250
- data/lib/rubydb/concurrency/worker_pool.rb +145 -143
- data/lib/rubydb/configuration/config.rb +170 -170
- data/lib/rubydb/configuration/defaults.rb +191 -179
- data/lib/rubydb/configuration/environment.rb +152 -152
- data/lib/rubydb/configuration/parser.rb +185 -185
- data/lib/rubydb/configuration/validation.rb +228 -221
- data/lib/rubydb/constants.rb +74 -74
- data/lib/rubydb/constraints/check.rb +181 -181
- data/lib/rubydb/constraints/constraint.rb +101 -101
- data/lib/rubydb/constraints/foreign_key.rb +130 -130
- data/lib/rubydb/constraints/not_null.rb +64 -64
- data/lib/rubydb/constraints/primary_key.rb +99 -99
- data/lib/rubydb/constraints/unique.rb +106 -108
- data/lib/rubydb/constraints/validator.rb +349 -350
- data/lib/rubydb/errors/authentication_error.rb +10 -10
- data/lib/rubydb/errors/authorization_error.rb +23 -23
- data/lib/rubydb/errors/client_error.rb +10 -10
- data/lib/rubydb/errors/configuration_error.rb +10 -10
- data/lib/rubydb/errors/connection_error.rb +10 -10
- data/lib/rubydb/errors/constraint_error.rb +23 -23
- data/lib/rubydb/errors/corruption_error.rb +10 -10
- data/lib/rubydb/errors/database_error.rb +10 -10
- data/lib/rubydb/errors/error.rb +20 -20
- data/lib/rubydb/errors/execution_error.rb +10 -10
- data/lib/rubydb/errors/parser_error.rb +10 -10
- data/lib/rubydb/errors/recovery_error.rb +10 -10
- data/lib/rubydb/errors/replication_error.rb +10 -10
- data/lib/rubydb/errors/server_error.rb +6 -6
- data/lib/rubydb/errors/storage_error.rb +10 -10
- data/lib/rubydb/errors/transaction_error.rb +10 -10
- data/lib/rubydb/execution/accelerator_dispatch.rb +30 -0
- data/lib/rubydb/execution/aggregate_executor.rb +134 -138
- data/lib/rubydb/execution/cost_model.rb +72 -0
- data/lib/rubydb/execution/delete_executor.rb +110 -112
- data/lib/rubydb/execution/distinct_executor.rb +131 -135
- data/lib/rubydb/execution/executor.rb +1544 -1188
- data/lib/rubydb/execution/expression.rb +191 -193
- data/lib/rubydb/execution/index_scan.rb +142 -142
- data/lib/rubydb/execution/insert_executor.rb +215 -217
- data/lib/rubydb/execution/join_executor.rb +243 -249
- data/lib/rubydb/execution/limit_executor.rb +83 -85
- data/lib/rubydb/execution/operator_selection.rb +57 -0
- data/lib/rubydb/execution/optimizer.rb +227 -215
- data/lib/rubydb/execution/physical_plan.rb +47 -0
- data/lib/rubydb/execution/plan.rb +355 -353
- data/lib/rubydb/execution/planner.rb +508 -536
- data/lib/rubydb/execution/predicate.rb +235 -235
- data/lib/rubydb/execution/scan.rb +49 -49
- data/lib/rubydb/execution/sequential_scan.rb +63 -63
- data/lib/rubydb/execution/sort_executor.rb +194 -185
- data/lib/rubydb/execution/update_executor.rb +160 -162
- data/lib/rubydb/functions/aggregate.rb +70 -70
- data/lib/rubydb/functions/date_functions.rb +274 -278
- data/lib/rubydb/functions/function.rb +85 -85
- data/lib/rubydb/functions/json_functions.rb +231 -215
- data/lib/rubydb/functions/numeric_functions.rb +346 -346
- data/lib/rubydb/functions/scalar.rb +52 -52
- data/lib/rubydb/functions/string_functions.rb +383 -383
- data/lib/rubydb/functions/system_functions.rb +258 -246
- data/lib/rubydb/history/as_of.rb +238 -238
- data/lib/rubydb/history/change.rb +105 -105
- data/lib/rubydb/history/history.rb +131 -131
- data/lib/rubydb/history/history_manager.rb +228 -229
- data/lib/rubydb/history/temporal_query.rb +202 -202
- data/lib/rubydb/history/timeline.rb +144 -144
- data/lib/rubydb/indexes/btree.rb +215 -186
- data/lib/rubydb/indexes/btree_cursor.rb +258 -258
- data/lib/rubydb/indexes/btree_node.rb +384 -385
- data/lib/rubydb/indexes/hash_index.rb +150 -150
- data/lib/rubydb/indexes/index.rb +71 -71
- data/lib/rubydb/indexes/index_manager.rb +408 -406
- data/lib/rubydb/indexes/index_scan.rb +466 -470
- data/lib/rubydb/migrations/migration.rb +253 -254
- data/lib/rubydb/migrations/migration_lock.rb +146 -146
- data/lib/rubydb/migrations/migration_manager.rb +187 -176
- data/lib/rubydb/migrations/migration_version.rb +71 -71
- data/lib/rubydb/migrations/schema_diff.rb +211 -211
- data/lib/rubydb/migrations/schema_version.rb +64 -64
- data/lib/rubydb/monitoring/events.rb +155 -160
- data/lib/rubydb/monitoring/health.rb +216 -222
- data/lib/rubydb/monitoring/logger.rb +188 -193
- data/lib/rubydb/monitoring/metrics.rb +363 -359
- data/lib/rubydb/monitoring/performance.rb +176 -176
- data/lib/rubydb/monitoring/statistics.rb +168 -170
- data/lib/rubydb/mvcc/garbage_collector.rb +199 -199
- data/lib/rubydb/mvcc/mvcc.rb +16 -16
- data/lib/rubydb/mvcc/snapshot.rb +146 -147
- data/lib/rubydb/mvcc/vacuum.rb +180 -180
- data/lib/rubydb/mvcc/version.rb +106 -106
- data/lib/rubydb/mvcc/version_store.rb +396 -398
- data/lib/rubydb/mvcc/visibility.rb +107 -109
- data/lib/rubydb/protocol/capabilities.rb +125 -125
- data/lib/rubydb/protocol/decoder.rb +142 -145
- data/lib/rubydb/protocol/encoder.rb +131 -136
- data/lib/rubydb/protocol/handshake.rb +306 -305
- data/lib/rubydb/protocol/message.rb +121 -121
- data/lib/rubydb/protocol/parameter_binder.rb +101 -0
- data/lib/rubydb/protocol/protocol.rb +276 -277
- data/lib/rubydb/protocol/version.rb +54 -54
- data/lib/rubydb/rails/adapter.rb +245 -239
- data/lib/rubydb/rails/connection.rb +312 -314
- data/lib/rubydb/rails/database_statements.rb +122 -122
- data/lib/rubydb/rails/migration.rb +131 -131
- data/lib/rubydb/rails/quoting.rb +109 -109
- data/lib/rubydb/rails/result.rb +117 -117
- data/lib/rubydb/rails/schema_statements.rb +339 -339
- data/lib/rubydb/rails/transaction.rb +105 -105
- data/lib/rubydb/rails/type.rb +126 -126
- data/lib/rubydb/recovery/checkpoint.rb +261 -257
- data/lib/rubydb/recovery/consistency.rb +457 -467
- data/lib/rubydb/recovery/corruption_detector.rb +5 -5
- data/lib/rubydb/recovery/crash_recovery.rb +381 -387
- data/lib/rubydb/recovery/recovery_manager.rb +204 -206
- data/lib/rubydb/recovery/redo.rb +235 -237
- data/lib/rubydb/recovery/undo.rb +204 -206
- data/lib/rubydb/replication/failover.rb +5 -5
- data/lib/rubydb/replication/fencing.rb +63 -63
- data/lib/rubydb/replication/primary.rb +461 -450
- data/lib/rubydb/replication/replica.rb +382 -384
- data/lib/rubydb/replication/replication_log.rb +194 -200
- data/lib/rubydb/replication/replication_manager.rb +307 -308
- data/lib/rubydb/replication/replication_slot.rb +293 -295
- data/lib/rubydb/replication/replication_stream.rb +198 -201
- data/lib/rubydb/rubydb.rb +570 -560
- data/lib/rubydb/security/access_control.rb +252 -254
- data/lib/rubydb/security/audit_log.rb +209 -213
- data/lib/rubydb/security/authentication.rb +302 -302
- data/lib/rubydb/security/authorization.rb +282 -282
- data/lib/rubydb/security/credentials.rb +192 -196
- data/lib/rubydb/security/password.rb +205 -215
- data/lib/rubydb/security/permissions.rb +74 -74
- data/lib/rubydb/security/role.rb +99 -101
- data/lib/rubydb/security/user.rb +86 -86
- data/lib/rubydb/server/connection.rb +383 -366
- data/lib/rubydb/server/connection_pool.rb +193 -193
- data/lib/rubydb/server/lifecycle.rb +227 -228
- data/lib/rubydb/server/listener.rb +139 -136
- data/lib/rubydb/server/request_handler.rb +277 -276
- data/lib/rubydb/server/server.rb +363 -364
- data/lib/rubydb/server/session.rb +416 -369
- data/lib/rubydb/server/worker.rb +206 -210
- data/lib/rubydb/server/worker_pool.rb +168 -168
- data/lib/rubydb/sql/ast/alter_table.rb +169 -169
- data/lib/rubydb/sql/ast/begin_transaction.rb +47 -47
- data/lib/rubydb/sql/ast/commit.rb +37 -37
- data/lib/rubydb/sql/ast/constraint.rb +92 -83
- data/lib/rubydb/sql/ast/create_database.rb +41 -41
- data/lib/rubydb/sql/ast/create_index.rb +61 -61
- data/lib/rubydb/sql/ast/create_schema.rb +52 -52
- data/lib/rubydb/sql/ast/create_table.rb +187 -187
- data/lib/rubydb/sql/ast/delete.rb +54 -54
- data/lib/rubydb/sql/ast/drop_database.rb +41 -41
- data/lib/rubydb/sql/ast/drop_index.rb +41 -41
- data/lib/rubydb/sql/ast/drop_schema.rb +49 -49
- data/lib/rubydb/sql/ast/drop_table.rb +49 -49
- data/lib/rubydb/sql/ast/explain.rb +64 -64
- data/lib/rubydb/sql/ast/expression.rb +617 -604
- data/lib/rubydb/sql/ast/insert.rb +66 -66
- data/lib/rubydb/sql/ast/node.rb +42 -42
- data/lib/rubydb/sql/ast/rollback.rb +63 -63
- data/lib/rubydb/sql/ast/savepoint.rb +59 -59
- data/lib/rubydb/sql/ast/select.rb +88 -88
- data/lib/rubydb/sql/ast/set_operation.rb +22 -20
- data/lib/rubydb/sql/ast/trigger.rb +35 -29
- data/lib/rubydb/sql/ast/update.rb +88 -88
- data/lib/rubydb/sql/ast/vacuum.rb +19 -19
- data/lib/rubydb/sql/ast/view.rb +38 -32
- data/lib/rubydb/sql/ast/with.rb +32 -32
- data/lib/rubydb/sql/grammar.rb +86 -86
- data/lib/rubydb/sql/keywords.rb +156 -156
- data/lib/rubydb/sql/lexer.rb +209 -214
- data/lib/rubydb/sql/operators.rb +100 -100
- data/lib/rubydb/sql/parser.rb +1167 -1170
- data/lib/rubydb/sql/planner/analyzer.rb +283 -302
- data/lib/rubydb/sql/planner/binder.rb +537 -550
- data/lib/rubydb/sql/planner/type_checker.rb +427 -431
- data/lib/rubydb/sql/token.rb +210 -210
- data/lib/rubydb/storage/buffer_frame.rb +44 -44
- data/lib/rubydb/storage/buffer_pool.rb +155 -155
- data/lib/rubydb/storage/database_lock.rb +74 -74
- data/lib/rubydb/storage/deserializer.rb +332 -342
- data/lib/rubydb/storage/engine.rb +2409 -2330
- data/lib/rubydb/storage/file_manager.rb +191 -187
- data/lib/rubydb/storage/free_space_map.rb +79 -81
- data/lib/rubydb/storage/page.rb +92 -94
- data/lib/rubydb/storage/page_allocator.rb +852 -855
- data/lib/rubydb/storage/page_header.rb +63 -67
- data/lib/rubydb/storage/page_manager.rb +127 -131
- data/lib/rubydb/storage/record.rb +58 -58
- data/lib/rubydb/storage/row.rb +78 -78
- data/lib/rubydb/storage/serializer.rb +51 -51
- data/lib/rubydb/storage/snapshot_reader.rb +167 -0
- data/lib/rubydb/storage/storage_layout.rb +151 -151
- data/lib/rubydb/storage/storage_manager.rb +114 -114
- data/lib/rubydb/storage/tuple.rb +458 -461
- data/lib/rubydb/storage/visibility_map.rb +964 -973
- data/lib/rubydb/transactions/commit_manager.rb +219 -220
- data/lib/rubydb/transactions/isolation.rb +98 -98
- data/lib/rubydb/transactions/lock.rb +76 -76
- data/lib/rubydb/transactions/lock_manager.rb +359 -362
- data/lib/rubydb/transactions/savepoint.rb +142 -143
- data/lib/rubydb/transactions/transaction.rb +214 -215
- data/lib/rubydb/transactions/transaction_id.rb +84 -84
- data/lib/rubydb/transactions/transaction_log.rb +256 -257
- data/lib/rubydb/transactions/transaction_manager.rb +434 -435
- data/lib/rubydb/types/bigint.rb +36 -36
- data/lib/rubydb/types/blob.rb +37 -37
- data/lib/rubydb/types/boolean.rb +34 -34
- data/lib/rubydb/types/date.rb +39 -39
- data/lib/rubydb/types/decimal.rb +48 -48
- data/lib/rubydb/types/float.rb +34 -34
- data/lib/rubydb/types/integer.rb +36 -36
- data/lib/rubydb/types/json.rb +41 -41
- data/lib/rubydb/types/null.rb +34 -34
- data/lib/rubydb/types/smallint.rb +36 -36
- data/lib/rubydb/types/text.rb +37 -37
- data/lib/rubydb/types/time.rb +46 -46
- data/lib/rubydb/types/timestamp.rb +39 -39
- data/lib/rubydb/types/type.rb +119 -119
- data/lib/rubydb/types/uuid.rb +47 -47
- data/lib/rubydb/types/varchar.rb +37 -37
- data/lib/rubydb/version.rb +32 -32
- data/lib/rubydb/wal/archive.rb +207 -193
- data/lib/rubydb/wal/checkpoint.rb +181 -183
- data/lib/rubydb/wal/lsn.rb +94 -94
- data/lib/rubydb/wal/reader.rb +259 -260
- data/lib/rubydb/wal/record.rb +105 -105
- data/lib/rubydb/wal/segment.rb +193 -193
- data/lib/rubydb/wal/wal.rb +481 -452
- data/lib/rubydb/wal/writer.rb +236 -236
- data/lib/rubydb.rb +7 -7
- data/packaging/docker/docker-compose.failover.yml +43 -43
- data/packaging/homebrew/rubydb.rb +19 -19
- data/rubydb.gemspec +70 -57
- data/scripts/benchmark +7 -7
- data/scripts/build_accelerator +49 -0
- data/scripts/durability_drill +37 -37
- data/scripts/fuzz +63 -63
- data/scripts/release +77 -42
- data/scripts/release_check +43 -43
- data/scripts/replication_failover_drill +268 -250
- data/scripts/replication_network_failover_drill +287 -255
- data/scripts/restore_drill +45 -45
- data/scripts/security +45 -0
- metadata +102 -1
data/docs/rails/database-yml.md
CHANGED
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
# Rails database configuration
|
|
2
|
-
|
|
3
|
-
Embedded single-owner configuration:
|
|
4
|
-
|
|
5
|
-
```yaml
|
|
6
|
-
development:
|
|
7
|
-
adapter: rubydb
|
|
8
|
-
database: tmp/development.rdb
|
|
9
|
-
embedded: true
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
For multiple web or worker processes, use a managed RubyDB server and configure
|
|
13
|
-
the host, port, credentials, timeout, pool size, TLS, and database name through
|
|
14
|
-
protected deployment configuration. Do not put passwords, replication tokens,
|
|
15
|
-
or private keys in `database.yml` committed to source control.
|
|
16
|
-
|
|
17
|
-
Match the total Rails pool size to the server connection limit and leave headroom
|
|
18
|
-
for migrations, monitoring, and replication. Test the exact configuration with
|
|
19
|
-
the Rails matrix before release.
|
|
20
|
-
|
|
21
|
-
## Production server/client configuration
|
|
22
|
-
|
|
23
|
-
For a multi-process Rails deployment, keep the server private and put only
|
|
24
|
-
non-secret connection settings in source control. This is a complete example;
|
|
25
|
-
the `RUBYDB_*` values are supplied by the deployment environment or secret
|
|
26
|
-
manager:
|
|
27
|
-
|
|
28
|
-
```yaml
|
|
29
|
-
production:
|
|
30
|
-
adapter: rubydb
|
|
31
|
-
embedded: false
|
|
32
|
-
host: <%= ENV.fetch("RUBYDB_HOST") %>
|
|
33
|
-
port: <%= ENV.fetch("RUBYDB_PORT", "7432") %>
|
|
34
|
-
database: <%= ENV.fetch("RUBYDB_DATABASE", "rubydb") %>
|
|
35
|
-
username: <%= ENV.fetch("RUBYDB_USERNAME") %>
|
|
36
|
-
password: <%= ENV.fetch("RUBYDB_PASSWORD") %>
|
|
37
|
-
timeout: <%= ENV.fetch("RUBYDB_TIMEOUT", "30") %>
|
|
38
|
-
pool: <%= ENV.fetch("RAILS_MAX_THREADS", "5") %>
|
|
39
|
-
ssl:
|
|
40
|
-
enabled: <%= ENV.fetch("RUBYDB_SSL_ENABLED", "true") == "true" %>
|
|
41
|
-
ca_file: <%= ENV.fetch("RUBYDB_SSL_CA_FILE") %>
|
|
42
|
-
verify_peer: <%= ENV.fetch("RUBYDB_SSL_VERIFY_PEER", "true") == "true" %>
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Deploy the application with values similar to:
|
|
46
|
-
|
|
47
|
-
```sh
|
|
48
|
-
RUBYDB_HOST=db.internal.example
|
|
49
|
-
RUBYDB_PORT=7432
|
|
50
|
-
RUBYDB_DATABASE=app
|
|
51
|
-
RUBYDB_USERNAME=app_rw
|
|
52
|
-
RUBYDB_PASSWORD='provided-by-secret-manager'
|
|
53
|
-
RUBYDB_SSL_ENABLED=true
|
|
54
|
-
RUBYDB_SSL_CA_FILE=/etc/rubydb/tls/ca.crt
|
|
55
|
-
RUBYDB_SSL_VERIFY_PEER=true
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
The exact variable names are application conventions; Rails reads them because
|
|
59
|
-
`database.yml` maps them into adapter settings. Do not put the password in a
|
|
60
|
-
committed YAML file, Docker image, URL, shell history, or log. The server must
|
|
61
|
-
be configured separately with its own data directory, authentication, TLS
|
|
62
|
-
certificate/key, and resource limits; see [server configuration](../server/configuration.md).
|
|
63
|
-
|
|
64
|
-
## One connection URL
|
|
65
|
-
|
|
66
|
-
The adapter also accepts a RubyDB-specific URL through `url`. This is useful
|
|
67
|
-
when a hosting provider gives the application one connection string:
|
|
68
|
-
|
|
69
|
-
```yaml
|
|
70
|
-
production:
|
|
71
|
-
adapter: rubydb
|
|
72
|
-
embedded: false
|
|
73
|
-
url: <%= ENV.fetch("RUBYDB_URL") %>
|
|
74
|
-
pool: <%= ENV.fetch("RAILS_MAX_THREADS", "5") %>
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
Example URL with TLS verification:
|
|
78
|
-
|
|
79
|
-
```text
|
|
80
|
-
rubydbs://app_user:password@db.example.com:7432/app?verify_peer=true&ca_file=%2Fetc%2Frubydb%2Fca.crt
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
Supported schemes are `rubydb://` and `rubydbs://`; `rubydbs` enables TLS.
|
|
84
|
-
The URL supports percent-encoded username/password/database values and query
|
|
85
|
-
options including `ssl`, `sslmode`, `verify_peer`, `ca_file`, `cert_file`,
|
|
86
|
-
`key_file`, `min_version`, `timeout`, `pool_size`, `compress`, and `format`.
|
|
87
|
-
Use a secret manager to inject `RUBYDB_URL`; URLs containing passwords must not
|
|
88
|
-
be committed, printed, or placed in public issue reports. This is RubyDB’s
|
|
89
|
-
URL format, not a PostgreSQL wire-protocol or generic `DATABASE_URL` promise.
|
|
90
|
-
|
|
91
|
-
Use the documented mapping above and run a real migration plus smoke query
|
|
92
|
-
through the network path before production.
|
|
1
|
+
# Rails database configuration
|
|
2
|
+
|
|
3
|
+
Embedded single-owner configuration:
|
|
4
|
+
|
|
5
|
+
```yaml
|
|
6
|
+
development:
|
|
7
|
+
adapter: rubydb
|
|
8
|
+
database: tmp/development.rdb
|
|
9
|
+
embedded: true
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
For multiple web or worker processes, use a managed RubyDB server and configure
|
|
13
|
+
the host, port, credentials, timeout, pool size, TLS, and database name through
|
|
14
|
+
protected deployment configuration. Do not put passwords, replication tokens,
|
|
15
|
+
or private keys in `database.yml` committed to source control.
|
|
16
|
+
|
|
17
|
+
Match the total Rails pool size to the server connection limit and leave headroom
|
|
18
|
+
for migrations, monitoring, and replication. Test the exact configuration with
|
|
19
|
+
the Rails matrix before release.
|
|
20
|
+
|
|
21
|
+
## Production server/client configuration
|
|
22
|
+
|
|
23
|
+
For a multi-process Rails deployment, keep the server private and put only
|
|
24
|
+
non-secret connection settings in source control. This is a complete example;
|
|
25
|
+
the `RUBYDB_*` values are supplied by the deployment environment or secret
|
|
26
|
+
manager:
|
|
27
|
+
|
|
28
|
+
```yaml
|
|
29
|
+
production:
|
|
30
|
+
adapter: rubydb
|
|
31
|
+
embedded: false
|
|
32
|
+
host: <%= ENV.fetch("RUBYDB_HOST") %>
|
|
33
|
+
port: <%= ENV.fetch("RUBYDB_PORT", "7432") %>
|
|
34
|
+
database: <%= ENV.fetch("RUBYDB_DATABASE", "rubydb") %>
|
|
35
|
+
username: <%= ENV.fetch("RUBYDB_USERNAME") %>
|
|
36
|
+
password: <%= ENV.fetch("RUBYDB_PASSWORD") %>
|
|
37
|
+
timeout: <%= ENV.fetch("RUBYDB_TIMEOUT", "30") %>
|
|
38
|
+
pool: <%= ENV.fetch("RAILS_MAX_THREADS", "5") %>
|
|
39
|
+
ssl:
|
|
40
|
+
enabled: <%= ENV.fetch("RUBYDB_SSL_ENABLED", "true") == "true" %>
|
|
41
|
+
ca_file: <%= ENV.fetch("RUBYDB_SSL_CA_FILE") %>
|
|
42
|
+
verify_peer: <%= ENV.fetch("RUBYDB_SSL_VERIFY_PEER", "true") == "true" %>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Deploy the application with values similar to:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
RUBYDB_HOST=db.internal.example
|
|
49
|
+
RUBYDB_PORT=7432
|
|
50
|
+
RUBYDB_DATABASE=app
|
|
51
|
+
RUBYDB_USERNAME=app_rw
|
|
52
|
+
RUBYDB_PASSWORD='provided-by-secret-manager'
|
|
53
|
+
RUBYDB_SSL_ENABLED=true
|
|
54
|
+
RUBYDB_SSL_CA_FILE=/etc/rubydb/tls/ca.crt
|
|
55
|
+
RUBYDB_SSL_VERIFY_PEER=true
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The exact variable names are application conventions; Rails reads them because
|
|
59
|
+
`database.yml` maps them into adapter settings. Do not put the password in a
|
|
60
|
+
committed YAML file, Docker image, URL, shell history, or log. The server must
|
|
61
|
+
be configured separately with its own data directory, authentication, TLS
|
|
62
|
+
certificate/key, and resource limits; see [server configuration](../server/configuration.md).
|
|
63
|
+
|
|
64
|
+
## One connection URL
|
|
65
|
+
|
|
66
|
+
The adapter also accepts a RubyDB-specific URL through `url`. This is useful
|
|
67
|
+
when a hosting provider gives the application one connection string:
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
production:
|
|
71
|
+
adapter: rubydb
|
|
72
|
+
embedded: false
|
|
73
|
+
url: <%= ENV.fetch("RUBYDB_URL") %>
|
|
74
|
+
pool: <%= ENV.fetch("RAILS_MAX_THREADS", "5") %>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Example URL with TLS verification:
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
rubydbs://app_user:password@db.example.com:7432/app?verify_peer=true&ca_file=%2Fetc%2Frubydb%2Fca.crt
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Supported schemes are `rubydb://` and `rubydbs://`; `rubydbs` enables TLS.
|
|
84
|
+
The URL supports percent-encoded username/password/database values and query
|
|
85
|
+
options including `ssl`, `sslmode`, `verify_peer`, `ca_file`, `cert_file`,
|
|
86
|
+
`key_file`, `min_version`, `timeout`, `pool_size`, `compress`, and `format`.
|
|
87
|
+
Use a secret manager to inject `RUBYDB_URL`; URLs containing passwords must not
|
|
88
|
+
be committed, printed, or placed in public issue reports. This is RubyDB’s
|
|
89
|
+
URL format, not a PostgreSQL wire-protocol or generic `DATABASE_URL` promise.
|
|
90
|
+
|
|
91
|
+
Use the documented mapping above and run a real migration plus smoke query
|
|
92
|
+
through the network path before production.
|
data/docs/rails/installation.md
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
# Rails adapter installation
|
|
2
|
-
|
|
3
|
-
From the repository adapter directory:
|
|
4
|
-
|
|
5
|
-
```sh
|
|
6
|
-
cd adapters/activerecord
|
|
7
|
-
bundle install
|
|
8
|
-
bundle exec rspec
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Add the adapter gem to the application bundle according to the release being
|
|
12
|
-
tested. Configure `adapter: rubydb` and a database path or server endpoint. Run
|
|
13
|
-
`db:migrate`, schema dump/load, representative joins, eager loading, nested
|
|
14
|
-
associations, and rollback tests before deployment.
|
|
15
|
-
|
|
16
|
-
The CI matrix currently exercises Rails 7.1, 7.2, and 8.0 with the supported
|
|
17
|
-
Ruby versions. Hosted results are the release evidence for a combination.
|
|
1
|
+
# Rails adapter installation
|
|
2
|
+
|
|
3
|
+
From the repository adapter directory:
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
cd adapters/activerecord
|
|
7
|
+
bundle install
|
|
8
|
+
bundle exec rspec
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Add the adapter gem to the application bundle according to the release being
|
|
12
|
+
tested. Configure `adapter: rubydb` and a database path or server endpoint. Run
|
|
13
|
+
`db:migrate`, schema dump/load, representative joins, eager loading, nested
|
|
14
|
+
associations, and rollback tests before deployment.
|
|
15
|
+
|
|
16
|
+
The CI matrix currently exercises Rails 7.1, 7.2, and 8.0 with the supported
|
|
17
|
+
Ruby versions. Hosted results are the release evidence for a combination.
|
data/docs/rails/migrations.md
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
# Rails migrations
|
|
2
|
-
|
|
3
|
-
RubyDB supports the documented ActiveRecord migration surface, including table
|
|
4
|
-
creation, integer primary keys, columns, defaults, indexes, constraints, and
|
|
5
|
-
populated-table round trips covered by the adapter suite.
|
|
6
|
-
|
|
7
|
-
Before production migration:
|
|
8
|
-
|
|
9
|
-
1. verify a full backup and WAL chain;
|
|
10
|
-
2. restore into a new staging directory with representative data;
|
|
11
|
-
3. run the migration, schema dump/load, application queries, and rollback path;
|
|
12
|
-
4. confirm the migration checksum and schema status;
|
|
13
|
-
5. retain the pre-migration directory until rollback is no longer needed.
|
|
14
|
-
|
|
15
|
-
RubyDB fails closed when an applied migration changes or disappears. Unsupported
|
|
16
|
-
table rebuilds, generated columns, polymorphic references, and dialect-specific
|
|
17
|
-
extensions require explicit validation.
|
|
1
|
+
# Rails migrations
|
|
2
|
+
|
|
3
|
+
RubyDB supports the documented ActiveRecord migration surface, including table
|
|
4
|
+
creation, integer primary keys, columns, defaults, indexes, constraints, and
|
|
5
|
+
populated-table round trips covered by the adapter suite.
|
|
6
|
+
|
|
7
|
+
Before production migration:
|
|
8
|
+
|
|
9
|
+
1. verify a full backup and WAL chain;
|
|
10
|
+
2. restore into a new staging directory with representative data;
|
|
11
|
+
3. run the migration, schema dump/load, application queries, and rollback path;
|
|
12
|
+
4. confirm the migration checksum and schema status;
|
|
13
|
+
5. retain the pre-migration directory until rollback is no longer needed.
|
|
14
|
+
|
|
15
|
+
RubyDB fails closed when an applied migration changes or disappears. Unsupported
|
|
16
|
+
table rebuilds, generated columns, polymorphic references, and dialect-specific
|
|
17
|
+
extensions require explicit validation.
|
data/docs/rails/production.md
CHANGED
|
@@ -1,82 +1,82 @@
|
|
|
1
|
-
# Rails production guidance
|
|
2
|
-
|
|
3
|
-
RubyDB can serve Rails applications that stay within the documented RubyDB SQL
|
|
4
|
-
and ActiveRecord adapter surface. Validate the exact Rails, Ruby, operating
|
|
5
|
-
system, schema, workload, and deployment topology before handling important
|
|
6
|
-
data. The compatibility workflow currently exercises Rails 7.1, 7.2, and 8.0
|
|
7
|
-
with Ruby 3.3; hosted workflow results are required before declaring a release
|
|
8
|
-
combination supported.
|
|
9
|
-
|
|
10
|
-
## Choose the topology
|
|
11
|
-
|
|
12
|
-
An embedded database path has exclusive ownership. Use it only when one Rails
|
|
13
|
-
process owns the database, such as a single-process development or controlled
|
|
14
|
-
worker deployment. Do not point multiple independent Rails processes at the
|
|
15
|
-
same embedded path.
|
|
16
|
-
|
|
17
|
-
For multiple web/worker processes, run a separately managed RubyDB server and
|
|
18
|
-
configure clients to use its network endpoint. Size the server connection
|
|
19
|
-
limit for the Rails pool total, keep application and replication traffic on
|
|
20
|
-
private networks, and enable TLS and authentication. A Rails connection pool
|
|
21
|
-
does not make an embedded file safe for concurrent process ownership.
|
|
22
|
-
|
|
23
|
-
## Migrations and releases
|
|
24
|
-
|
|
25
|
-
Before a migration:
|
|
26
|
-
|
|
27
|
-
1. Run the complete test suite and the adapter suite for the target Rails
|
|
28
|
-
version.
|
|
29
|
-
2. Create and verify a full backup, including the WAL chain when applicable.
|
|
30
|
-
3. Restore the backup into a separate staging directory and run the migration
|
|
31
|
-
against the restored copy with a representative populated dataset.
|
|
32
|
-
4. Test schema dump/load, indexes, defaults, foreign keys, eager loading,
|
|
33
|
-
nested associations, joins, and application write/read smoke queries.
|
|
34
|
-
|
|
35
|
-
Stop writes or use the deployment's migration lock. RubyDB fails closed when an
|
|
36
|
-
already-applied migration changes checksum or disappears. Keep the pre-release
|
|
37
|
-
backup and old data directory until the rollback window closes; do not delete
|
|
38
|
-
or overwrite the live directory during rollback.
|
|
39
|
-
|
|
40
|
-
## Operations
|
|
41
|
-
|
|
42
|
-
Collect request rate/error rate/latency, active connections, WAL and checkpoint
|
|
43
|
-
health, filesystem space, recovery-required acknowledgements, and replication
|
|
44
|
-
received/replayed LSNs. Alert on readiness failure, repeated errors, failed
|
|
45
|
-
flush/checkpoint, low disk space, excessive pool wait, authentication failures,
|
|
46
|
-
and replication lag beyond the application RPO.
|
|
47
|
-
|
|
48
|
-
Run `scripts/restore_drill`, the threaded and multi-process workloads, and
|
|
49
|
-
`scripts/replication_failover_drill` on target-like staging infrastructure.
|
|
50
|
-
Archive the Ruby version, RubyDB commit, Rails version, host resources, result
|
|
51
|
-
JSON, and recovery time with the release record.
|
|
52
|
-
|
|
53
|
-
## Current boundaries
|
|
54
|
-
|
|
55
|
-
The adapter is not a complete PostgreSQL, MySQL, or SQLite compatibility layer.
|
|
56
|
-
The tested common SQLite-style profile is documented in
|
|
57
|
-
[`docs/sql/sqlite-compatibility.md`](../sql/sqlite-compatibility.md). Complex
|
|
58
|
-
table rebuilds, generated columns, polymorphic references, adapter-specific
|
|
59
|
-
schema features, and dialect-specific SQL require explicit validation before
|
|
60
|
-
use. Automatic high-availability election is disabled; failover is an
|
|
61
|
-
operator-controlled, fenced procedure described in
|
|
62
|
-
[`docs/operations/failover.md`](../operations/failover.md).
|
|
63
|
-
|
|
64
|
-
## Environment-based deployment
|
|
65
|
-
|
|
66
|
-
The Rails application normally points at RubyDB through `config/database.yml`.
|
|
67
|
-
For a production server, set `embedded: false` and map protected environment
|
|
68
|
-
values to `host`, `port`, `database`, `username`, `password`, `timeout`, and
|
|
69
|
-
the `ssl` hash. See the copy-paste example in
|
|
70
|
-
[Rails database configuration](database-yml.md). The application connects to
|
|
71
|
-
the RubyDB server endpoint; it does not open the server’s data directory.
|
|
72
|
-
|
|
73
|
-
If the deployment platform provides one connection string, set
|
|
74
|
-
`RUBYDB_URL` to the documented `rubydb://` or `rubydbs://` format and use the
|
|
75
|
-
`url:` form in `database.yml`. Do not assume a PostgreSQL `DATABASE_URL` will
|
|
76
|
-
work; RubyDB uses its own protocol and URL scheme.
|
|
77
|
-
|
|
78
|
-
Deploy the RubyDB server separately with its own persistent volume and
|
|
79
|
-
`config/production.yml`. Verify TLS hostname/CA validation, authentication,
|
|
80
|
-
readiness, migration status, and a read/write smoke query from the same network
|
|
81
|
-
path as the Rails application. Use a secret manager for credentials and never
|
|
82
|
-
commit or print them.
|
|
1
|
+
# Rails production guidance
|
|
2
|
+
|
|
3
|
+
RubyDB can serve Rails applications that stay within the documented RubyDB SQL
|
|
4
|
+
and ActiveRecord adapter surface. Validate the exact Rails, Ruby, operating
|
|
5
|
+
system, schema, workload, and deployment topology before handling important
|
|
6
|
+
data. The compatibility workflow currently exercises Rails 7.1, 7.2, and 8.0
|
|
7
|
+
with Ruby 3.3; hosted workflow results are required before declaring a release
|
|
8
|
+
combination supported.
|
|
9
|
+
|
|
10
|
+
## Choose the topology
|
|
11
|
+
|
|
12
|
+
An embedded database path has exclusive ownership. Use it only when one Rails
|
|
13
|
+
process owns the database, such as a single-process development or controlled
|
|
14
|
+
worker deployment. Do not point multiple independent Rails processes at the
|
|
15
|
+
same embedded path.
|
|
16
|
+
|
|
17
|
+
For multiple web/worker processes, run a separately managed RubyDB server and
|
|
18
|
+
configure clients to use its network endpoint. Size the server connection
|
|
19
|
+
limit for the Rails pool total, keep application and replication traffic on
|
|
20
|
+
private networks, and enable TLS and authentication. A Rails connection pool
|
|
21
|
+
does not make an embedded file safe for concurrent process ownership.
|
|
22
|
+
|
|
23
|
+
## Migrations and releases
|
|
24
|
+
|
|
25
|
+
Before a migration:
|
|
26
|
+
|
|
27
|
+
1. Run the complete test suite and the adapter suite for the target Rails
|
|
28
|
+
version.
|
|
29
|
+
2. Create and verify a full backup, including the WAL chain when applicable.
|
|
30
|
+
3. Restore the backup into a separate staging directory and run the migration
|
|
31
|
+
against the restored copy with a representative populated dataset.
|
|
32
|
+
4. Test schema dump/load, indexes, defaults, foreign keys, eager loading,
|
|
33
|
+
nested associations, joins, and application write/read smoke queries.
|
|
34
|
+
|
|
35
|
+
Stop writes or use the deployment's migration lock. RubyDB fails closed when an
|
|
36
|
+
already-applied migration changes checksum or disappears. Keep the pre-release
|
|
37
|
+
backup and old data directory until the rollback window closes; do not delete
|
|
38
|
+
or overwrite the live directory during rollback.
|
|
39
|
+
|
|
40
|
+
## Operations
|
|
41
|
+
|
|
42
|
+
Collect request rate/error rate/latency, active connections, WAL and checkpoint
|
|
43
|
+
health, filesystem space, recovery-required acknowledgements, and replication
|
|
44
|
+
received/replayed LSNs. Alert on readiness failure, repeated errors, failed
|
|
45
|
+
flush/checkpoint, low disk space, excessive pool wait, authentication failures,
|
|
46
|
+
and replication lag beyond the application RPO.
|
|
47
|
+
|
|
48
|
+
Run `scripts/restore_drill`, the threaded and multi-process workloads, and
|
|
49
|
+
`scripts/replication_failover_drill` on target-like staging infrastructure.
|
|
50
|
+
Archive the Ruby version, RubyDB commit, Rails version, host resources, result
|
|
51
|
+
JSON, and recovery time with the release record.
|
|
52
|
+
|
|
53
|
+
## Current boundaries
|
|
54
|
+
|
|
55
|
+
The adapter is not a complete PostgreSQL, MySQL, or SQLite compatibility layer.
|
|
56
|
+
The tested common SQLite-style profile is documented in
|
|
57
|
+
[`docs/sql/sqlite-compatibility.md`](../sql/sqlite-compatibility.md). Complex
|
|
58
|
+
table rebuilds, generated columns, polymorphic references, adapter-specific
|
|
59
|
+
schema features, and dialect-specific SQL require explicit validation before
|
|
60
|
+
use. Automatic high-availability election is disabled; failover is an
|
|
61
|
+
operator-controlled, fenced procedure described in
|
|
62
|
+
[`docs/operations/failover.md`](../operations/failover.md).
|
|
63
|
+
|
|
64
|
+
## Environment-based deployment
|
|
65
|
+
|
|
66
|
+
The Rails application normally points at RubyDB through `config/database.yml`.
|
|
67
|
+
For a production server, set `embedded: false` and map protected environment
|
|
68
|
+
values to `host`, `port`, `database`, `username`, `password`, `timeout`, and
|
|
69
|
+
the `ssl` hash. See the copy-paste example in
|
|
70
|
+
[Rails database configuration](database-yml.md). The application connects to
|
|
71
|
+
the RubyDB server endpoint; it does not open the server’s data directory.
|
|
72
|
+
|
|
73
|
+
If the deployment platform provides one connection string, set
|
|
74
|
+
`RUBYDB_URL` to the documented `rubydb://` or `rubydbs://` format and use the
|
|
75
|
+
`url:` form in `database.yml`. Do not assume a PostgreSQL `DATABASE_URL` will
|
|
76
|
+
work; RubyDB uses its own protocol and URL scheme.
|
|
77
|
+
|
|
78
|
+
Deploy the RubyDB server separately with its own persistent volume and
|
|
79
|
+
`config/production.yml`. Verify TLS hostname/CA validation, authentication,
|
|
80
|
+
readiness, migration status, and a read/write smoke query from the same network
|
|
81
|
+
path as the Rails application. Use a secret manager for credentials and never
|
|
82
|
+
commit or print them.
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
# Rails troubleshooting
|
|
2
|
-
|
|
3
|
-
## Connection or ownership errors
|
|
4
|
-
|
|
5
|
-
Confirm the database path exists, the process has permission, and no second
|
|
6
|
-
embedded owner is using it. Multiple Rails processes must use server mode.
|
|
7
|
-
|
|
8
|
-
## Migration failures
|
|
9
|
-
|
|
10
|
-
Stop writes, preserve the database and WAL, inspect migration status and
|
|
11
|
-
checksums, and retry only after restoring a verified staging copy. Do not delete
|
|
12
|
-
WAL or overwrite the original directory.
|
|
13
|
-
|
|
14
|
-
## Query failures
|
|
15
|
-
|
|
16
|
-
Capture the RubyDB version, Rails/Ruby versions, generated SQL without secrets,
|
|
17
|
-
and a minimal schema/query reproduction. Check the documented SQL and adapter
|
|
18
|
-
compatibility surface before changing application behavior.
|
|
1
|
+
# Rails troubleshooting
|
|
2
|
+
|
|
3
|
+
## Connection or ownership errors
|
|
4
|
+
|
|
5
|
+
Confirm the database path exists, the process has permission, and no second
|
|
6
|
+
embedded owner is using it. Multiple Rails processes must use server mode.
|
|
7
|
+
|
|
8
|
+
## Migration failures
|
|
9
|
+
|
|
10
|
+
Stop writes, preserve the database and WAL, inspect migration status and
|
|
11
|
+
checksums, and retry only after restoring a verified staging copy. Do not delete
|
|
12
|
+
WAL or overwrite the original directory.
|
|
13
|
+
|
|
14
|
+
## Query failures
|
|
15
|
+
|
|
16
|
+
Capture the RubyDB version, Rails/Ruby versions, generated SQL without secrets,
|
|
17
|
+
and a minimal schema/query reproduction. Check the documented SQL and adapter
|
|
18
|
+
compatibility surface before changing application behavior.
|
data/docs/release.md
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
# RubyDB release checklist
|
|
2
|
-
|
|
3
|
-
The release workflow is intentionally fail-closed. A maintainer must configure
|
|
4
|
-
these protected GitHub Actions secrets:
|
|
5
|
-
|
|
6
|
-
- `RUBYGEMS_API_KEY`: a RubyGems API key scoped to the gem
|
|
7
|
-
- `RUBYDB_GEM_SIGNING_KEY_B64`: base64-encoded private signing key
|
|
8
|
-
- `RUBYDB_GEM_CERT_B64`: base64-encoded certificate chain
|
|
9
|
-
|
|
10
|
-
Create the signing key and certificate outside the repository, store them in a
|
|
11
|
-
secret manager, and rotate them according to the organization's key policy.
|
|
12
|
-
Never commit the private key or write it to a persistent workspace.
|
|
13
|
-
|
|
14
|
-
To publish, review `CHANGELOG.md`, commit the version, create a matching tag,
|
|
15
|
-
and let `.github/workflows/release.yml` run the full suite, build the gem,
|
|
16
|
-
verify its SHA-512 checksum, attest provenance, sign it, and publish it. A
|
|
17
|
-
local artifact check is:
|
|
18
|
-
|
|
19
|
-
```sh
|
|
20
|
-
ruby scripts/release_check
|
|
21
|
-
ruby scripts/release
|
|
22
|
-
```
|
|
23
|
-
|
|
1
|
+
# RubyDB release checklist
|
|
2
|
+
|
|
3
|
+
The release workflow is intentionally fail-closed. A maintainer must configure
|
|
4
|
+
these protected GitHub Actions secrets:
|
|
5
|
+
|
|
6
|
+
- `RUBYGEMS_API_KEY`: a RubyGems API key scoped to the gem
|
|
7
|
+
- `RUBYDB_GEM_SIGNING_KEY_B64`: base64-encoded private signing key
|
|
8
|
+
- `RUBYDB_GEM_CERT_B64`: base64-encoded certificate chain
|
|
9
|
+
|
|
10
|
+
Create the signing key and certificate outside the repository, store them in a
|
|
11
|
+
secret manager, and rotate them according to the organization's key policy.
|
|
12
|
+
Never commit the private key or write it to a persistent workspace.
|
|
13
|
+
|
|
14
|
+
To publish, review `CHANGELOG.md`, commit the version, create a matching tag,
|
|
15
|
+
and let `.github/workflows/release.yml` run the full suite, build the gem,
|
|
16
|
+
verify its SHA-512 checksum, attest provenance, sign it, and publish it. A
|
|
17
|
+
local artifact check is:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
ruby scripts/release_check
|
|
21
|
+
ruby scripts/release
|
|
22
|
+
```
|
|
23
|
+
|
|
24
24
|
The local command does not publish unless `RUBYDB_PUBLISH=1` and
|
|
25
25
|
`GEM_HOST_API_KEY` are explicitly set. Publishing also requires the release
|
|
26
26
|
version to be supplied when you are not running from a matching Git tag.
|
|
@@ -28,7 +28,7 @@ version to be supplied when you are not running from a matching Git tag.
|
|
|
28
28
|
On Windows PowerShell, run this from the repository root:
|
|
29
29
|
|
|
30
30
|
```powershell
|
|
31
|
-
$env:RUBYDB_RELEASE_VERSION = "0.1.
|
|
31
|
+
$env:RUBYDB_RELEASE_VERSION = "0.1.6"
|
|
32
32
|
$env:RUBYDB_PUBLISH = "1"
|
|
33
33
|
$env:GEM_HOST_API_KEY = "YOUR_RUBYGEMS_API_KEY"
|
|
34
34
|
ruby scripts/release
|
|
@@ -49,7 +49,7 @@ file automatically. Keep the file private and never commit it.
|
|
|
49
49
|
On macOS/Linux, use:
|
|
50
50
|
|
|
51
51
|
```sh
|
|
52
|
-
RUBYDB_RELEASE_VERSION=0.1.
|
|
52
|
+
RUBYDB_RELEASE_VERSION=0.1.6 \
|
|
53
53
|
RUBYDB_PUBLISH=1 \
|
|
54
54
|
GEM_HOST_API_KEY="YOUR_RUBYGEMS_API_KEY" \
|
|
55
55
|
ruby scripts/release
|
data/docs/server/architecture.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Server architecture
|
|
2
|
-
|
|
3
|
-
The server owns one embedded engine and exposes client sessions over the RubyDB
|
|
4
|
-
protocol. A listener accepts bounded connections, a connection pool tracks
|
|
5
|
-
active sessions, and a worker pool handles requests under configured limits.
|
|
6
|
-
|
|
7
|
-
Lifecycle shutdown stops acceptance, closes connections, joins workers, flushes
|
|
8
|
-
the engine, and removes the PID file. Multiple application processes should
|
|
9
|
-
share the server, not the embedded path. Use health/readiness and Prometheus
|
|
10
|
-
metrics to decide whether to route traffic.
|
|
1
|
+
# Server architecture
|
|
2
|
+
|
|
3
|
+
The server owns one embedded engine and exposes client sessions over the RubyDB
|
|
4
|
+
protocol. A listener accepts bounded connections, a connection pool tracks
|
|
5
|
+
active sessions, and a worker pool handles requests under configured limits.
|
|
6
|
+
|
|
7
|
+
Lifecycle shutdown stops acceptance, closes connections, joins workers, flushes
|
|
8
|
+
the engine, and removes the PID file. Multiple application processes should
|
|
9
|
+
share the server, not the embedded path. Use health/readiness and Prometheus
|
|
10
|
+
metrics to decide whether to route traffic.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Server authentication
|
|
2
|
-
|
|
3
|
-
Configure authentication explicitly for production. Password/SCRAM-SHA-256,
|
|
4
|
-
authorization, peer replication tokens, bounded frames, TLS, and server
|
|
5
|
-
signature verification are covered by the security suite.
|
|
6
|
-
|
|
7
|
-
Use high-entropy credentials from a secret manager. Bind to a private address,
|
|
8
|
-
enable TLS 1.2 or newer, validate the CA and hostname, and rotate credentials
|
|
9
|
-
through a drain/reconnect procedure. Missing or incomplete authentication
|
|
10
|
-
configuration must fail startup rather than silently downgrade security.
|
|
1
|
+
# Server authentication
|
|
2
|
+
|
|
3
|
+
Configure authentication explicitly for production. Password/SCRAM-SHA-256,
|
|
4
|
+
authorization, peer replication tokens, bounded frames, TLS, and server
|
|
5
|
+
signature verification are covered by the security suite.
|
|
6
|
+
|
|
7
|
+
Use high-entropy credentials from a secret manager. Bind to a private address,
|
|
8
|
+
enable TLS 1.2 or newer, validate the CA and hostname, and rotate credentials
|
|
9
|
+
through a drain/reconnect procedure. Missing or incomplete authentication
|
|
10
|
+
configuration must fail startup rather than silently downgrade security.
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
# Server configuration
|
|
2
|
-
|
|
3
|
-
Run with an explicit database and resource limits:
|
|
4
|
-
|
|
5
|
-
```sh
|
|
6
|
-
rubydb-server --host 127.0.0.1 --port 7432 --database /var/lib/rubydb/app.rdb
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
Production configuration should set host/port, data and log directories, PID
|
|
10
|
-
file, max connections, worker and queue limits, request/frame size, read/write
|
|
11
|
-
and idle timeouts, authentication, and TLS. Keep configuration outside source
|
|
12
|
-
control when it contains secrets.
|
|
13
|
-
|
|
14
|
-
Validate configuration before startup and monitor readiness, active/rejected
|
|
15
|
-
connections, request errors, disk space, WAL/checkpoint state, and recovery-
|
|
16
|
-
required acknowledgements.
|
|
1
|
+
# Server configuration
|
|
2
|
+
|
|
3
|
+
Run with an explicit database and resource limits:
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
rubydb-server --host 127.0.0.1 --port 7432 --database /var/lib/rubydb/app.rdb
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Production configuration should set host/port, data and log directories, PID
|
|
10
|
+
file, max connections, worker and queue limits, request/frame size, read/write
|
|
11
|
+
and idle timeouts, authentication, and TLS. Keep configuration outside source
|
|
12
|
+
control when it contains secrets.
|
|
13
|
+
|
|
14
|
+
Validate configuration before startup and monitor readiness, active/rejected
|
|
15
|
+
connections, request errors, disk space, WAL/checkpoint state, and recovery-
|
|
16
|
+
required acknowledgements.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Connection pooling
|
|
2
|
-
|
|
3
|
-
The server limits active connections and queues work through its connection and
|
|
4
|
-
worker pools. Rails/client pool totals must fit below the server limit with
|
|
5
|
-
headroom for administrative and replication traffic.
|
|
6
|
-
|
|
7
|
-
Set finite acquisition, read, write, idle, and query timeouts. Alert on pool
|
|
8
|
-
wait, rejected connections, request failures, and saturation. Load-test pool
|
|
9
|
-
behavior with the multi-process and production soak harness; a successful local
|
|
10
|
-
connection does not prove capacity under application traffic.
|
|
1
|
+
# Connection pooling
|
|
2
|
+
|
|
3
|
+
The server limits active connections and queues work through its connection and
|
|
4
|
+
worker pools. Rails/client pool totals must fit below the server limit with
|
|
5
|
+
headroom for administrative and replication traffic.
|
|
6
|
+
|
|
7
|
+
Set finite acquisition, read, write, idle, and query timeouts. Alert on pool
|
|
8
|
+
wait, rejected connections, request failures, and saturation. Load-test pool
|
|
9
|
+
behavior with the multi-process and production soak harness; a successful local
|
|
10
|
+
connection does not prove capacity under application traffic.
|
data/docs/server/deployment.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Server deployment
|
|
2
|
-
|
|
3
|
-
Run RubyDB under a dedicated least-privilege service account with protected
|
|
4
|
-
data, WAL, logs, TLS, and backup paths. Use the packaged systemd unit or the
|
|
5
|
-
non-root Docker image, private networking, TLS, authentication, resource
|
|
6
|
-
limits, health checks, and persistent storage.
|
|
7
|
-
|
|
8
|
-
Before accepting traffic, run status/readiness, smoke queries, backup/restore,
|
|
9
|
-
workload, and recovery checks. Keep one writable primary, fence before
|
|
10
|
-
promotion, and retain the previous data directory during upgrades.
|
|
1
|
+
# Server deployment
|
|
2
|
+
|
|
3
|
+
Run RubyDB under a dedicated least-privilege service account with protected
|
|
4
|
+
data, WAL, logs, TLS, and backup paths. Use the packaged systemd unit or the
|
|
5
|
+
non-root Docker image, private networking, TLS, authentication, resource
|
|
6
|
+
limits, health checks, and persistent storage.
|
|
7
|
+
|
|
8
|
+
Before accepting traffic, run status/readiness, smoke queries, backup/restore,
|
|
9
|
+
workload, and recovery checks. Keep one writable primary, fence before
|
|
10
|
+
promotion, and retain the previous data directory during upgrades.
|