{"id":41836296,"url":"https://github.com/tidesdb/tidesql","last_synced_at":"2026-06-06T08:01:59.844Z","repository":{"id":334510657,"uuid":"1141333090","full_name":"tidesdb/tidesql","owner":"tidesdb","description":"A space and write optimized pluggable MariaDB engine built on TidesDB","archived":false,"fork":false,"pushed_at":"2026-06-02T06:36:47.000Z","size":58965,"stargazers_count":18,"open_issues_count":6,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-06-02T07:25:05.346Z","etag":null,"topics":["btree","cloud-native","lsmtree","mariadb","mvcc","object-storage","olap","oltp","optimistic","pessimistic-concurrency","sql","storage-engine","transactional"],"latest_commit_sha":null,"homepage":"https://tidesdb.com/reference/tidesql/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tidesdb.png","metadata":{"files":{"readme":"README","changelog":null,"contributing":"CONTRIBUTING","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":"CLA"}},"created_at":"2026-01-24T17:13:20.000Z","updated_at":"2026-05-24T02:30:22.000Z","dependencies_parsed_at":"2026-02-14T08:03:28.156Z","dependency_job_id":null,"html_url":"https://github.com/tidesdb/tidesql","commit_stats":null,"previous_names":["tidesdb/tidesql"],"tags_count":38,"template":false,"template_full_name":null,"purl":"pkg:github/tidesdb/tidesql","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidesdb%2Ftidesql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidesdb%2Ftidesql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidesdb%2Ftidesql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidesdb%2Ftidesql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tidesdb","download_url":"https://codeload.github.com/tidesdb/tidesql/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidesdb%2Ftidesql/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33973868,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-06T02:00:07.033Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["btree","cloud-native","lsmtree","mariadb","mvcc","object-storage","olap","oltp","optimistic","pessimistic-concurrency","sql","storage-engine","transactional"],"created_at":"2026-01-25T09:09:06.833Z","updated_at":"2026-06-06T08:01:59.837Z","avatar_url":"https://github.com/tidesdb.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"TIDESQL\n░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n\nA pluggable write and space optimized storage engine for MariaDB using TidesDB.\n\nTo find compatibility table with MariaDB go to https://tidesdb.com/reference/tidesql/#mariadb-compatibility\n\n\nINSTALLATION\n░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n\nYou can choose to run install.sh, for instructions run ./install.sh --help\n\nTo install in a specific location(e.g /data being NVMe disk)\n./install.sh --mariadb-prefix /data/mariadb --tidesdb-prefix /data/tidesdb --build-dir /data/tidesql-build\n\n\nThe install script will build TidesDB and MariaDB from source.\nYou can specify the versions if you want.  The script will install everything\nand make TidesDB available as an engine to utilize.\n\nTo skip storage engines you don't need (saves build time and reduces warnings):\n\n./install.sh --list-engines                       # see what can be skipped\n./install.sh --skip-engines mroonga,rocksdb,connect,spider,oqgraph,columnstore\n\nTo use specific MariaDB version you use:\n--mariadb-version mariadb-12.3.1 \n\nmariadb-12.3.1 aligning to https://github.com/MariaDB/server/releases/tag/mariadb-12.3.1\n\nWhen using install script you are installing the latest version of TideSQL at the time of clone or download.\n\nTo link libtidesdb against a non-default allocator (jemalloc is a common\npick for write-heavy workloads):\n\n./install.sh --allocator jemalloc\n./install.sh --allocator mimalloc\n./install.sh --allocator tcmalloc\n\nThe flag only affects libtidesdb.so's internal allocations; mariadbd's\nallocator is unchanged.  For a process-wide swap also LD_PRELOAD the\nallocator at mariadbd startup:\n\n  LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2 \\\n    /usr/local/mariadb/bin/mariadbd-safe \\\n    --defaults-file=/usr/local/mariadb/my.cnf \u0026\n\nNote that --rebuild-plugin does not rebuild libtidesdb, so changing the\nallocator requires a full install run (omit --rebuild-plugin) to take\neffect.  Verify the linkage with:\n\n  ldd /usr/local/lib/libtidesdb.so | grep -E 'jemalloc|mimalloc|tcmalloc'\n\nSkippable engines:\n  archive        Archive storage engine (read-only row-format tables)\n  blackhole      Blackhole engine (accepts writes, stores nothing)\n  columnstore    MariaDB ColumnStore (columnar analytics engine)\n  connect        CONNECT engine (access external data sources)\n  example        Example storage engine (test/demo only)\n  federated      Legacy Federated engine (MODULE_ONLY)\n  federatedx     FederatedX engine (query remote MySQL/MariaDB tables)\n  mroonga        Mroonga full-text search engine (requires Groonga)\n  oqgraph        Open Query GRAPH engine (graph computation)\n  rocksdb        MyRocks / RocksDB LSM-tree engine\n  sequence       Sequence engine (virtual auto-increment sequences)\n  sphinx         SphinxSE engine (Sphinx full-text search integration)\n  spider         Spider engine (sharding / federation)\n\nInnoDB, Aria, MyISAM, and CSV cannot be skipped (server depends on them).\n\nBelow are manual install instructions for those who want to configure everything\nthemselves, though with the install script you can modify configuration files\nafter the fact.\n\nLINUX (Ubuntu/Debian)\n░░░░░░░░░░░░░░░░░░░░░░░░\n\n1. Install dependencies:\n\n   sudo apt update\n   sudo apt install -y build-essential cmake ninja-build bison flex \\\n     libzstd-dev liblz4-dev libsnappy-dev libncurses-dev libssl-dev \\\n     libxml2-dev libevent-dev libcurl4-openssl-dev pkg-config\n\n2. Install TidesDB library:\n\n   git clone --depth 1 https://github.com/tidesdb/tidesdb.git tidesdb-lib\n   cd tidesdb-lib \u0026\u0026 mkdir build \u0026\u0026 cd build\n   cmake ..\n   make -j$(nproc)\n   sudo make install\n   sudo ldconfig\n\n3. Clone MariaDB and copy TidesDB storage engine:\n\n   git clone --depth 1 --branch mariadb-11.8.6 https://github.com/MariaDB/server.git mariadb-server\n   cd mariadb-server\n   git submodule update --init --recursive\n   cp -r /path/to/tidesql/tidesdb storage/\n   cp -r /path/to/tidesql/mysql-test/suite/tidesdb mysql-test/suite/\n\n4. Build MariaDB:\n\n   mkdir build \u0026\u0026 cd build\n   cmake ..\n   make -j$(nproc)\n\n5. Run tests (from the build directory):\n\n   cd mysql-test\n   perl mtr --suite=tidesdb --parallel=4 --force\n\n\nMACOS\n░░░░░░░░░░░░░░░░░░░░░░░░\n\n1. Install dependencies:\n\n   brew install cmake ninja bison snappy lz4 zstd openssl@3\n\n2. Install TidesDB library:\n\n   # Ensure Xcode SDK is used (not CommandLineTools)\n   sudo xcode-select -s /Applications/Xcode.app/Contents/Developer\n   export SDKROOT=$(xcrun --show-sdk-path)\n\n   git clone --depth 1 https://github.com/tidesdb/tidesdb.git tidesdb-lib\n   cd tidesdb-lib \u0026\u0026 mkdir build \u0026\u0026 cd build\n   cmake .. -DCMAKE_OSX_SYSROOT=${SDKROOT} -DOPENSSL_ROOT_DIR=$(brew --prefix openssl@3)\n   make -j$(sysctl -n hw.ncpu)\n   sudo make install\n\n3. Clone MariaDB and copy TidesDB storage engine:\n\n   git clone --depth 1 --branch mariadb-11.8.6 https://github.com/MariaDB/server.git mariadb-server\n   cd mariadb-server\n   git submodule update --init --recursive\n   cp -r /path/to/tidesql/tidesdb storage/\n   cp -r /path/to/tidesql/mysql-test/suite/tidesdb mysql-test/suite/\n\n4. Build MariaDB:\n\n   # Remove CommandLineTools SDK to prevent header conflicts\n   sudo rm -rf /Library/Developer/CommandLineTools/SDKs/MacOSX*.sdk\n\n   export SDKROOT=$(xcrun --show-sdk-path)\n   export CC=$(xcrun -find clang)\n   export CXX=$(xcrun -find clang++)\n\n   mkdir build \u0026\u0026 cd build\n   cmake .. \\\n     -DCMAKE_C_COMPILER=${CC} \\\n     -DCMAKE_CXX_COMPILER=${CXX} \\\n     -DCMAKE_OSX_SYSROOT=${SDKROOT} \\\n     -DCMAKE_C_FLAGS=\"-Wno-nullability-completeness\" \\\n     -DCMAKE_CXX_FLAGS=\"-Wno-nullability-completeness\" \\\n     -DWITH_SSL=bundled \\\n     -DWITH_PCRE=bundled \\\n     -G Ninja\n   cmake --build . --parallel $(sysctl -n hw.ncpu)\n\n   Note -- The CommandLineTools SDK removal is needed because CMake may find\n   headers in /Library/Developer/CommandLineTools/SDKs/MacOSX*.sdk which\n   causes C/C++ header path conflicts with libc++.\n\n5. Run tests (from the build directory):\n\n   cd mysql-test\n   perl mtr --suite=tidesdb --parallel=4 --force\n\n\nWINDOWS\n░░░░░░░░░░░░░░░░░░░░░░░░\n\n1. Install prerequisites:\n\n   - Visual Studio 2022 with C++ workload\n   - CMake (choco install cmake)\n   - Strawberry Perl (choco install strawberryperl)\n   - WinFlexBison (download from GitHub releases)\n\n2. Install vcpkg dependencies:\n\n   cd C:\\vcpkg\n   git pull\n   .\\vcpkg.exe install zstd:x64-windows lz4:x64-windows snappy:x64-windows pthreads:x64-windows\n\n3. Install TidesDB library:\n\n   git clone --depth 1 https://github.com/tidesdb/tidesdb.git tidesdb-lib\n   cd tidesdb-lib\n   mkdir build \u0026\u0026 cd build\n   cmake .. -G \"Visual Studio 17 2022\" -A x64 ^\n     -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake ^\n     -DCMAKE_INSTALL_PREFIX=C:/tidesdb\n   cmake --build . --config Release\n   cmake --install . --config Release\n\n4. Clone MariaDB and copy TidesDB storage engine:\n\n   git clone --depth 1 --branch mariadb-11.8.6 https://github.com/MariaDB/server.git mariadb-server\n   cd mariadb-server\n   git submodule update --init --recursive\n   xcopy /E /I path\\to\\tidesql\\tidesdb storage\\tidesdb\n   xcopy /E /I path\\to\\tidesql\\mysql-test\\suite\\tidesdb mysql-test\\suite\\tidesdb\n\n5. Build MariaDB:\n\n   mkdir build \u0026\u0026 cd build\n   cmake .. -G \"Visual Studio 17 2022\" -A x64 ^\n     -DCMAKE_PREFIX_PATH=\"C:/tidesdb;C:/vcpkg/installed/x64-windows\" ^\n     -DCONNECT_DYNAMIC=NO\n   cmake --build . --config RelWithDebInfo --parallel\n\n   Note -- CONNECT plugin is disabled (-DCONNECT_DYNAMIC=NO) because it\n   requires libxml2 headers that may conflict with vcpkg installations.\n\n6. Run tests:\n\n   cd mysql-test\n   perl mtr --suite=tidesdb --parallel=4 --force\n\n\nENABLE PLUGIN\n░░░░░░░░░░░░░░░░░░░░░░░░\n\nAfter building, enable the plugin in MariaDB:\n\n   INSTALL SONAME 'ha_tidesdb';  -- works on all platforms\n\n\n\nFEATURES\n░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n\nCore:\n- MVCC transactions with per-table isolation (autocommit uses READ_COMMITTED;\n  multi-statement transactions use the table's configured level)\n- SQL savepoints (SAVEPOINT / ROLLBACK TO / RELEASE SAVEPOINT)\n- START TRANSACTION WITH CONSISTENT SNAPSHOT\n- Lock-free concurrency (no THR_LOCK, TidesDB handles isolation internally)\n- Pessimistic row locking (tidesdb_pessimistic_locking, ON by default).\n  Two-mode lock manager with shared (S) and exclusive (X) locks over a\n  cache-line aligned hash-partitioned table sized at init from CPU\n  count (8 * hardware_concurrency, clamped to 128..65536 partitions).\n  Multiple S holders coexist on the same row, X conflicts with any\n  other holder, and new S requests block while an X is queued so\n  writers are never starved.  Writes acquire X on the actual mutation\n  target inside write_row, update_row and delete_row; range scans\n  under UPDATE/DELETE do not lock rows that ICP filters away. SELECT\n  FOR UPDATE keeps the per-row lock on every cursor-visible row per\n  the SQL contract.  Plain reads acquire S under REPEATABLE-READ or\n  SERIALIZABLE, no lock under READ-COMMITTED or SNAPSHOT (MVCC\n  snapshot suffices).  DFS wait-for-graph deadlock detection bounded\n  by DEADLOCK_MAX_DEPTH walks every conflicting holder per hop;\n  lock-wait timeout configurable via tidesdb_lock_wait_timeout_ms\n  (default 50 s, mirrors innodb_lock_wait_timeout).  Lock entries\n  recycle in place once empty so per-partition memory is bounded by\n  peak concurrent locks.  Status counters tidesdb_lock_waits,\n  tidesdb_lock_wait_us, tidesdb_lock_deadlocks, tidesdb_lock_timeouts,\n  tidesdb_lock_held, tidesdb_lock_entries, tidesdb_lock_entry_recycles\n  surface contention for observability\n- LSM-tree storage with optional B+tree SSTable format\n- Compression (NONE, LZ4, LZ4_FAST, ZSTD, Snappy)\n- Bloom filters for fast key lookups\n- Block cache for frequently accessed data\n- Primary key (single and composite) and secondary index support\n- Index Condition Pushdown (ICP) for secondary index scans\n- Multi-Range Read (MRR) with sorted point-lookup batching for queries of\n  the shape WHERE col IN (v1, v2, ..., vN).  Accepted only when every\n  range is a full-key point equality and there are 2+ ranges; keys are\n  sorted by comparable bytes so the LSM sees a monotone stream of seeks.\n- Bulk UPDATE / DELETE batching --  multi-row UPDATE and DELETE statements\n  share the same mid-txn commit plumbing as bulk INSERT, keeping long\n  statements' txn memory bounded regardless of statement size\n- Single-delete with pair cancellation at compaction -- every secondary\n  index delete (regular, FTS, spatial) uses tidesdb_txn_single_delete\n  unconditionally, safe by construction because each (col_values, pk)\n  composite is put once and deleted once per row lifetime.  Primary CF\n  single-delete is opt-in via the tidesdb_single_delete_primary session\n  variable (default OFF) for sessions that only INSERT and DELETE\n- Tombstone-density compaction trigger -- per-table TOMBSTONE_DENSITY_TRIGGER\n  and TOMBSTONE_DENSITY_MIN_ENTRIES options arm a post-flush check that\n  escalates compaction for any single SSTable whose tombstone density\n  crosses the configured ratio.  Aggregates surface as\n  tidesdb_total_tombstones, tidesdb_tombstone_ratio, and\n  tidesdb_max_sst_tombstone_density status vars\n- Auto compact-after-range-delete -- session variable\n  tidesdb_compact_after_range_delete_min_rows (default 0) lets a multi-row\n  DELETE that touches at least N rows synchronously call\n  tidesdb_compact_range over the touched primary-key range at end of\n  statement, physically reclaiming tombstoned space without waiting for\n  a structural trigger\n- REPLACE INTO and INSERT ... ON DUPLICATE KEY UPDATE\n- AUTO_INCREMENT with O(1) atomic counter (no iterator per INSERT).\n  TRUNCATE TABLE and ALTER TABLE ... AUTO_INCREMENT=N both correctly\n  reset the counter via the reset_auto_increment handler hook.\n- TTL (time-to-live) per-row and per-table expiration\n- Virtual/generated columns\n- Online backup (SET GLOBAL tidesdb_backup_dir = '/path')\n- Hard-link checkpoint (SET GLOBAL tidesdb_checkpoint_dir = '/path')\n- OPTIMIZE TABLE (synchronous purge + compact via tidesdb_purge_cf)\n- CHECK TABLE (verifies SSTable metadata and block integrity)\n- REPAIR TABLE (full purge + compaction, rebuilds LSM tree)\n- FLUSH TABLES FOR EXPORT (HA_CAN_EXPORT, consistent file copy)\n- SHOW ENGINE TIDESDB STATUS (DB stats, memory, cache, conflict info,\n  unified-memtable block with active bytes / immutable count / WAL\n  generation / next-CF index, and a write-amplification block with\n  cumulative user/WAL/flush/compaction bytes plus a derived total WA\n  ratio.  Object-store builds also report the last successfully\n  uploaded unified-WAL generation.)\n- SHOW GLOBAL STATUS LIKE 'tidesdb%' monitoring variables for tools like\n  Prometheus, PMM, Datadog -- column-family and memtable bytes, cache hit\n  rate, tombstone density aggregates, lock-manager observability\n  (tidesdb_lock_waits, tidesdb_lock_wait_us, tidesdb_lock_deadlocks,\n  tidesdb_lock_timeouts, tidesdb_lock_held, tidesdb_lock_entries,\n  tidesdb_lock_entry_recycles), back-pressure wait counters\n  (tidesdb_backpressure_waits, tidesdb_backpressure_wait_us), unified\n  memtable state (tidesdb_unified_memtable_enabled,\n  tidesdb_unified_memtable_bytes, tidesdb_unified_immutable_count,\n  tidesdb_unified_is_flushing, tidesdb_unified_wal_generation),\n  object-store progress (tidesdb_object_store_enabled,\n  tidesdb_replica_mode_active, tidesdb_local_cache_bytes,\n  tidesdb_local_cache_files, tidesdb_upload_queue_depth,\n  tidesdb_total_uploads, tidesdb_upload_failures,\n  tidesdb_last_uploaded_generation), and write-amplification counters\n  (tidesdb_uwal_bytes_written, tidesdb_wal_bytes_written,\n  tidesdb_flush_bytes_written, tidesdb_compaction_bytes_written,\n  tidesdb_compaction_bytes_read, tidesdb_user_bytes_written,\n  tidesdb_flush_count, tidesdb_compaction_count)\n- Handlerton lifecycle + administrative hooks wired:\n    drop_database    DROP DATABASE removes all TidesDB CFs for the db\n    flush_logs       FLUSH LOGS syncs the TidesDB WAL (safe before backup)\n    panic            orderly close on signal-driven shutdown\n    pre_shutdown     background thread quiesce before deinit\n    kill_query       KILL QUERY wakes waiters in row_lock_acquire and is\n                     checked inside rnd_next / index_next / spatial /\n                     ft_read so long scans return HA_ERR_ABORTED_BY_USER\n- Partitioning (RANGE, LIST, HASH, KEY)\n- Data-at-rest encryption (MariaDB encryption plugin integration; fail-closed\n  on missing key so a rotated-out version cannot silently mis-encrypt or\n  return zeroed plaintext)\n- Online DDL (instant metadata, inplace add/drop secondary index, force-copy\n  for FULLTEXT/SPATIAL adds so row back-fill goes through write_row, copy\n  for column-type changes and PK rewrites)\n- TRUNCATE TABLE as O(1) drop+recreate (instant regardless of table size)\n- ANALYZE TABLE with detailed CF statistics (levels, keys, sizes, cache\n  hit rate, plus a per-CF write-amplification note that reports user\n  bytes ingested versus WAL / flush / compaction bytes and the derived\n  ratio, so a single ANALYZE makes the WA of an individual table\n  legible without having to compute it from global counters)\n- Cached optimizer statistics (refreshed every 2 seconds from TidesDB)\n- Full-text search (FULLTEXT indexes with BM25 ranking, natural language\n  and boolean mode, charset-aware tokenizer, configurable BM25 parameters,\n  stop words matching InnoDB defaults, blend_chars for Romance language\n  elision support, extended FT API via HA_CAN_FULLTEXT_EXT)\n- Vector search (VECTOR indexes via MariaDB's MHNSW approximate nearest\n  neighbor, Euclidean and cosine distance, INSERT/UPDATE/DELETE support)\n- Spatial indexes (SPATIAL KEY with Hilbert curve encoding on LSM,\n  MBRIntersects/MBRContains/MBRWithin/MBREquals/MBRDisjoint predicates)\n\nCloud / Object Store:\n- S3-compatible object store backend (AWS S3, MinIO, GCS)\n- Four-tier hot/warm/cold/frozen storage hierarchy\n- Block-level range_get for point lookups on frozen SSTables (single HTTP request)\n- Parallel SSTable prefetch for iterators\n- Read-only replica mode with MANIFEST sync and WAL replay\n- Primary promotion via SET GLOBAL tidesdb_promote_primary = ON\n- Configurable WAL sync (per-commit for RPO=0, or bytes-threshold)\n- LRU local file cache with paired klog/vlog eviction\n- Upload retry with verification, download retry with backoff\n- Kubernetes deployment with automated failover (see k8s/ directory)\n\n\nCONFIGURATION\n░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n\nTidesDB stores its data as a sibling of the MariaDB data directory:\n  \u003cparent_of_datadir\u003e/tidesdb_data\n\n\nSYSTEM VARIABLES (SET GLOBAL tidesdb_...)\n░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n\nRead-only (set at startup):\n\n  flush_threads             Background flush threads (default: 4)\n  compaction_threads        Background compaction threads (default: 4)\n  log_level                 DEBUG/INFO/WARN/ERROR/FATAL/NONE (default: DEBUG)\n  block_cache_size          Global block cache in bytes (default: 256MB)\n  max_open_sstables         Max cached SSTable files (default: 256)\n  max_memory_usage          Global memory limit in bytes; 0 = auto (default: 0)\n  data_home_dir             Override TidesDB data directory (default: auto)\n  log_to_file               Write logs to file vs stderr (default: ON)\n  log_truncation_at         Log file truncation size (default: 24MB; 0 = off)\n  unified_memtable          Single shared WAL+memtable across all CFs (default: ON)\n  unified_memtable_write_buffer_size  Write buffer for unified memtable (default: 256MB)\n  unified_memtable_sync_mode         NONE/INTERVAL/FULL for unified WAL (default: FULL)\n  unified_memtable_sync_interval     Sync interval in µs for INTERVAL mode (default: 128000)\n  unified_memtable_skip_list_max_level   Skip-list max level for the unified\n                                         memtable; 0 keeps the library default\n  unified_memtable_skip_list_probability Skip-list level promotion probability\n                                         for the unified memtable; 0.0 keeps\n                                         the library default\n  object_store_backend      LOCAL or S3 (default: LOCAL)\n  s3_endpoint               S3 endpoint (e.g. s3.amazonaws.com)\n  s3_bucket                 S3 bucket name\n  s3_prefix                 S3 key prefix (e.g. production/db1/)\n  s3_access_key             S3 access key ID\n  s3_secret_key             S3 secret access key\n  s3_region                 S3 region (NULL for MinIO)\n  s3_use_ssl                Use HTTPS (default: ON)\n  s3_path_style             Path-style URLs for MinIO (default: OFF)\n  s3_tls_ca_path            Custom CA bundle path for the S3 TLS handshake;\n                            NULL uses the system bundle\n  s3_tls_insecure_skip_verify  Disable TLS peer/host verification (INSECURE,\n                            test endpoints only; default: OFF)\n  s3_multipart_threshold    Object size in bytes that triggers S3 multipart\n                            upload; 0 keeps the library default\n  s3_multipart_part_size    S3 multipart chunk size in bytes; 0 keeps the\n                            library default\n  objstore_local_cache_max  Local cache size limit (default: 0 = unlimited)\n  objstore_wal_sync_threshold  WAL sync byte threshold (default: 1MB)\n  objstore_wal_sync_on_commit  Upload WAL on every commit (default: OFF)\n  objstore_cache_on_read    Cache downloaded objects locally (default: ON)\n  objstore_cache_on_write   Cache uploaded objects locally (default: ON)\n  objstore_max_concurrent_uploads\n                            Concurrent upload threads; 0 keeps the library\n                            default\n  objstore_max_concurrent_downloads\n                            Concurrent download threads; 0 keeps the library\n                            default\n  objstore_multipart_threshold\n                            Object size in bytes that triggers multipart\n                            upload at the objstore layer; 0 keeps the library\n                            default\n  objstore_multipart_part_size\n                            Multipart chunk size in bytes at the objstore\n                            layer; 0 keeps the library default\n  objstore_sync_manifest_to_object\n                            Upload MANIFEST after each compaction (default: ON)\n  objstore_wal_upload_sync  Block memtable flush on WAL upload\n                            (default: OFF for background WAL upload)\n  objstore_replicate_wal    Upload WAL segments for replica recovery\n                            (default: ON)\n  objstore_replica_replay_wal  Replay WAL on replicas for near-real-time\n                            visibility (default: ON)\n  replica_mode              Read-only replica (default: OFF)\n  replica_sync_interval     MANIFEST poll interval in us (default: 5000000)\n  fast_shutdown             When ON, deinit calls tidesdb_cancel_background_work\n                            before tidesdb_close so in-flight compactions bail\n                            at their next checkpoint and shutdown returns\n                            quickly (default: OFF).  Default OFF lets close\n                            drain naturally, which is safer for object-store\n                            and replica setups where a mid-compaction cancel\n                            can leave S3 with referenced-but-not-yet-uploaded\n                            SSTables that confuse a syncing replica.\n\nDynamic (SET GLOBAL at runtime):\n\n  backup_dir                Set to a path to trigger online backup\n  checkpoint_dir            Set to a path to trigger hard-link checkpoint\n  print_all_conflicts       Log all TDB_ERR_CONFLICT events (default: OFF)\n  pessimistic_locking       Enable plugin-level row locks for SELECT...FOR UPDATE,\n                            UPDATE, DELETE, and INSERT (default: ON).  Two-mode\n                            S/X lock manager over a cache-line aligned\n                            hash-partitioned table sized at init from CPU\n                            count (8 * hardware_concurrency, clamped to\n                            128..65536 partitions).  Writes acquire X on the\n                            actual mutation target inside write_row,\n                            update_row and delete_row; range scans under\n                            UPDATE/DELETE do not lock rows that ICP filters\n                            away.  Plain reads under REPEATABLE-READ or\n                            SERIALIZABLE acquire S (multiple S holders\n                            coexist), while READ-COMMITTED and SNAPSHOT\n                            reads take no lock and rely on MVCC.  A new S\n                            blocks while an X is queued so writers cannot\n                            be starved.  DFS wait-for-graph deadlock\n                            detection with bounded depth, lock-wait timeout\n                            controlled by tidesdb_lock_wait_timeout_ms.  Locks\n                            can cover non-existing keys (SFU on a missing row\n                            blocks INSERT of that key).  OFF reverts to pure\n                            optimistic MVCC, where conflicts surface as\n                            HA_ERR_LOCK_DEADLOCK at COMMIT and the application\n                            must retry.\n  promote_primary           Set to ON to promote a replica to primary\n                            (trigger variable, resets to OFF after promotion)\n  fts_min_word_len          Minimum word length for FTS indexing (default: 3)\n  fts_max_word_len          Maximum word length for FTS indexing (default: 84)\n  fts_bm25_k1               BM25 k1 term-frequency saturation (default: 1.2)\n  fts_bm25_b                BM25 b document-length normalization (default: 0.75)\n  ft_stopword_table         Custom stop word table 'db/table' (default: NULL = InnoDB defaults)\n  fts_blend_chars           Blend characters for Romance elision (default: empty)\n\nSession (SET SESSION tidesdb_...):\n\n  ttl                       Per-session TTL override in seconds (default: 0)\n  skip_unique_check         Skip PK/unique checks on INSERT (default: OFF)\n  lock_wait_timeout_ms      Milliseconds a pessimistic row-lock acquire\n                            waits before returning HA_ERR_LOCK_WAIT_TIMEOUT\n                            (default: 50000, mirrors innodb_lock_wait_timeout).\n                            0 disables the bound and the wait is interrupted\n                            only by KILL QUERY.\n  backpressure_wait_timeout_ms\n                            Milliseconds the plugin blocks a writer on\n                            TidesDB back-pressure (memtable, flush queue,\n                            or L0 backlog at soft cap) before surfacing\n                            the condition to the SQL layer as\n                            HA_ERR_LOCK_WAIT_TIMEOUT (default: 60000).\n                            The budget is anchored once per statement at\n                            external_lock(F_WRLCK) and shared across every\n                            backpressure call inside that statement, so a\n                            multi-row INSERT respects the configured ms\n                            end-to-end instead of multiplying it by row\n                            count.  0 disables blocking and the\n                            back-pressure signal returns immediately.\n  single_delete_primary     Route primary-CF DELETEs through\n                            tidesdb_txn_single_delete (default: OFF).\n                            Caller promises the session does no UPDATE\n                            on non-PK columns, no REPLACE INTO, and no\n                            INSERT ... ON DUPLICATE KEY UPDATE on tables\n                            without secondary indexes.  Violating the\n                            contract may re-expose older row versions\n                            after compaction.  Safe for INSERT-only +\n                            DELETE-only workloads (e.g. log rotation,\n                            iibench l.i1 shape).\n  compact_after_range_delete_min_rows\n                            If non-zero, after a multi-row DELETE that\n                            touches at least this many rows, the engine\n                            calls tidesdb_compact_range over the\n                            touched primary-key range to physically\n                            reclaim tombstoned space synchronously\n                            instead of waiting for a structural\n                            compaction trigger (default: 0 = disabled).\n                            Useful for sliding-window expiry, tenant\n                            eviction, or any DELETE-by-PK-range op.\n  default_compression       Default compression for new tables\n  default_write_buffer_size Default write buffer for new tables (64MB)\n  default_sync_mode         Default sync mode for new tables (FULL)\n  default_tombstone_density_trigger\n                            Default tombstone-density compaction\n                            trigger ratio for new tables, in parts\n                            per 10000 (5000 = 0.50 ratio).  When set\n                            non-zero, after each flush the engine\n                            inspects level-1 SSTables and escalates\n                            compaction for any single SST whose\n                            tombstone count divided by entry count\n                            exceeds the ratio (default: 0 = disabled).\n  default_tombstone_density_min_entries\n                            Minimum entry count for an SSTable to be\n                            considered by the tombstone-density\n                            trigger; smaller SSTables are ignored\n                            (default: 1024).\n  (and other default_* variables for all table options)\n\nLogging -- TidesDB writes to \u003ctidesdb_data\u003e/LOG by default with automatic\ntruncation at 24 MB.  Set log_level to WARN or higher in production to\nreduce log volume.\n\n\nTABLE OPTIONS (CREATE TABLE ... ENGINE=TidesDB \u003coption\u003e=\u003cvalue\u003e)\n░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n\nThese are per-table options set at creation time and applied to the column\nfamily configuration.  ALTER TABLE ... \u003coption\u003e=\u003cvalue\u003e updates both the .frm\nand the live column family via tidesdb_cf_update_runtime_config().\n\nStorage:\n  WRITE_BUFFER_SIZE         Memtable size before flush (default: 64MB PER TABLE/CF)\n  MIN_DISK_SPACE            Minimum free disk space (default: 100MB)\n  KLOG_VALUE_THRESHOLD      Values larger than this go to vlog (default: 512)\n\nCompression:\n  COMPRESSION               NONE/SNAPPY/LZ4/ZSTD/LZ4_FAST (default: LZ4)\n\nBloom Filters:\n  BLOOM_FILTER              Enable bloom filters (default: ON)\n  BLOOM_FPR                 FPR in parts per 10000; 100 = 1% (default: 100)\n\nDurability:\n  SYNC_MODE                 NONE/INTERVAL/FULL (default: FULL)\n  SYNC_INTERVAL_US          Sync interval in microseconds (default: 128000)\n\nIsolation:\n  ISOLATION_LEVEL           READ_UNCOMMITTED/READ_COMMITTED/REPEATABLE_READ/\n                            SNAPSHOT/SERIALIZABLE (default: REPEATABLE_READ)\n\nLSM Tree:\n  USE_BTREE                 Use B+tree SSTable format (default: OFF)\n  LEVEL_SIZE_RATIO          Level size multiplier (default: 10)\n  MIN_LEVELS                Minimum LSM levels (default: 1, matches library)\n  DIVIDING_LEVEL_OFFSET     Compaction dividing level offset (default: 1, matches library)\n  L1_FILE_COUNT_TRIGGER     L1 file count trigger for compaction (default: 4)\n  L0_QUEUE_STALL_THRESHOLD  L0 queue stall threshold (default: 10, matches library)\n  TOMBSTONE_DENSITY_TRIGGER Ratio in parts per 10000 above which compaction\n                            is escalated for a single SSTable when the\n                            tombstone-density check fires after a flush\n                            (e.g. 5000 = 0.50; default: 0 = disabled).\n  TOMBSTONE_DENSITY_MIN_ENTRIES\n                            Minimum entry count for an SSTable to be\n                            considered by the density trigger; smaller\n                            SSTables are skipped (default: 1024).\n\nSkip List:\n  SKIP_LIST_MAX_LEVEL       Max skip list level (default: 12)\n  SKIP_LIST_PROBABILITY     Percentage; 25 = 0.25 (default: 25)\n\nBlock Indexes:\n  BLOCK_INDEXES             Enable block indexes (default: ON)\n  INDEX_SAMPLE_RATIO        Sample ratio for block index (default: 1)\n  BLOCK_INDEX_PREFIX_LEN    Block index prefix length (default: 16)\n\nTTL:\n  TTL                       Default TTL in seconds, 0 = none (default: 0)\n\nObject Store:\n  OBJECT_LAZY_COMPACTION    Double L1 compaction trigger in S3 mode (default: OFF)\n  OBJECT_PREFETCH_COMPACTION Prefetch inputs before merge in S3 mode (default: ON)\n\nEncryption:\n  ENCRYPTED                 Enable data-at-rest encryption (default: OFF)\n  ENCRYPTION_KEY_ID         Encryption key ID (default: 1)\n\n\nDEFAULTS ALIGNMENT WITH THE LIBRARY\n░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n\nThe column-family option defaults track tidesdb_default_column_family_config\nin the underlying TidesDB library 1:1 except for two deliberate\ndeviations chosen to fit SQL semantics.  tidesdb_defaults_alignment in\nthe MTR suite pins every default so a future change has to be made\ndeliberately.\n\n  SYNC_MODE          plugin FULL, library NONE.  SQL clients expect\n                     committed writes to be durable.  Only the per CF\n                     SSTable sync is affected since the shared WAL is\n                     governed by tidesdb_unified_memtable_sync_mode.\n  ISOLATION_LEVEL    plugin REPEATABLE_READ, library READ_COMMITTED.\n                     Matches MariaDB's default session isolation so a\n                     plain CREATE TABLE mirrors what an InnoDB table\n                     would do.\n\nEvery other CF default (write_buffer_size 64MB, level_size_ratio,\nmin_levels, dividing_level_offset, klog_value_threshold, compression\nLZ4, bloom filter on with fpr 0.01, block indexes, index sample ratio,\nblock_index_prefix_len, skip list shape, l1 trigger, l0 stall\nthreshold, tombstone density triggers, min_disk_space, use_btree,\nobject_lazy_compaction, object_prefetch_compaction) matches the\nlibrary exactly so a table created in the plugin and one created with\na bare libtidesdb application share the same on disk shape.\n\ntidesdb_unified_memtable_write_buffer_size defaults to 256MB which is a\nDB-level shared WAL+memtable knob and intentionally larger than a per\nCF buffer since one pool serves every table on the instance.\n\n\nFIELD OPTIONS (per-column)\n░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n\n  TTL                       Marks column as per-row TTL source (seconds)\n\nExample:\n  CREATE TABLE t (\n    id INT PRIMARY KEY,\n    data VARCHAR(100),\n    expires INT TTL=1\n  ) ENGINE=TIDESDB TTL=3600 SYNC_MODE='NONE' COMPRESSION='ZSTD';\n\n\nTESTING\n░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n\nRun all TidesDB tests (from the build directory):\n\n  cd mysql-test\n  perl mtr --suite=tidesdb\n\nRun specific test:\n\n  perl mtr --suite=tidesdb tidesdb_crud\n\nRun with verbose output:\n\n  perl mtr --suite=tidesdb --verbose\n\n\nQUICK TEST\n░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n\n  CREATE TABLE t (id INT PRIMARY KEY, data VARCHAR(100)) ENGINE=TidesDB;\n  INSERT INTO t VALUES (1, 'hello'), (2, 'world');\n  SELECT * FROM t;\n  DROP TABLE t;\n\n\nSANITIZER BUILDS\n░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n\nThe TidesDB plugin supports plugin-level UBSAN/ASAN without rebuilding the\nentire MariaDB server:\n\n  cmake .. -DTIDESDB_WITH_UBSAN=ON   # UBSAN only\n  cmake .. -DTIDESDB_WITH_ASAN=ON    # ASAN only\n  cmake .. -DTIDESDB_WITH_ASAN=ON -DTIDESDB_WITH_UBSAN=ON  # both\n  make -j$(nproc) tidesdb\n\n  # Run tests with sanitizer error logging:\n  UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=0 \\\n    perl ./mtr --suite=tidesdb --parallel=4\n\nFor full ASAN coverage (requires full server rebuild):\n\n  cmake .. -DWITH_ASAN=ON -DWITH_UBSAN=ON -DCMAKE_BUILD_TYPE=Debug\n  make -j$(nproc)\n\n\nLICENSE\n░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░\n\nGNU General Public License v2\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftidesdb%2Ftidesql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftidesdb%2Ftidesql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftidesdb%2Ftidesql/lists"}