knightcrawler-stremio / knightcrawler

A selfhosted Stremio addon
Apache License 2.0
318 stars 43 forks source link

Failed syncing database: Error #66

Closed FunkeCoder23 closed 10 months ago

FunkeCoder23 commented 10 months ago

Describe the bug Getting an error on startup, resolves after a bit of time but causes a decent amount of lag between startup and ingestion.

To Reproduce Steps to reproduce the behavior:

  1. Start and run Knight Crawler
  2. (Potentially, import database using steps in README)
  3. Stop Knight Crawler (gracefully)
  4. Restart Knight Crawler

Expected behavior Startup without errors

Logs

Shortened log:

Failed syncing database:  Error
...
  name: 'SequelizeDatabaseError',
  parent: error: cache lookup failed for attribute 1 of relation 17198
      at Parser.parseErrorMessage (/app/node_modules/pg-protocol/dist/parser.js:287:98)
...
    sql: "SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'files' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;",
    parameters: undefined
  },

Full Logs

Hardware:

Additional context

Seems related to this issue which links to a potential fix:

export let pool = new pg.native.Pool(config);

pool.on('connect', (_client: pg.PoolClient) => {
  // On each new client initiated, need to register for error(this is a serious bug on pg, the client throw errors although it should not)
  _client.on('error', (err: Error) => {
    console.log(err);
  });
});
funkypenguin commented 10 months ago

I too, see errors like this, after importing the rarbg dump:

Created RARBG entry for [029cd7c2a6d89351645febb94ea7649c587c0f45] <redacted>
    internalQuery: undefined,
    where: undefined,
    schema: undefined,
    table: undefined,
            ^
npm notice Changelog: <https://github.com/npm/cli/releases/tag/v10.4.0>
    sql: "SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'ingested_torrents' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;",
    file: 'tablecmds.c',
      at Parser.parseErrorMessage (/app/node_modules/pg-protocol/dist/parser.js:287:98)
Created RARBG entry for [196e3111f7421feb7cf4de02ede6cc928a2b1c6a] Journey.to.the.Far.Side.of.the.Sun.1969.1080p.BRRip.x264-YIFY
node:internal/process/promises:289
            triggerUncaughtException(err, true /* fromPromise */);
            ^
Error
    at Dq.run (/app/dist/index.cjs:310:117524)
    at /app/dist/index.cjs:310:235505 {
  name: 'SequelizeDatabaseError',
  parent: error: cache lookup failed for attribute 1 of relation 19285
      at Parser.parseErrorMessage (/app/node_modules/pg-protocol/dist/parser.js:287:98)
      at Parser.handlePacket (/app/node_modules/pg-protocol/dist/parser.js:126:29)
      at Parser.parse (/app/node_modules/pg-protocol/dist/parser.js:39:38)
      at Socket.<anonymous> (/app/node_modules/pg-protocol/dist/index.js:11:42)
      at Socket.emit (node:events:518:28)
      at addChunk (node:internal/streams/readable:559:12)
      at readableAddChunkPushByteMode (node:internal/streams/readable:510:3)
      at Readable.push (node:internal/streams/readable:390:5)
      at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
    length: 116,
    severity: 'ERROR',
    code: 'XX000',
    detail: undefined,
    hint: undefined,
    position: undefined,
    internalPosition: undefined,
    internalQuery: undefined,
    where: undefined,
    schema: undefined,
    table: undefined,
    column: undefined,
    dataType: undefined,
    constraint: undefined,
    file: 'lsyscache.c',
    line: '1008',
    routine: 'get_attoptions',
    sql: "SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'files' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;",
    parameters: undefined
  },
  original: error: cache lookup failed for attribute 1 of relation 19285
      at Parser.parseErrorMessage (/app/node_modules/pg-protocol/dist/parser.js:287:98)
      at Parser.handlePacket (/app/node_modules/pg-protocol/dist/parser.js:126:29)
Processing torrent Maya.the.Bee.Movie.2014.1080p.BRRip.x264-YIFY with infoHash d856e3b0ec6c5ad18822871cf79b468e4abdf2c1
    column: undefined,
    dataType: undefined,
    constraint: undefined,
    file: 'lsyscache.c',
FunkeCoder23 commented 10 months ago

I too, see errors like this, after importing the rarbg dump: \<snip>

While it might be related to the rarbg dump, you're also seeing logs from multiple consumers at once. The errored consumers aren't able to process/create entries until the errors stop. You can run docker logs knightcrawler-consumer-1 or whichever number you want to view to see only that consumer's logs

FunkeCoder23 commented 10 months ago

After a bit of searching around, it's definitely related to the connect() call in src/node/consumer/src/lib/repository.js

export function connect() {
    if (databaseConfig.ENABLE_SYNC) {
        return database.sync({ alter: true })
            .catch(error => {
-             console.error('Failed syncing database: ', error);
-             throw error;
+             console.error('Failed syncing database: ', error.message);
            });
    }
    return Promise.resolve();
}

this seems to fix the constant error messages. each only prints one error and then resumes functionality. However, I'm not versed enough in js to make the call that this is good practice.

Also, printing the error.message cleans up the logs a lot as Sequelize apparently returns an error object with a bunch of extra data (could be useful for DEBUG_MODE)

Gabisonfire commented 10 months ago

This seems like it! I think this would be a reasonable fix, but I'll wait for someone to review this.

FunkeCoder23 commented 10 months ago

Yeah, after looking through the code, it seems like it defeats the purpose of ENABLE_SYNC. However, I'm not sure what that purpose is... so best to have the JS/Sequelize folks look at it 😄

FunkeCoder23 commented 10 months ago

Another possibility is removing the {alter: true} param, that seems to fix the error completely, even after adding the throw back in. The docs do say to not use in production 🤔

export function connect() {
    if (databaseConfig.ENABLE_SYNC) {
-         return database.sync({ alter: true })
+         return database.sync()
            .catch(error => {
               console.error('Failed syncing database: ', error);
               throw error;
            });
    }
    return Promise.resolve();
}

But again, best to have someone review and decide

Made an MR #68 if this is the route we want to take

purple-emily commented 10 months ago

@FunkeCoder23 Can you try something else for me? Can you change true here to false, and see if the errors stop?

purple-emily commented 10 months ago

Hopefully fixed in #68

Closing. Please open a new issue if you encounter similar problems.