feat: 添加 relocate_partition_to_tablespace 函数以强制分区及其索引分配到指定表空间,并在创建日分区时调用该函数
This commit is contained in:
@@ -33,6 +33,70 @@ AS $$
|
||||
SELECT format('heartbeat_events_%s', to_char(p_day, 'YYYYMMDD'));
|
||||
$$;
|
||||
|
||||
-- 强制将分区及其索引分配到指定表空间(幂等)
|
||||
CREATE OR REPLACE FUNCTION heartbeat.relocate_partition_to_tablespace(
|
||||
p_schema text,
|
||||
p_partition text,
|
||||
p_tablespace text DEFAULT 'ts_hot'
|
||||
)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
DECLARE
|
||||
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 = p_schema
|
||||
AND c.relname = p_partition
|
||||
AND c.relkind = 'r';
|
||||
|
||||
IF v_part_oid IS NULL THEN
|
||||
RAISE EXCEPTION 'partition %.% not found', p_schema, p_partition;
|
||||
END IF;
|
||||
|
||||
-- 1) 分区表对象 -> 指定 tablespace
|
||||
EXECUTE format('ALTER TABLE %I.%I SET TABLESPACE %I', p_schema, p_partition, p_tablespace);
|
||||
|
||||
-- 2) 分区全部索引 -> 指定 tablespace
|
||||
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_part_oid
|
||||
AND COALESCE(ts.spcname, 'pg_default') <> p_tablespace
|
||||
LOOP
|
||||
EXECUTE format('ALTER INDEX %I.%I SET TABLESPACE %I', r.index_schema, r.index_name, p_tablespace);
|
||||
END LOOP;
|
||||
|
||||
-- 3) TOAST 表 + TOAST 索引 -> 指定 tablespace(若存在)
|
||||
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, p_tablespace);
|
||||
|
||||
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') <> p_tablespace
|
||||
LOOP
|
||||
EXECUTE format('ALTER INDEX %I.%I SET TABLESPACE %I', r.index_schema, r.index_name, p_tablespace);
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
-- 4) 统计信息
|
||||
EXECUTE format('ANALYZE %I.%I', p_schema, p_partition);
|
||||
END;
|
||||
$$;
|
||||
|
||||
-- 创建单日分区(幂等);父表索引自动继承到子表,无需手动建索引
|
||||
CREATE OR REPLACE FUNCTION heartbeat.create_daily_partition(p_day date)
|
||||
RETURNS void
|
||||
@@ -51,6 +115,8 @@ BEGIN
|
||||
'CREATE TABLE IF NOT EXISTS heartbeat.%I PARTITION OF heartbeat.heartbeat_events FOR VALUES FROM (%s) TO (%s) TABLESPACE ts_hot',
|
||||
part_name, start_ms, end_ms
|
||||
);
|
||||
|
||||
PERFORM heartbeat.relocate_partition_to_tablespace('heartbeat', part_name, 'ts_hot');
|
||||
END;
|
||||
$$;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user