@@ -69,7 +69,6 @@
|
||||
## 3. 分区策略与自动分区
|
||||
- 分区键:`ts_ms`
|
||||
- 粒度:按天(Asia/Shanghai,自然日)
|
||||
- 新建分区表空间:每日新分区显式创建在 `ts_hot`(非 `pg_default`)
|
||||
- 自动分区:通过“预创建分区”的方式实现(安装时预建昨天~未来 7 天),并提供函数供服务启动/定时任务调用
|
||||
|
||||
调用方式:
|
||||
|
||||
@@ -105,7 +105,7 @@ npm run db:apply
|
||||
|
||||
```bash
|
||||
# 使用PM2启动服务
|
||||
pm2 start ecosystem.config.cjs
|
||||
pm2 start ecosystem.config.js
|
||||
|
||||
# 查看服务状态
|
||||
pm2 status
|
||||
@@ -129,7 +129,7 @@ pm2 startup
|
||||
|
||||
## PM2配置说明
|
||||
|
||||
项目提供了 `ecosystem.config.cjs` 配置文件,包含以下配置:
|
||||
项目提供了 `ecosystem.config.js` 配置文件,包含以下配置:
|
||||
|
||||
- 应用名称:`web-bls-heartbeat-server`
|
||||
- 运行模式:`cluster`(集群模式)
|
||||
@@ -199,7 +199,7 @@ xcopy /E /I /Y C:\BLS_Heartbeat_Server C:\BLS_Heartbeat_Server_backup
|
||||
npm install --production
|
||||
|
||||
# 重启服务
|
||||
pm2 start ecosystem.config.cjs
|
||||
pm2 start ecosystem.config.js
|
||||
|
||||
# 验证服务状态
|
||||
pm2 status
|
||||
|
||||
55
docs/新分区方法案例.md
Normal file
55
docs/新分区方法案例.md
Normal file
@@ -0,0 +1,55 @@
|
||||
-- 通过 docker compose 在容器内执行 psql,并使用 here-doc 传入 SQL
|
||||
docker compose exec -T postgres psql -U log_admin -d log_platform -v ON_ERROR_STOP=1 <<'SQL'
|
||||
|
||||
-- 使用匿名代码块批量处理分区创建与索引迁移
|
||||
DO $$
|
||||
DECLARE
|
||||
d date; -- 循环日期(从今天到未来 29 天)
|
||||
pname text; -- 分区表名,例如 heartbeat_events_20260303
|
||||
start_ms bigint; -- 分区起始毫秒时间戳(UTC,含)
|
||||
end_ms bigint; -- 分区结束毫秒时间戳(UTC,不含)
|
||||
idx record; -- 遍历分区索引时的游标记录
|
||||
BEGIN
|
||||
-- 生成从 current_date 到 current_date+29 的日期序列(共 30 天)
|
||||
FOR d IN
|
||||
SELECT generate_series(current_date, current_date + 29, interval '1 day')::date
|
||||
LOOP
|
||||
-- 按约定命名分区名:heartbeat_events_YYYYMMDD
|
||||
pname := format('heartbeat_events_%s', to_char(d, 'YYYYMMDD'));
|
||||
|
||||
-- 计算该日期 00:00:00 UTC 的毫秒时间戳作为分区下界
|
||||
start_ms := (extract(epoch from (d::timestamp at time zone 'UTC')) * 1000)::bigint;
|
||||
|
||||
-- 计算下一天 00:00:00 UTC 的毫秒时间戳作为分区上界
|
||||
end_ms := (extract(epoch from ((d + 1)::timestamp at time zone 'UTC')) * 1000)::bigint;
|
||||
|
||||
-- 若分区不存在则创建;存在则跳过(幂等)
|
||||
EXECUTE format(
|
||||
'CREATE TABLE IF NOT EXISTS heartbeat.%I PARTITION OF heartbeat.heartbeat_events FOR VALUES FROM (%s) TO (%s) TABLESPACE ts_hot',
|
||||
pname, start_ms, end_ms
|
||||
);
|
||||
|
||||
-- 无论新建或已存在,强制把分区表迁移到 ts_hot(保证热分区落热盘)
|
||||
EXECUTE format('ALTER TABLE heartbeat.%I SET TABLESPACE ts_hot', pname);
|
||||
|
||||
-- 遍历该分区的全部索引,筛出不在 ts_hot 的索引
|
||||
FOR idx 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 = 'heartbeat'
|
||||
AND t.relname = pname
|
||||
AND COALESCE(ts.spcname, 'pg_default') <> 'ts_hot'
|
||||
LOOP
|
||||
-- 将索引迁移到 ts_hot,确保“分区与索引同盘”
|
||||
EXECUTE format('ALTER INDEX %I.%I SET TABLESPACE ts_hot', idx.index_schema, idx.index_name);
|
||||
END LOOP;
|
||||
END LOOP;
|
||||
END $$;
|
||||
|
||||
-- here-doc 结束标记
|
||||
SQL
|
||||
Reference in New Issue
Block a user