Files
ulthon_admin/database/migrations/20260801125222_nginx_log_add_node_id.php
augushong 8faa52ce90 feat(nginx-log): 多节点适配(node_id 全链路 + 全局/按节点聚合 + 节点筛选 + v2.4.0 升级脚本)
- 6 张表加 node_id 字段 + position/stat 改复合唯一键(migration)
- 6 个 Scheme 同步 node_id 注解 + 唯一键
- Reader 带 node_id 参数 + 懒加载接管(getLastPosition 回退查 node_id='')
- Aggregator 全局行(node_id='')+ 按节点循环 insertAggregatesForScope
- Stat 所有查询方法加 where node_id 条件
- Dashboard 控制器/视图加节点筛选下拉框 + AJAX 带 node_id
- AccessLog 列表加节点列 + 采集进度卡片显示节点信息
- import 定时任务 run_type 改 all(每节点采集自己的日志)
- v2.4.0 升级脚本追加 ALTER TABLE(幂等 check-then-alter)
- 菜单调整:去掉 Nginx 顶级菜单 + 读取位置管理,改为系统管理下挂两个子菜单
- ulthon-timer 文档补充 run_type=all 多节点部署注意事项
2026-08-08 10:33:20 +08:00

71 lines
4.0 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
use think\migration\Migrator;
/**
* nginx 日志表新增 node_id 字段(多节点采集支持)
*
* 变更内容:
* - 6 张表全部新增 node_id varchar(64) default ''(采集节点 ID空=全局汇总)
* - position / 4 张 stat 表的唯一键前置 node_id多节点隔离避免聚合 INSERT 触发 duplicate key
* - raw 表nginx_access_log加 node_id + time_local 普通索引,无唯一键变更
*
* 注意:
* - 不回填历史 raw/stat 数据(旧数据 node_id 为空,视为全局汇总)
* - 不在 migration 中 UPDATE position 的 node_id多节点共享 DB 下第一个节点会抢走所有 position
* position 迁移改为 getLastPosition() 懒加载接管,见配套 Task
* - phinx 表名不带 ul_ 前缀phinx 自动加前缀)
*/
class NginxLogAddNodeId extends Migrator
{
public function change()
{
// ==================== 1. nginx_log_position ====================
// 旧唯一键 uniq_file_path(file_path) → 新 uniq_node_file(node_id, file_path)
$this->table('nginx_log_position')
->addColumn('node_id', 'string', ['limit' => 64, 'default' => '', 'comment' => '采集节点 ID空=全局汇总)'])
->removeIndexByName('uniq_file_path')
->addIndex(['node_id', 'file_path'], ['unique' => true, 'name' => 'uniq_node_file'])
->update();
// ==================== 2. nginx_access_lograw 表)====================
// 仅加字段 + 普通索引(按节点 + 时间查询),无唯一键变更
$this->table('nginx_access_log')
->addColumn('node_id', 'string', ['limit' => 64, 'default' => '', 'comment' => '采集节点 ID空=全局汇总)'])
->addIndex(['node_id', 'time_local'], ['name' => 'idx_node_time'])
->update();
// ==================== 3. nginx_stat_hour ====================
// 旧唯一键 uniq_date_hour(stat_date, stat_hour) → uniq_node_date_hour(node_id, stat_date, stat_hour)
$this->table('nginx_stat_hour')
->addColumn('node_id', 'string', ['limit' => 64, 'default' => '', 'comment' => '采集节点 ID空=全局汇总)'])
->removeIndexByName('uniq_date_hour')
->addIndex(['node_id', 'stat_date', 'stat_hour'], ['unique' => true, 'name' => 'uniq_node_date_hour'])
->update();
// ==================== 4. nginx_stat_url ====================
// 旧唯一键 uniq_date_uri(stat_date, uri) → uniq_node_date_uri(node_id, stat_date, uri)
$this->table('nginx_stat_url')
->addColumn('node_id', 'string', ['limit' => 64, 'default' => '', 'comment' => '采集节点 ID空=全局汇总)'])
->removeIndexByName('uniq_date_uri')
->addIndex(['node_id', 'stat_date', 'uri'], ['unique' => true, 'name' => 'uniq_node_date_uri'])
->update();
// ==================== 5. nginx_stat_referer ====================
// 旧唯一键 uniq_date_referer(stat_date, referer_domain) → uniq_node_date_referer(node_id, stat_date, referer_domain)
$this->table('nginx_stat_referer')
->addColumn('node_id', 'string', ['limit' => 64, 'default' => '', 'comment' => '采集节点 ID空=全局汇总)'])
->removeIndexByName('uniq_date_referer')
->addIndex(['node_id', 'stat_date', 'referer_domain'], ['unique' => true, 'name' => 'uniq_node_date_referer'])
->update();
// ==================== 6. nginx_stat_ua ====================
// 旧唯一键 uniq_date_type_name(stat_date, ua_type, ua_name) → uniq_node_date_type_name(node_id, stat_date, ua_type, ua_name)
$this->table('nginx_stat_ua')
->addColumn('node_id', 'string', ['limit' => 64, 'default' => '', 'comment' => '采集节点 ID空=全局汇总)'])
->removeIndexByName('uniq_date_type_name')
->addIndex(['node_id', 'stat_date', 'ua_type', 'ua_name'], ['unique' => true, 'name' => 'uniq_node_date_type_name'])
->update();
}
}