diff --git a/src/sdk/nb.d.ts b/src/sdk/nb.d.ts index df7d37f4d2..d0a499e554 100644 --- a/src/sdk/nb.d.ts +++ b/src/sdk/nb.d.ts @@ -766,7 +766,7 @@ interface DBCollection { validate(doc: object, warn?: 'warn'): object; - executeSQL(query: string, params: Array, options?: { query_name?: string }): Promise>; + executeSQL(query: string, params: Array, options?: { query_name?: string, preferred_pool?: string }): Promise>; name: any; } diff --git a/src/server/object_services/md_store.js b/src/server/object_services/md_store.js index 0c49cac1e7..1e5212b16d 100644 --- a/src/server/object_services/md_store.js +++ b/src/server/object_services/md_store.js @@ -776,6 +776,7 @@ class MDStore { }, { limit: Math.min(limit, 1000), hint: 'deleted_unreclaimed_index', + preferred_pool: 'read_only', }); return results; } @@ -1123,7 +1124,7 @@ class MDStore { FROM ${this._objects.name} WHERE (to_ts(data->>'deleted') ({ @@ -1773,7 +1775,8 @@ class MDStore { projection: { _id: 1, deleted: 1 - } + }, + preferred_pool: 'read_only' }) .then(objects => db_client.instance().uniq_ids(objects, '_id')); } @@ -1781,6 +1784,8 @@ class MDStore { has_any_blocks_for_chunk(chunk_id) { return this._blocks.findOne({ chunk: { $eq: chunk_id, $exists: true }, + }, { + preferred_pool: 'read_only' }) .then(obj => Boolean(obj)); } @@ -1788,6 +1793,8 @@ class MDStore { has_any_parts_for_chunk(chunk_id) { return this._parts.findOne({ chunk: { $eq: chunk_id, $exists: true }, + }, { + preferred_pool: 'read_only' }) .then(obj => Boolean(obj)); } @@ -2029,7 +2036,8 @@ class MDStore { projection: { _id: 1, deleted: 1 - } + }, + preferred_pool: 'read_only' }) .then(objects => db_client.instance().uniq_ids(objects, '_id')); } diff --git a/src/util/postgres_client.js b/src/util/postgres_client.js index 993ec6970b..e4f053a820 100644 --- a/src/util/postgres_client.js +++ b/src/util/postgres_client.js @@ -248,6 +248,9 @@ function convert_timestamps(where_clause) { async function _do_query(pg_client, q, transaction_counter) { query_counter += 1; + + dbg.log3("pg_client.options?.host =", pg_client.options?.host, ", q =", q); + const tag = `T${_.padStart(transaction_counter, 8, '0')}|Q${_.padStart(query_counter.toString(), 8, '0')}`; try { // dbg.log0(`postgres_client: ${tag}: ${q.text}`, util.inspect(q.values, { depth: 6 })); @@ -629,6 +632,10 @@ class PostgresTable { get_pool(key = this.pool_key) { const pool = this.client.get_pool(key); if (!pool) { + //if original get_pool was not for the default this.pool_key, try also this.pool_key + if (key && key !== this.pool_key) { + return this.get_pool(); + } throw new Error(`The postgres clients pool ${key} disconnected`); } return pool; @@ -716,13 +723,14 @@ class PostgresTable { * @param {Array} params * @param {{ * query_name?: string, + * preferred_pool?: string, * }} [options = {}] * * @returns {Promise>} */ async executeSQL(query, params, options = {}) { /** @type {Pool} */ - const pool = this.get_pool(); + const pool = this.get_pool(options.preferred_pool); const client = await pool.connect(); const q = { @@ -926,7 +934,7 @@ class PostgresTable { query_string += ` OFFSET ${sql_query.offset}`; } try { - const res = await this.single_query(query_string); + const res = await this.single_query(query_string, undefined, this.get_pool(options.preferred_pool)); return res.rows.map(row => decode_json(this.schema, row.data)); } catch (err) { dbg.error('find failed', query, options, query_string, err); @@ -943,7 +951,7 @@ class PostgresTable { } query_string += ' LIMIT 1'; try { - const res = await this.single_query(query_string); + const res = await this.single_query(query_string, undefined, this.get_pool(options.preferred_pool)); if (res.rowCount === 0) return null; return res.rows.map(row => decode_json(this.schema, row.data))[0]; } catch (err) {