Phorge 2026.27 常用 CLI 与运维命令详解

覆盖 Phorge 2026.27 的 bin/storage、bin/config、bin/phd、bin/aphlict、bin/user、bin/cache、bin/search 常用子命令与真实回显,含备份、升级回滚、日志定位和 7 条实测排障案例。

PhorgePHPPHP 应用项目管理工单系统2026/10/28

Phorge 2026.27 常用 CLI 与运维命令详解

目标:把 Phorge 2026.27 的日常命令行工具讲全——bin/storage、bin/config、bin/phd、bin/aphlict、bin/user、bin/cache、bin/search 的常用子命令、真实回显与典型运维场景(备份、升级、日志定位、故障恢复)。文中命令与回显均来自 2026-10-28 的实测环境(Ubuntu 22.04.5 LTS、Phorge 2026.27、源码目录 /var/www/phorge、站点端口 8138)。

一、环境信息

项目实测值
操作系统Ubuntu 22.04.5 LTS(x86_64)
Phorge2026.27
PHP8.1.2-1ubuntu2.28(php8.1-cli 执行 bin 脚本)
数据库MySQL 8.0.46-0ubuntu0.22.04.4
Web 服务器Nginx 1.18.0
源码目录/var/www/phorge
Arcanist 目录/var/www/arcanist
运行账号www-data
站点地址http://192.168.1.100:8138
查询日期2026-10-28

