Merge branch 'main' of http://blv-rd.tech:3001/Boonlive_RD_Web/Web_BLS_RCUAction_Server
This commit is contained in:
@@ -3,6 +3,8 @@ import dbManager from './databaseManager.js';
|
||||
|
||||
const PARENT_TABLE = 'rcu_action.rcu_action_events';
|
||||
const PARTITION_TABLESPACE = 'ts_hot';
|
||||
const PARTITION_SCHEMA = 'rcu_action';
|
||||
const PARTITION_PREFIX = 'rcu_action_events_';
|
||||
const PARENT_INDEX_STATEMENTS = [
|
||||
'CREATE INDEX IF NOT EXISTS idx_rcu_action_hotel_id ON rcu_action.rcu_action_events (hotel_id);',
|
||||
'CREATE INDEX IF NOT EXISTS idx_rcu_action_room_id ON rcu_action.rcu_action_events (room_id);',
|
||||
@@ -14,6 +16,72 @@ const PARENT_INDEX_STATEMENTS = [
|
||||
];
|
||||
|
||||
class PartitionManager {
|
||||
toSqlTextLiteral(value) {
|
||||
return `'${String(value).replace(/'/g, "''")}'`;
|
||||
}
|
||||
|
||||
buildForceTablespaceSql({ schema, partition, tablespace }) {
|
||||
return `
|
||||
DO $$
|
||||
DECLARE
|
||||
v_schema text := ${this.toSqlTextLiteral(schema)};
|
||||
v_partition text := ${this.toSqlTextLiteral(partition)};
|
||||
v_hot text := ${this.toSqlTextLiteral(tablespace)};
|
||||
v_part_oid oid;
|
||||
v_toast_oid oid;
|
||||
r record;
|
||||
BEGIN
|
||||
SELECT c.oid INTO v_part_oid
|
||||
FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
|
||||
WHERE n.nspname = v_schema AND c.relname = v_partition AND c.relkind = 'r';
|
||||
|
||||
IF v_part_oid IS NULL THEN
|
||||
RAISE EXCEPTION 'partition %.% not found', v_schema, v_partition;
|
||||
END IF;
|
||||
|
||||
-- 1) 分区表对象 -> hot
|
||||
EXECUTE format('ALTER TABLE %I.%I SET TABLESPACE %I', v_schema, v_partition, v_hot);
|
||||
|
||||
-- 2) 分区全部索引 -> hot
|
||||
FOR r IN
|
||||
SELECT idxn.nspname AS index_schema, i.relname AS index_name
|
||||
FROM pg_index x
|
||||
JOIN pg_class t ON t.oid = x.indrelid
|
||||
JOIN pg_namespace nt ON nt.oid = t.relnamespace
|
||||
JOIN pg_class i ON i.oid = x.indexrelid
|
||||
JOIN pg_namespace idxn ON idxn.oid = i.relnamespace
|
||||
LEFT JOIN pg_tablespace ts ON ts.oid = i.reltablespace
|
||||
WHERE nt.nspname = v_schema
|
||||
AND t.relname = v_partition
|
||||
AND COALESCE(ts.spcname, 'pg_default') <> v_hot
|
||||
LOOP
|
||||
EXECUTE format('ALTER INDEX %I.%I SET TABLESPACE %I', r.index_schema, r.index_name, v_hot);
|
||||
END LOOP;
|
||||
|
||||
-- 3) TOAST 表 + TOAST 全部索引 -> hot(若存在)
|
||||
SELECT reltoastrelid INTO v_toast_oid FROM pg_class WHERE oid = v_part_oid;
|
||||
IF v_toast_oid IS NOT NULL AND v_toast_oid <> 0 THEN
|
||||
EXECUTE format('ALTER TABLE %s SET TABLESPACE %I', v_toast_oid::regclass, v_hot);
|
||||
|
||||
FOR r IN
|
||||
SELECT idxn.nspname AS index_schema, i.relname AS index_name
|
||||
FROM pg_index x
|
||||
JOIN pg_class i ON i.oid = x.indexrelid
|
||||
JOIN pg_namespace idxn ON idxn.oid = i.relnamespace
|
||||
LEFT JOIN pg_tablespace ts ON ts.oid = i.reltablespace
|
||||
WHERE x.indrelid = v_toast_oid
|
||||
AND COALESCE(ts.spcname, 'pg_default') <> v_hot
|
||||
LOOP
|
||||
EXECUTE format('ALTER INDEX %I.%I SET TABLESPACE %I', r.index_schema, r.index_name, v_hot);
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
-- 4) 统计信息
|
||||
EXECUTE format('ANALYZE %I.%I', v_schema, v_partition);
|
||||
END $$;
|
||||
`;
|
||||
}
|
||||
|
||||
async ensureParentIndexes(client) {
|
||||
for (const sql of PARENT_INDEX_STATEMENTS) {
|
||||
await client.query(sql);
|
||||
@@ -59,7 +127,8 @@ class PartitionManager {
|
||||
targetDate.setDate(now.getDate() + i);
|
||||
|
||||
const { startMs, endMs, partitionSuffix } = this.getPartitionInfo(targetDate);
|
||||
const partitionName = `rcu_action.rcu_action_events_${partitionSuffix}`;
|
||||
const partitionTable = `${PARTITION_PREFIX}${partitionSuffix}`;
|
||||
const partitionName = `${PARTITION_SCHEMA}.${partitionTable}`;
|
||||
|
||||
// Check if partition exists
|
||||
const checkSql = `
|
||||
@@ -76,6 +145,13 @@ class PartitionManager {
|
||||
TABLESPACE ${PARTITION_TABLESPACE};
|
||||
`;
|
||||
await client.query(createSql);
|
||||
|
||||
const forceTablespaceSql = this.buildForceTablespaceSql({
|
||||
schema: PARTITION_SCHEMA,
|
||||
partition: partitionTable,
|
||||
tablespace: PARTITION_TABLESPACE
|
||||
});
|
||||
await client.query(forceTablespaceSql);
|
||||
}
|
||||
}
|
||||
logger.info('Partition check completed.');
|
||||
|
||||
Reference in New Issue
Block a user