fix(server): sync PostgreSQL and LanceDB discrepancies on startup - #553
Conversation
There was a problem hiding this comment.
Code Review
This pull request enhances the startup maintenance checks by comparing media IDs between PostgreSQL and LanceDB to queue delta syncs for any discrepancies, rather than defaulting to a full sync. The review feedback identifies two critical improvement opportunities: chunking the discrepancy lists when queueing delta syncs to avoid exceeding PostgreSQL parameter limits, and paginating the LanceDB query when reading media IDs to prevent potential Out-of-Memory (OOM) errors.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if (toUpsert.length > 0) { | ||
| await BackupService.queueSourceLanceDBDelta( | ||
| source.id, | ||
| toUpsert, | ||
| "upsert", | ||
| { enqueueJob: false }, | ||
| ); | ||
| } | ||
| if (toDelete.length > 0) { | ||
| await BackupService.queueSourceLanceDBDelta( | ||
| source.id, | ||
| toDelete, | ||
| "delete", | ||
| { enqueueJob: false }, | ||
| ); | ||
| } |
There was a problem hiding this comment.
PostgreSQLのプレースホルダー(パラメータ)数の上限(65,535)やメモリ負荷を考慮すると、toUpsert や toDelete の件数が非常に大きい場合に BackupService.queueSourceLanceDBDelta 内のバルクインサート処理でエラーが発生する可能性があります。
lanceDbSyncDirty テーブルは4カラム(mediaSourceId, mediaId, operation, updatedAt)を持つため、一度にインサートできる件数は最大でも約16,000件程度に制限されます。
安全のため、toUpsert および toDelete を一定のチャンクサイズ(例: 1000件ずつ)に分割して queueSourceLanceDBDelta を呼び出すように修正することを推奨します。
const CHUNK_SIZE = 1000;
if (toUpsert.length > 0) {
for (let i = 0; i < toUpsert.length; i += CHUNK_SIZE) {
const chunk = toUpsert.slice(i, i + CHUNK_SIZE);
await BackupService.queueSourceLanceDBDelta(
source.id,
chunk,
"upsert",
{ enqueueJob: false },
);
}
}
if (toDelete.length > 0) {
for (let i = 0; i < toDelete.length; i += CHUNK_SIZE) {
const chunk = toDelete.slice(i, i + CHUNK_SIZE);
await BackupService.queueSourceLanceDBDelta(
source.id,
chunk,
"delete",
{ enqueueJob: false },
);
}
}| async function readMediaIds(lanceDbDir: string): Promise<string[]> { | ||
| const connect = await getConnect(); | ||
| const db = await connect(lanceDbDir); | ||
| const mediaTable = await db.openTable("media"); | ||
| const rows = await mediaTable.query().select(["id"]).toArray(); | ||
| return rows.flatMap((row) => { | ||
| const id = safeString(row.id); | ||
| return id ? [id] : []; | ||
| }); | ||
| } |
There was a problem hiding this comment.
mediaTable.query().select(["id"]).toArray() は、LanceDBの media テーブルに格納されているすべてのレコードのIDを一度にメモリ上に読み込みます。
メディアの件数が非常に多い場合(数十万〜数百万件など)、一時的に大量のメモリを消費し、最悪の場合Out-of-Memory (OOM) エラーを引き起こす可能性があります。
すでに定義されている readPage などのヘルパー関数と同様に、一定のチャンクサイズ(例: 5000件ずつ)で分割してIDを取得し、配列に結合していく方式にすることで、メモリ消費を抑え安全に処理することができます。
async function readMediaIds(lanceDbDir: string): Promise<string[]> {
const connect = await getConnect();
const db = await connect(lanceDbDir);
const mediaTable = await db.openTable("media");
const allIds: string[] = [];
let offset = 0;
const limit = 5000;
while (true) {
const rows = await mediaTable.query().select(["id"]).limit(limit).offset(offset).toArray();
if (rows.length === 0) break;
for (const row of rows) {
const id = safeString(row.id);
if (id) {
allIds.push(id);
}
}
if (rows.length < limit) break;
offset += rows.length;
}
return allIds;
}References
- When implementing chunked or streaming reads of relational data from a database (such as LanceDB) to prevent Out-of-Memory (OOM) errors, avoid loading all tables entirely into memory.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
概要
サーバー起動時に PostgreSQL と LanceDB のメディアデータの不整合を検出し、差分同期ジョブを実行する機能を追加します。
変更内容
ILanceDbDumpServiceにreadMediaIds関数を追加し、LanceDB に格納されているメディアID一覧を取得できるように変更MaintenanceServiceのスタートアップ処理にて、LanceDB の manifest ファイルが存在する場合に PostgreSQL 内のメディアIDと LanceDB 内のメディアIDを比較する処理を追加BackupService.queueSourceLanceDBDeltaを呼んで差分データをキューし、差分同期ジョブ(sync_lancedb_delta)を生成する処理を実装