所有 bin/* 命令都必须在源码根目录执行,或用绝对路径(如 /var/www/phorge/bin/storage)调用;脚本会以当前工作目录定位 arcanist/ 与 conf/。托管场景统一用 runuser -u www-data -- 切换账号。

二、工具概览

工具作用常用子命令
bin/storage数据库结构与数据维护status、databases、probe、upgrade、adjust、analyze、optimize、dump、destroy、renamespace、shell
bin/config配置读写list、get、set、delete、migrate
bin/phd后台守护进程start、stop、restart、status、list、log、launch、debug、reload
bin/aphlict实时通知服务start、stop、restart、status、notify、debug
bin/user账号救援approve、empower、enable
bin/cache缓存清理purge
bin/search全文索引init、index、ngrams、query

bin/storage 是运维最核心的工具,先看它的完整工作流清单:

cd /var/www/phorge
runuser -u www-data -- ./bin/storage help

实测输出(节选,完整清单共 14 个工作流):

WORKFLOWS

      adjust [options]
      Make schemata adjustments to correct issues with characters sets,
      collations, and keys.

      analyze
      Run "ANALYZE TABLE" on tables to improve performance.

      databases [options]
      List databases.

      destroy [options]
      Permanently destroy all storage and data.

      dump [options]
      Dump all data in storage to stdout.

      help [command]
      Show this help, or workflow help for command.

      optimize
      Run "OPTIMIZE TABLE" on tables to reclaim space.

      partition [options]
      Commit partition configuration to databases.

      probe
      Show approximate table sizes.

      quickstart [options]
      Generate a new quickstart database dump. This command is mostly useful
      for internal development.

      renamespace [options] --input dump.sql --from old --to new > out.sql
      Change the database namespace of a .sql dump file.

      shell [options]
      Launch an interactive shell.

      status [options]
      Show patch application status.

      upgrade [options]
      Upgrade database schemata.

通用选项:--dryrun 只演练不改动、--force/-f 跳过危险操作确认、--host/--user/--password/--namespace 覆盖连接参数。

三、前置条件

3.1 Arcanist 必须与源码并列

ls /var/www

实测回显:

arcanist  phorge

缺 arcanist 时任何 bin/* 命令都会报:

FATAL ERROR: Unable to load the "Arcanist" library. Put "arcanist/" next to "phorge/" on disk.

3.2 数据库账号可连、库已初始化

mysql -u phorge -pq1w2e3r4 -e 'SELECT COUNT(*) FROM information_schema.schemata WHERE schema_name LIKE "phabricator\_%";'

实测回显:

+----------+
| COUNT(*) |
+----------+
|       56 |
+----------+

3.3 先确认服务状态再动命令

systemctl is-active mysql
systemctl is-active php8.1-fpm
systemctl is-active nginx
systemctl is-active phorge-phd
systemctl is-active phorge-aphlict

实测回显:

active
active
active
active
active

3.4 明确「谁在托管进程」

bin/phd 与 bin/aphlict 既可以手工启停,也可以交给 systemd。本环境用 systemd 单元 phorge-phd.service、phorge-aphlict.service 托管,因此日常操作应使用 systemctl,而不是直接 bin/phd restart,原因见 9.2。

四、bin/storage:数据库与仓储维护

4.1 查看补丁状态:status

status 输出每个应用库与每个补丁的应用情况,按行排列。本环境共 1561 行:

cd /var/www/phorge
runuser -u www-data -- ./bin/storage status | wc -l
runuser -u www-data -- ./bin/storage status | head -12
runuser -u www-data -- ./bin/storage status | tail -4

实测回显(首尾节选):

1561
phabricator:db.audit                                                  default localhost:3306 Applied -          db   audit
phabricator:db.calendar                                               default localhost:3306 Applied -          db   calendar
phabricator:db.conduit                                                default localhost:3306 Applied -          db   conduit
phabricator:db.countdown                                              default localhost:3306 Applied -          db   countdown
phabricator:db.daemon                                                 default localhost:3306 Applied -          db   daemon
phabricator:db.differential                                           default localhost:3306 Applied -          db   differential
phabricator:db.draft                                                  default localhost:3306 Applied -          db   draft
phabricator:db.drydock                                                default localhost:3306 Applied -          db   drydock
phabricator:db.feed                                                   default localhost:3306 Applied -          db   feed
phabricator:db.file                                                   default localhost:3306 Applied -          db   file
phabricator:db.flag                                                   default localhost:3306 Applied -          db   flag
phabricator:db.harbormaster                                           default localhost:3306 Applied -          db   harbormaster
phabricator:20190412.herald.01.rebuild.php                            worker  localhost:3306 Applied 1,878 us   php  /var/www/phorge/resources/sql/autopatches/20190412.herald.01.rebuild.php
phabricator:20190909.herald.01.rebuild.php                            worker  localhost:3306 Applied 5,155 us   php  /var/www/phorge/resources/sql/autopatches/20190909.herald.01.rebuild.php
phabricator:20191028.uriindex.01.rebuild.php                          worker  localhost:3306 Applied 2,389 us   php  /var/www/phorge/resources/sql/autopatches/20191028.uriindex.01.rebuild.php
phabricator:20230902.repository.01.rebuild-index.php                  worker  localhost:3306 Applied 5,681 us   php  /var/www/phorge/resources/sql/autopatches/20230902.repository.01.rebuild-index.php

排障用法:搜 Not Applied 或 Applied 之外的异常状态:

runuser -u www-data -- ./bin/storage status | grep -v 'Applied' | head

预期结果:无输出(全部补丁已应用)。若有输出,说明某个补丁失败或被跳过,需结合 bin/storage upgrade 的报错定位。

4.2 列出数据库:databases

runuser -u www-data -- ./bin/storage databases | wc -l
runuser -u www-data -- ./bin/storage databases | head -10

实测回显:

54
phabricator_audit
phabricator_calendar
phabricator_conduit
phabricator_countdown
phabricator_daemon
phabricator_differential
phabricator_draft
phabricator_drydock
phabricator_feed
phabricator_file

💡 说明:MySQL 里实际有 56 个 phabricator_* 库(3.2 的 SHOW DATABASES 统计),而 bin/storage databases 列出 54 个——它按当前应用清单输出,少掉 phabricator_fund 与 phabricator_pastebin 两个历史库。做备份时要按 SHOW DATABASES 的结果覆盖,避免漏库。

4.3 容量体检:probe

runuser -u www-data -- ./bin/storage probe | head -18

实测回显(节选):

Analyzing table sizes (this may take a moment)...
phabricator_phrequent                             0.0 MB        0.1%
    phrequent_usertime                            0.0 MB        0.1%
phabricator_xhpast                                0.0 MB        0.1%
    phpast_parsetree                              0.0 MB        0.1%
    xhpast_parsetree                              0.0 MB        0.1%
phabricator_xhprof                                0.0 MB        0.1%
    xhprof_sample                                 0.0 MB        0.1%
phabricator_flag                                  0.0 MB        0.2%
    flag                                          0.0 MB        0.2%
phabricator_draft                                 0.1 MB        0.3%
    draft                                         0.0 MB        0.1%
    draft_versioneddraft                          0.0 MB        0.1%
phabricator_system                                0.1 MB        0.3%
    system_destructionlog                         0.0 MB        0.1%
    system_actionlog                              0.0 MB        0.2%
phabricator_cache                                 0.1 MB        0.4%
    cache_markupcache                             0.0 MB        0.2%

最后一列是该库占全部数据的百分比。新建环境几乎都是 0.x%,只有附件表或任务表增长后才会明显变化。

4.4 升级结构:upgrade

首次安装用 --force 跳过交互确认;已是最新版本时重复执行只做校验与统计:

runuser -u www-data -- ./bin/storage upgrade --force

实测回显:

Storage is up to date. Use "storage status" for details.
Synchronizing static tables...
Verifying database schemata on "localhost:3306"...
Found no adjustments for schemata.
 ANALYZE  Analyzing tables...
 ANALYZED  Analyzed 500 tables.

升级前可先演练:

runuser -u www-data -- ./bin/storage upgrade --dryrun

预期结果:只打印将执行的补丁,不写数据库。升级类操作必须先备份,完整流程见第八章。

4.5 修正与优化:adjust / analyze / optimize

schema 出现字符集、排序规则、索引差异时用 adjust,先演练:

runuser -u www-data -- ./bin/storage adjust --dryrun

实测回显:

Verifying database schemata on "localhost:3306"...
Found no adjustments for schemata.

analyze 更新统计信息,optimize 回收表空间。两者都是全库操作,建议在低峰执行:

runuser -u www-data -- ./bin/storage analyze
runuser -u www-data -- ./bin/storage optimize

实测 analyze 的等效输出会在 upgrade 尾部出现(ANALYZED Analyzed 500 tables.)。optimize 本环境未执行,按 MySQL 8.0 的 OPTIMIZE TABLE 语义运行,存在锁表时间,大表环境要避开业务高峰。

4.6 导出与销毁:dump / destroy / renamespace / shell

dump 把所有库导出到标准输出,适合管道压缩或落盘:

mkdir -p /var/backups/phorge
runuser -u www-data -- ./bin/storage dump > /var/backups/phorge/phorge-storage-20261028.sql
echo EXIT=$?
ls -lh /var/backups/phorge/phorge-storage-20261028.sql

实测回显:

EXIT=0
-rw-r--r-- 1 root root 1.5M Oct 27 18:26 /var/backups/phorge/phorge-storage-20261028.sql

导出时 stderr 会出现两行 Access denied; you need (at least one of) the PROCESS privilege(s) for this operation(mysqldump 读取表空间信息时的告警),但退出码仍为 0、SQL 文件完整,原因与规避方式见 9.4。

destroy 会永久删除全部数据,只有确认要重装时才执行,且必须先加 --dryrun 看清范围:

runuser -u www-data -- ./bin/storage destroy --dryrun

预期结果:列出将被销毁的库,不实际删除。去掉 --dryrun 后仍需输入确认,生产环境不要执行。

改名空间(把旧 dump 的库前缀换掉)用 renamespace:

runuser -u www-data -- ./bin/storage renamespace --input /var/backups/phorge/phorge-storage-20261028.sql --from phabricator --to phorge2 > /var/backups/phorge/phorge2.sql

预期结果:生成 phorge2.sql,其中 phabricator_* 全部替换为 phorge2_*。该命令本环境未执行,属文档化用法。

交互式进库用 shell:

runuser -u www-data -- ./bin/storage shell

预期结果:进入 MySQL 交互终端,exit 退出。

五、bin/config:配置读写

bin/config 的完整工作流:

runuser -u www-data -- ./bin/config help

实测关键输出:

      delete key
      Delete a local configuration value.

      get key
      Get a local configuration value.

      list
      List all configuration keys.

      migrate
      Migrate file-based configuration to more modern storage.

      set key value
      set key --stdin < value.json
      Set a local configuration value.

常用操作与实测回显:

runuser -u www-data -- ./bin/config list | wc -l
runuser -u www-data -- ./bin/config set account.minimum-password-length 10
runuser -u www-data -- ./bin/config get account.minimum-password-length
runuser -u www-data -- ./bin/config delete account.minimum-password-length
155
 DONE  Wrote configuration key "account.minimum-password-length" to local storage (in file "conf/local/local.json").
{
  "config": [
    {
      "key": "account.minimum-password-length",
      "source": "local",
      "value": 10,
      "status": "set",
      "errorInfo": null
    },
    {
      "key": "account.minimum-password-length",
      "source": "database",
      "value": null,
      "status": "unset",
      "errorInfo": null
    }
  ]
}
Deleted 'account.minimum-password-length' from local configuration.

两个高频报错及含义:

runuser -u www-data -- ./bin/config set no.such.key 1
runuser -u www-data -- ./bin/config set account.minimum-password-length abc
Usage Exception: Configuration key "no.such.key" is unknown. Use "bin/config list" to list all known keys.
Usage Exception: Value for option "account.minimum-password-length" must be an integer.

⚠️ 注意:bin/config 写入 conf/local/local.json 时要求该文件对执行账号可写。若此前用 root 执行过命令,会报 Local path "conf/local/local.json" is not writable,修复方式是 chown www-data:www-data conf/local/local.json 并 chmod 660。

六、bin/phd:守护进程管理

6.1 启停与状态

phd 的标准负载共 4 类守护进程:仓库拉取、触发器、事实统计、任务处理(4 个池)。启动:

cd /var/www/phorge
runuser -u www-data -- ./bin/phd start

实测回显:

Freeing active task leases...
Freed 0 task leases.
Launching daemons:
(Logs will appear in "/var/tmp/phd/log/daemons.log".)

    (Pool: 1) PhabricatorRepositoryPullLocalDaemon
    (Pool: 1) PhabricatorTriggerDaemon
    (Pool: 1) PhabricatorFactDaemon
    (Pool: 4) PhabricatorTaskmasterDaemon

Done.

查看进程与可用守护进程:

runuser -u www-data -- ./bin/phd status
runuser -u www-data -- ./bin/phd list

实测回显:

PID   Command
24646 php ./phd-daemon
Daemons in library phorge:
    PhabricatorFactDaemon
    PhabricatorRepositoryPullLocalDaemon
    PhabricatorTaskmasterDaemon
    PhabricatorTriggerDaemon

停止:

runuser -u www-data -- ./bin/phd stop

实测回显:

Interrupting process 24646...
Process 24646 exited.
 STOP  Stopped PID 24646 ("php ./phd-daemon")

6.2 重启、日志与调试

restart 等价于 stop + start:

runuser -u www-data -- ./bin/phd restart

实测回显:

Interrupting process 24646...
Process 24646 exited.
 STOP  Stopped PID 24646 ("php ./phd-daemon")
Freeing active task leases...
Freed 0 task leases.
Launching daemons:
(Logs will appear in "/var/tmp/phd/log/daemons.log".)

    (Pool: 1) PhabricatorRepositoryPullLocalDaemon
    (Pool: 1) PhabricatorTriggerDaemon
    (Pool: 1) PhabricatorFactDaemon
    (Pool: 4) PhabricatorTaskmasterDaemon

Done.

log 读取守护进程日志,默认输出全部,建议配合 tail:

runuser -u www-data -- ./bin/phd log | tail -12

实测回显(节选):

Daemon 32 INIT [Wed, 28 Oct 2026 02:24:18 +0800] Starting process.
Daemon 32 ZZZZ [Wed, 28 Oct 2026 02:24:34 +0800] Process is preparing to hibernate for 180 seconds.
Daemon 32 DONE [Wed, 28 Oct 2026 02:24:34 +0800] Process exited normally.
Daemon 32 WAIT [Wed, 28 Oct 2026 02:24:34 +0800] Waiting 180 seconds to restart process.
Daemon 31 INIT [Wed, 28 Oct 2026 02:25:02 +0800] Starting process.
Daemon 31 ZZZZ [Wed, 28 Oct 2026 02:25:02 +0800] Process is preparing to hibernate for 60 seconds.
Daemon 31 DONE [Wed, 28 Oct 2026 02:25:02 +0800] Process exited normally.
Daemon 31 WAIT [Wed, 28 Oct 2026 02:25:02 +0800] Waiting 60 seconds to restart process.

日志级别含义:INIT 启动、ZZZZ 无任务休眠、DONE 正常退出、WAIT 等待重启。出现 EXCEPTION 时按 9.3 定位。

其他两个工作流:

runuser -u www-data -- ./bin/phd launch 2 PhabricatorTaskmasterDaemon
runuser -u www-data -- ./bin/phd debug PhabricatorTaskmasterDaemon
  • launch 2 PhabricatorTaskmasterDaemon 单独启动 2 个任务守护进程,用于临时扩容;
  • debug PhabricatorTaskmasterDaemon 前台运行并输出大量诊断信息,Ctrl+C 退出,适合排查单个守护进程的异常。

⚠️ 注意:托管在 systemd 下时,bin/phd restart 会杀掉 systemd 的主进程,导致 phorge-phd.service 变成 inactive,而新守护进程仍在后台跑。正确做法是 systemctl restart phorge-phd,实测冲突过程见 9.2。

七、bin/aphlict 与 bin/user

7.1 bin/aphlict:通知服务

cd /var/www/phorge
runuser -u www-data -- ./bin/aphlict status

实测回显:

Reading configuration from: <phorge>/conf/aphlict/aphlict.default.json
Aphlict (20533) is running.

启停与重启:

runuser -u www-data -- ./bin/aphlict start
runuser -u www-data -- ./bin/aphlict stop
runuser -u www-data -- ./bin/aphlict restart

发送测试通知(--user 为登录用户名,--message 为正文):

runuser -u www-data -- ./bin/aphlict notify --user root --message 'CLI notify test'

实测回显:

Sent notification.

💡 说明:notify 只是把消息投递到通知服务,用户必须已经打开浏览器并建立 WebSocket 连接才能看到;命令行返回 Sent notification. 仅代表服务端已接收。

7.2 bin/user:账号救援

bin/user 只有三个工作流,用于管理员账号被锁死时的救援:

runuser -u www-data -- ./bin/user help

实测关键输出:

      approve --user username
      Approves a user.

      empower --user username
      Turn a user account into an administrator account.

      enable --user username
      Enable a disabled user account.

实测审批并提权首个账号:

runuser -u www-data -- ./bin/user approve --user root
runuser -u www-data -- ./bin/user empower --user root

实测回显:

 DONE  Approved user account "root".
 DONE  Empowered user account "root".

⚠️ 注意:bin/user enable 对未禁用的账号会返回退出码 77 并提示账号未禁用,这是正常现象,不代表命令失败。Phorge 2026.27 没有 bin/accountadmin,创建账号只能走 Web 注册页,再回到命令行审批与提权。

八、备份、升级与回滚

8.1 逻辑备份:两种方式

方式一:Phorge 自带的 bin/storage dump,一条命令导出全部库:

mkdir -p /var/backups/phorge
cd /var/www/phorge
runuser -u www-data -- ./bin/storage dump > /var/backups/phorge/phorge-storage-20261028.sql
ls -lh /var/backups/phorge/phorge-storage-20261028.sql
gzip -c /var/backups/phorge/phorge-storage-20261028.sql > /var/backups/phorge/phorge-storage-20261028.sql.gz
ls -lh /var/backups/phorge/phorge-storage-20261028.sql.gz

实测回显(首条为文件大小):

-rw-r--r-- 1 root root 1.5M Oct 27 18:26 /var/backups/phorge/phorge-storage-20261028.sql
-rw-r--r-- 1 root root 198K Oct 27 18:26 /var/backups/phorge/phorge-storage-20261028.sql.gz

方式二:用 mysqldump 精确控制参数。先取库清单再一次性传入,避免漏库:

DBS=$(mysql -N -e 'SHOW DATABASES' | grep '^phabricator_')
mysqldump --no-tablespaces --single-transaction --default-character-set=utf8mb4 -u phorge -pq1w2e3r4 --databases $DBS > /var/backups/phorge/phorge-20261028.sql
echo EXIT=$?
ls -lh /var/backups/phorge/phorge-20261028.sql

实测回显:

mysqldump: [Warning] Using a password on the command line interface can be insecure.
EXIT=0
-rw-r--r-- 1 root root 815K Oct 27 18:26 /var/backups/phorge/phorge-20261028.sql

两种方式的差异:

方式覆盖范围优点注意
bin/storage dump应用清单内的库版本兼容,官方维护可能漏历史库,实测 54 vs 56
mysqldump --databasesSHOW DATABASES 全量不漏库,参数可控需自行保证一致性参数

恢复命令(在停机窗口执行,先确认目标实例没有同名库):

mysql -u root -p < /var/backups/phorge/phorge-20261028.sql

⚠️ 注意:恢复会覆盖同名库中的表。本次实验只做了导出与大小校验,未执行覆盖式恢复,避免破坏正在运行的演示环境;生产恢复前务必先做一次当前状态备份。

8.2 附件备份

附件默认落本地磁盘,路径由 storage.local-disk.path 决定:

runuser -u www-data -- ./bin/config get storage.local-disk.path | grep '"value"'
tar -czf /var/backups/phorge/phorge-files-20261028.tar.gz -C /var/www phorge-files
ls -lh /var/backups/phorge/phorge-files-20261028.tar.gz

实测回显(value 行):

      "value": "/var/www/phorge-files",

压缩包大小取决于附件量,本环境附件目录为空,tar 正常生成、退出码为 0。

8.3 升级流程与回滚

标准升级步骤(下面以重新部署同版本 2026.27 为例;跨版本时把命令里的 2026.27 替换为 GitHub 上的目标标签):

# 1. 备份
mysqldump --no-tablespaces --single-transaction -u phorge -pq1w2e3r4 --databases $(mysql -N -e 'SHOW DATABASES' | grep '^phabricator_') > /var/backups/phorge/before-upgrade.sql
tar -czf /var/backups/phorge/before-upgrade-files.tar.gz -C /var/www phorge-files

# 2. 停守护进程,避免升级期间写库
systemctl stop phorge-phd

# 3. 替换源码(老目录改名保留,便于回滚)
mv /var/www/phorge /var/www/phorge.old
tar -xzf /opt/src/phorge-2026.27.tar.gz -C /var/www
mv /var/www/phorge-2026.27 /var/www/phorge
chown -R www-data:www-data /var/www/phorge

# 4. 升级数据库结构
cd /var/www/phorge
runuser -u www-data -- ./bin/storage upgrade --force

# 5. 清理缓存并重启
runuser -u www-data -- ./bin/cache purge --all
systemctl start phorge-phd

⚠️ 注意:本环境只实测了同版本重复执行 bin/storage upgrade --force 的幂等输出(见 4.4),跨版本升级与回滚未实测;命令中的 2026.27 是实值,跨版本时按上一段说明替换。

回滚思路:数据库补丁是单向的,不能靠旧代码回退。必须「换回旧源码目录 + 恢复升级前的数据库备份」:

systemctl stop phorge-phd
rm -rf /var/www/phorge
mv /var/www/phorge.old /var/www/phorge
mysql -u root -p < /var/backups/phorge/before-upgrade.sql
systemctl start phorge-phd

bin/cache purge --all 的真实回显:

Purging "builtin-file" cache...
Purging "changeset" cache...
Purging "general" cache...
Purging "remarkup" cache...
Purging "user" cache...

九、日志与排障

9.1 日志都在哪里

日志路径查看命令
守护进程/var/tmp/phd/log/daemons.logbin/phd log 或 tail -f
systemd 单元journaldjournalctl -u phorge-phd -n 50
Nginx 访问/var/log/nginx/access.logtail -f
Nginx 错误/var/log/nginx/error.logtail -f
PHP-FPM/var/log/php8.1-fpm.logtail -f
MySQL 错误/var/log/mysql/error.logtail -f

实测确认这些文件均存在:

ls -l /var/tmp/phd/log/ /var/log/php8.1-fpm.log /var/log/mysql/error.log
-rw-r----- 1 mysql    adm      4514 Oct 27 17:53 /var/log/mysql/error.log
-rw------- 1 root     root      187 Oct 27 17:52 /var/log/php8.1-fpm.log

/var/tmp/phd/log/:
total 4
-rw-r--r-- 1 www-data www-data 3666 Oct 27 18:26 daemons.log

journalctl 看 systemd 托管状态:

journalctl -u phorge-phd -n 5 --no-pager

实测回显:

Oct 27 18:21:01 phorge phd[24638]: Done.
Oct 27 18:21:01 phorge systemd[1]: Started Phorge daemons (phd).
Oct 27 18:26:26 phorge phd[27831]:  NO DAEMONS  There are no running daemons.
Oct 27 18:26:26 phorge systemd[1]: phorge-phd.service: Deactivated successfully.
Oct 27 18:26:26 phorge systemd[1]: phorge-phd.service: Consumed 1.153s CPU time.

9.2 手工 restart 把 systemd 单元弄成 inactive

现象:执行 bin/phd restart 后,systemctl is-active phorge-phd 返回 inactive,但 bin/phd status 仍有进程:

inactive
PID   Command
27841 php ./phd-daemon

原因:systemd 以 Type=forking 跟踪主进程;bin/phd restart 杀掉主进程后自行拉起新进程,systemd 认为服务已退出。

解决:先停掉手工拉起的进程,再交回 systemd:

cd /var/www/phorge
runuser -u www-data -- ./bin/phd stop
systemctl start phorge-phd
systemctl is-active phorge-phd

实测回显:

Interrupting process 27841...
Process 27841 exited.
 STOP  Stopped PID 27841 ("php ./phd-daemon")
active

恢复后 bin/phd status 会显示新的 systemd 子进程 PID。

9.3 守护进程异常:从日志到根因

runuser -u www-data -- ./bin/phd log | grep -E 'EXCEPTION|ERROR' | tail -5

实测命中一条真实异常:

[28-Oct-2026 02:26:48 Asia/Shanghai] [2026-10-28 02:26:48] EXCEPTION: (Exception) Task "38" encountered a permanent failure and was cancelled. {>} (PhabricatorWorkerPermanentFailureException) Feed story (with key "7701415846629080445") does not exist or could not be loaded.

定位方法:异常里带 Task "38" 与抛出类 PhabricatorWorkerPermanentFailureException,说明是后台任务而非 Web 请求;Feed story ... does not exist 表示任务引用的动态对象已被删除,属数据一致性问题,不影响站点登录与代码评审。清理缓存并重启守护进程后不再复现即可;若持续出现,按对象类型检查对应表的孤儿记录。

9.4 备份报 PROCESS 权限与表空间告警

现象:bin/storage dump 的 stderr 出现:

mysqldump: Error: 'Access denied; you need (at least one of) the PROCESS privilege(s) for this operation' when trying to dump tablespaces

原因:MySQL 8.0 的 mysqldump 默认读取表空间元数据,需要 PROCESS 权限;phorge 账号只有业务库权限。

解决:退出码仍为 0 时备份可用,忽略告警即可;要彻底消除告警,改用 mysqldump --no-tablespaces(8.1 实测无告警、EXIT=0):

mysqldump --no-tablespaces --single-transaction -u phorge -pq1w2e3r4 --databases $(mysql -N -e 'SHOW DATABASES' | grep '^phabricator_') > /var/backups/phorge/phorge-20261028.sql

9.5 Web 500 的三类高频原因

  • Request parameter '__path__' is set, but empty:Nginx 重写写成 __path__=$1,改为 __path__=/$1;
  • Site Not Found:phabricator.base-uri 与实际访问地址不一致,统一地址或补 phabricator.allowed-uris;
  • Unable to load the "Arcanist" library:arcanist/ 未与 phorge/ 并列。

对应的验证命令:

curl -s -o /dev/null -w '%{http_code}\n' -H 'Host: 192.168.1.100:8138' http://127.0.0.1:8138/
runuser -u www-data -- ./bin/config get phabricator.base-uri | grep '"value"'
ls /var/www

实测回显:

302
      "value": "http://192.168.1.100:8138",
arcanist  phorge

新装未登录时 302 跳注册页属正常;登录后同一地址返回 200。

十、注意事项

  1. 账号统一:所有 bin/* 用 runuser -u www-data -- 执行,phd 与 aphlict 拒绝 root 运行。直接 root 执行还会把 conf/local/local.json、/var/tmp/aphlict 的属主改坏。
  2. 托管优先 systemd:phorge-phd、phorge-aphlict 有 systemd 单元时,日常启停只用 systemctl,不要用 bin/phd restart、bin/aphlict restart。
  3. 危险命令先演练:storage upgrade、storage adjust、storage destroy 先加 --dryrun;destroy 生产环境禁止执行。
  4. 备份覆盖全量库:以 SHOW DATABASES 为准,不要只用 bin/storage databases 的 54 个库。
  5. 配置改动分级生效:Web 参数即时生效;phd.*、notification.servers 需重启对应服务。
  6. 升级不可逆:数据库补丁只能向前,回滚必须恢复升级前的库备份。

十一、常见问题

11.1 所有 bin 命令报 Arcanist 缺失

现象:FATAL ERROR: Unable to load the "Arcanist" library.
解决:把同版本的 arcanist 解压到源码同级目录,确认 ls /var/www 输出 arcanist phorge。

11.2 bin/config 报 local.json 不可写

现象:Local path "conf/local/local.json" is not writable.
解决:

chown www-data:www-data /var/www/phorge/conf/local/local.json
chmod 660 /var/www/phorge/conf/local/local.json

11.3 storage upgrade 报 1044 权限不足

现象:#1044: Access denied for user 'phorge'@'localhost' to database 'phabricator_meta_data'
原因:只授权了单个库,Phorge 需要创建全部 phabricator_* 库。
解决:

mysql -e "GRANT ALL PRIVILEGES ON \`phabricator\\_%\`.* TO 'phorge'@'localhost'; FLUSH PRIVILEGES;"
cd /var/www/phorge
runuser -u www-data -- ./bin/storage upgrade --force

11.4 bin/aphlict 启动报目录不可写

现象:Requested path '/var/tmp/aphlict/pid' is not writable.
解决:

mkdir -p /var/tmp/aphlict
chown -R www-data:www-data /var/tmp/aphlict
cd /var/www/phorge
runuser -u www-data -- ./bin/aphlict start

11.5 bin/aphlict 报缺少 ws 模块

现象:Error: Cannot find module 'ws'
解决:

apt-get install -y npm
cd /var/www/phorge/support/aphlict/server
npm install ws --registry=https://registry.npmmirror.com
systemctl restart phorge-aphlict

11.6 bin/user enable 返回 77

现象:Usage Exception: User "root" is not disabled. 并返回 77。
原因:账号本来就可登录,无需启用。
解决:忽略即可;账号被锁时先 bin/user approve --user root,再 bin/user empower --user root。

11.7 站点首页 500 但命令行一切正常

按 9.5 的三类原因逐项排除:重写规则、base-uri、Arcanist。用 curl -H 'Host: 192.168.1.100:8138' 指定 Host 复现,避免把「Host 不匹配」误判为应用故障。

十二、参考链接