Skip to content

Faiss in CI and default vector db#12265

Merged
ea-rus merged 57 commits into
releases/26.1.0from
faiss-in-ci
Mar 24, 2026
Merged

Faiss in CI and default vector db#12265
ea-rus merged 57 commits into
releases/26.1.0from
faiss-in-ci

Conversation

@ea-rus

@ea-rus ea-rus commented Mar 2, 2026

Copy link
Copy Markdown
Contributor

Description

Updates:

  • chromadb is replaced by duckdb_faiss in CI unit tests
  • duckdb_faiss database is created by default for knowledge base:
    • if duckdb_faiss handler is installed
    • and no shared pgvector is defined
  • block insert into faiss database using threads (because it has locks)

Fixes https://linear.app/mindsdb/issue/FQE-2098/enable-unit-tests-for-macos-and-windows

Type of change

(Please delete options that are not relevant)

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ⚡ New feature (non-breaking change which adds functionality)

Verification Process

To ensure the changes are working as expected:

  • Test Location: Specify the URL or path for testing.
  • Verification Steps: Outline the steps or queries needed to validate the change. Include any data, configurations, or actions required to reproduce or see the new functionality.

Additional Media:

  • I have attached a brief loom video or screenshots showcasing the new functionality or change.

Checklist:

  • My code follows the style guidelines(PEP 8) of MindsDB.
  • I have appropriately commented on my code, especially in complex areas.
  • Necessary documentation updates are either made or tracked in issues.
  • Relevant unit and integration tests are updated or added.

Confidence Score: 3/5 - Review Recommended

  • There is an unresolved correctness issue in the knowledge base controller where non-unique integration names could cause conflicts between Knowledge Bases from different projects that share the same name
  • The bug could lead to integration name collisions in a multi-project environment, potentially causing one KB's FAISS store to overwrite or conflict with another's
  • No new issues were found in the current review, suggesting the rest of the PR is clean, but this existing unresolved bug is a genuine correctness concern worth addressing before merge
  • 1 previous unresolved comment(s) likely resolved in latest diff (score-only signal; thread status unchanged)
Files requiring special attention
  • mindsdb/interfaces/knowledge_base/controller.py

Comment on lines +57 to +63
recover_path = Path(self.path).parent / "recover"
if recover_path.exists():
# move all files from recover dir that might be left after index failing
for item in recover_path.iterdir():
if item.is_dir():
continue
item.rename(Path(self.path).parent / item.name)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correctness: In FaissIndex.__init__, moving files from recover_path to the parent directory is performed unconditionally. If a crash occurs after a new index is saved but before the recover directory is deleted, this logic will overwrite the new index with the old backup. This recovery should only be performed if the primary index file (self.path) does not already exist.

🤖 AI Agent Prompt for Cursor/Windsurf

📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue

In `mindsdb/integrations/handlers/duckdb_faiss_handler/faiss_index.py` (lines 57-63), prevent recovery from overwriting a valid index. Update the recovery guard to only move files back when the main index file is missing (e.g., `if recover_path.exists() and not os.path.exists(self.path):`). Ensure existing index files are not replaced by stale recover artifacts.

Comment on lines +203 to +206
# remove index files (everything except duckdb)
for item in Path(self.path).parent.iterdir():
if item.is_dir() or item.name.startswith("duckdb."):
continue

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correctness: The drop method iterates over the parent directory and unlinks all files that do not start with duckdb.. This is destructive and will delete unrelated files stored in the same directory. Limit the deletion to files explicitly managed by this class, for example by checking if the filename starts with faiss_index.

🤖 AI Agent Prompt for Cursor/Windsurf

📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue

In `mindsdb/integrations/handlers/duckdb_faiss_handler/faiss_index.py` around lines 203-206, `drop()` currently unlinks every non-`duckdb.*` file in the index directory. This risks deleting unrelated files. Update the loop to only delete FAISS-related files (e.g., names starting with `faiss_`). Apply the provided diff suggestion exactly.

Comment on lines +149 to +151
now_ts = time.time()
to_close: List[str] = []
for table_name, entry in self.tables_cache.items():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correctness: ⚠️ The pruning logic relies on in_use_count, but increments/decrements happen outside tables_cache_lock in open_table. This allows a race where in_use_count is observed as 0 while another thread is about to use the table, causing it to be closed mid-use. 🔥 Move the in_use_count/last_used_ts updates under the same lock (or use a dedicated lock) so pruning sees consistent state.

Affected Locations:

  • mindsdb/integrations/handlers/duckdb_faiss_handler/duckdb_faiss_handler.py:149-151
  • mindsdb/integrations/handlers/duckdb_faiss_handler/duckdb_faiss_handler.py:185-197
🤖 AI Agent Prompt for Cursor/Windsurf

📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue

In `mindsdb/integrations/handlers/duckdb_faiss_handler/duckdb_faiss_handler.py` around lines 149-151, `_close_old_tables_cache` prunes based on `entry.in_use_count`. Update `open_table` so increments/decrements of `entry.in_use_count` (and `last_used_ts`) are performed while holding `self.tables_cache_lock`, or otherwise synchronize access, to prevent pruning a table while it is being used.

@ea-rus ea-rus changed the base branch from main to faiss-tables March 6, 2026 13:48
@ea-rus ea-rus marked this pull request as ready for review March 6, 2026 13:51
@ea-rus ea-rus requested a review from a team as a code owner March 6, 2026 13:51
@ea-rus ea-rus changed the title Faiss in ci Faiss in CI and default vector db Mar 6, 2026
@martyna-mindsdb martyna-mindsdb requested a review from tino097 March 10, 2026 14:45

@tino097 tino097 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Base automatically changed from faiss-tables to releases/26.1.0 March 19, 2026 16:44
ea-rus added 3 commits March 19, 2026 19:47
# Conflicts:
#	mindsdb/api/executor/sql_query/sql_query.py
#	mindsdb/interfaces/knowledge_base/controller.py
@ea-rus

ea-rus commented Mar 19, 2026

Copy link
Copy Markdown
Contributor Author

@mindsdb-devops, I made some updates of CI actions in this PR: replaced chromadb with faiss

# Conflicts:
#	requirements/requirements-kb.txt
@ea-rus ea-rus merged commit f5f55c5 into releases/26.1.0 Mar 24, 2026
18 checks passed
@ea-rus ea-rus deleted the faiss-in-ci branch March 24, 2026 13:18
@github-actions github-actions Bot locked and limited conversation to collaborators Mar 24, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants