Elgg 日常运维手册
Elgg 7.1.2 运维实测手册:plugins:list/upgrade/cron/缓存三命令巡检基线,mariadb-dump+tar 备份与 17/17 表恢复验证,system_log 与通知队列监控,upgrade 幂等空跑与回滚要点,含 plugins:list 静默退出码 2(缺 composer.json)等六条运行期排障实录。
Elgg 日常运维手册
目标:给出 Elgg 7.1.2 站点的日常运维操作手册——巡检项与阈值、备份恢复(实测可还原)、系统日志与 cron 监控、升级回滚流程、以及六条运行期排障实录。全部命令与回显在 7.1.2 真实站点实测通过;命令默认在**站点根目录(应用运行环境)**执行,部署形态见《部署篇》,在编排环境中进入对应服务执行即可。
一、环境信息
- Elgg:7.1.2(PHP 8.3 + MariaDB 11.8.9,Apache 2.4 重写开启)
- 站点根:
/var/www/html(含vendor/bin/elgg-cli) - 数据目录:
/var/www/elgg-data(caches、上传文件、cron 状态) - 数据库:
elgg库,实测 17 张表 - CLI 运行用户:与 Web 相同的低权限用户(
www-data),命令形如php vendor/bin/elgg-cli <子命令> - 演示账号:admin / q1w2e3r4q1w2e3r4
二、日常巡检
2.1 CLI 与数据库快检
# 插件状态总表(实测 31 行:30 内置 + 1 自研)
php vendor/bin/elgg-cli plugins:list
# 升级是否有待执行项
php vendor/bin/elgg-cli upgrade:list # 输出 Completed upgrades 即无欠账
# 数据库基线(实测回显)
mariadb -u elgg -pq1w2e3r4 elgg -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='elgg'; SELECT COUNT(*) FROM elgg_entities WHERE deleted='no'; SELECT COUNT(*) FROM elgg_queue; SELECT COUNT(*) FROM elgg_system_log;"
# 17
# 53
# 0
# 425
判读:表数应为 17(版本迁移欠账会加表);elgg_queue 持续大于 0 说明 cron 通知投递停摆;elgg_system_log 行数随保留期波动。
2.2 磁盘与目录
du -sh /var/www/elgg-data <数据库数据目录>
# 152K data
# 164M db
关注三处:上传文件(elgg-data/<owner>/<guid>/file)、缓存(elgg-data/caches/)、数据库目录。缓存异常膨胀通常是 simplecache/views 反复重建,见 2.3。
2.3 缓存三命令(实测回显)
php vendor/bin/elgg-cli cache:invalidate # The site's caches have been invalidated
php vendor/bin/elgg-cli cache:purge # The site's caches have been purged
php vendor/bin/elgg-cli cache:clear # The site's caches have been cleared
语义区别:invalidate 只标记失效(下次请求重建)、purge 清空内容、clear 失效+清空。改插件配置、换语言包、视图不更新时先 cache:clear。
2.4 cron 心跳
php vendor/bin/elgg-cli cron
实测输出为分级日志(节选):
[2026-11-02T01:20:43.228165+00:00] CRON.NOTICE: Cron jobs for "minute" completed at Mon, 02 Nov 2026 01:20:43 +0000
[2026-11-02T01:20:43.228889+00:00] CRON.NOTICE: Starting Elgg\SystemLog\Logger::listen
[2026-11-02T01:20:43.229009+00:00] CRON.NOTICE: Finished Elgg\GarbageCollector\CronRunner
[2026-11-02T01:20:43.229128+00:00] CRON.NOTICE: Finished Elgg\Notifications\Events\Enqueue
调度状态落盘在数据目录 1/1/cron/*.complete(实测存在 daily.complete、fifteenmin.complete 等时间戳文件)。生产 crontab 建议:
* * * * * cd /var/www/html && sudo -u www-data php vendor/bin/elgg-cli cron --interval minute >> /var/log/elgg-cron.log 2>&1
*/5 * * * * cd /var/www/html && sudo -u www-data php vendor/bin/elgg-cli cron --interval five_minutes >> /var/log/elgg-cron.log 2>&1
0 * * * * cd /var/www/html && sudo -u www-data php vendor/bin/elgg-cli cron --interval hourly >> /var/log/elgg-cron.log 2>&1
0 3 * * * cd /var/www/html && sudo -u www-data php vendor/bin/elgg-cli cron --interval daily >> /var/log/elgg-cron.log 2>&1
三、备份与恢复
3.1 备份(实测)
Elgg 完整备份 = 数据库 + 数据目录 + 站点配置(settings.php 在代码目录内,随代码备份):
# 1. 数据库逻辑备份
mariadb-dump -u elgg -pq1w2e3r4 elgg | gzip > elgg-db-$(date +%F).sql.gz
# 产物实测:elgg-db-2026-11-02.sql.gz 15,243 字节,含 17 条 CREATE TABLE
zcat elgg-db-2026-11-02.sql.gz | head -4
# /*M!999999\- enable the sandbox mode */
# -- MariaDB dump 10.20-11.8.9-MariaDB, for debian-linux-gnu (x86_64)
# -- Host: localhost Database: elgg
# 2. 数据目录归档(上传文件+缓存+插件状态)
tar czf elgg-data-$(date +%F).tar.gz /var/www/elgg-data
# 产物实测:elgg-data-2026-11-02.tar.gz 68,485 字节
一致性提示:逻辑备份与文件备份之间新产生的实体,其文件可能不在归档内;停写窗口内执行,或先备份数据目录再备份数据库。
3.2 恢复验证(实测)
把备份导入临时库验证可用性(不覆盖生产库):
mariadb -u root -pq1w2e3r4 -e "CREATE DATABASE IF NOT EXISTS elgg_restore;"
zcat elgg-db-2026-11-02.sql.gz | mariadb -u root -pq1w2e3r4 elgg_restore
mariadb -u root -pq1w2e3r4 -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='elgg_restore';"
# 17
实测恢复表数 17,与原库 information_schema 计数一致,备份可用。确认无误后 DROP DATABASE elgg_restore;。
数据目录恢复:tar xzf elgg-data-<日期>.tar.gz -C / 后务必修正属主(排障实录 #3):chown -R www-data:www-data /var/www/elgg-data。
3.3 恢复演练清单
- 停应用入口(保留数据库)
mariadb -u elgg -p... elgg < elgg-db-<日期>.sql- 解归档数据目录、chown www-data
- 启动应用,
php vendor/bin/elgg-cli cache:clear - 登录 + 打开一个已知 GUID 的文件页验证(实测样例:
/file/view/51/test-upload)
四、监控与告警
- 站内系统日志:system_log 插件(默认激活)把实体级动作写
elgg_system_log(实测 425 条),管理页admin/administer_utilities/logbrowser可按对象 GUID/动作过滤,实测条目含login:user、login:before:user、create:after:relationship、dequeue:notifications,字段为时间/IP/对象/GUID/动作。保留期由插件设置period(默认 never,cron 的Elgg\SystemLog\Cron::rotateLogs/deleteLogs按设置轮转删除)。 - 进程日志:应用日志走标准输出(编排环境用日志驱动采集),关键级别看
ELGG.ERROR/CRON.NOTICE。cron 停摆告警:监控elgg_queue行数(>0 持续增长)与1/1/cron/*.complete时间戳新鲜度。 - Web 可用性:对
/account/login或首页做 HTTP 200 探测即可(实测首页标题All Site Activity : Elgg Community)。 - 升级欠账:
upgrade:list输出中出现非 Completed 段即需处理。
五、扩容缩容
Elgg 是 PHP 单体应用,扩容路径按瓶颈分三层(本环境为单实例,以下为架构性建议,未做压力实测,如实标注):
- 应用层:多副本共享同一代码目录与数据目录(网络文件系统需支持 POSIX 随机读写),前置负载均衡;会话与缓存都在数据库/数据目录中,天然可多实例。
- 数据库层:
elgg_entities+elgg_metadata是主要热点,优先加内存与索引巡检;读写分离可用 MariaDB 复制,但 Elgg 无原生只读库路由,需代理层(如 MaxScale)承接。 - 缓存层:视图/系统缓存全部落数据目录文件系统,
cacheroot可指到本地 SSD;OPcache 必开。
缩容即撤副本,无状态迁移需求;数据库缩容走常规主从切换。
六、升级与回滚
6.1 升级流程
# 0. 完整备份(第三节)
# 1. 替换代码:解压新版发行包到临时目录,保留 elgg-config/ 与 mod/ 后覆盖引擎与 vendor
# 2. 执行升级(实测空跑回显,幂等)
php vendor/bin/elgg-cli upgrade
# All Done. Took 0.0016s
# System upgrades have been executed
# 3. 清缓存
php vendor/bin/elgg-cli cache:clear
# 4. 验证:登录、开一个既有 GUID 页面、plugins:list 无 invalid
upgrade 内部走 Phinx 迁移(实测输出 using adapter mysql / using database elgg / using table prefix elgg_),逐条迁移可回溯,跨大版本前先读官方 upgrade notes。
6.2 回滚
代码回滚 = 换回旧版发行包;数据回滚 = 3.2 的恢复流程(导入升级前备份 + 解归档 + chown + cache:clear)。迁移表结构不向后兼容,回滚必须连同数据库一起回,不要只回代码。
七、故障排查手册
以下六条为运行期实测排障实录(部署期七条见《部署篇》第十一节)。
7.1 plugins:list 退出码 2 且零输出(静默崩溃)
现象:php vendor/bin/elgg-cli plugins:list 无任何输出、echo $? 得 2;plugins:activate <新插件> 报 <id> is an invalid plugin ID;REST 自定义方法报 Method call '...' has not been implemented.。
定位过程:源码 Elgg/Cli/PluginsListCommand.php 第 67 行 catch (PluginException $ex) { return self::INVALID; } 吞掉异常不打印。临时在 catch 里加一行输出异常信息,立即暴露真因:
DIAG: Elgg\Exceptions\Plugin\ComposerException: Missing composer.json for plugin ID hello_world (guid 53)
根因:Elgg 7 起每个插件目录必须含 composer.json,且其 name 项目段必须与目录名一致(Elgg/Plugin/Composer.php:59 assertPluginId,否则报 This plugin's directory must be renamed to ...)。补齐后:
php vendor/bin/elgg-cli plugins:list # 正常输出 31 行表格,RC=0
php vendor/bin/elgg-cli plugins:activate hello_world
# Activating plugins
# 1/1 [============================] 100%
7.2 新插件不被识别
手工放入 mod/ 的插件首次不会被数据库感知,需刷新插件实体(实测在补 composer.json 后列表即出现 guid 53):
php vendor/bin/elgg-cli plugins:list --refresh
(--refresh 触发 generateEntities();若插件本身非法,刷新同样会被 7.1 的静默坑吞掉,先确保 composer.json 合规。)
7.3 站点 500:缓存目录不可写
现象日志:ELGG.ERROR ... PhpfastcacheIOException: The directory /var/www/elgg-data/caches/fastcache/boot_cache/Files could not be created。
处置:数据目录属主改回 Web 运行用户:chown -R www-data:www-data /var/www/elgg-data,再 cache:clear。备份恢复后忘 chown 是最常见触发场景。
7.4 REST 调用报 status:-32 / -20
实测对照表(详见 《API 篇》):
| 响应 | 含义 | 处置 |
|---|---|---|
{"status":-32,"message":"Method call failed the API Authentication"} | 方法要求 api_key/HMAC 认证而未带 | 按 API 篇补 X-Elgg-* 头 |
{"status":-32,"message":"HMAC is invalid. <你的值> != [calc]<服务端计算值>"} | 签名串拼接或 urlencode 环节不对 | 核对 time.nonce.key.QUERY_STRING 顺序与 base64 后 urlencode |
{"status":-20,"message":"User could not be authenticated"} | API 认证过了,缺 auth_token 参数 | 先 POST:auth.gettoken 换 token |
7.5 HMAC 重放与时间漂移
同一签名重复提交报 SecurityException:DupePacket(服务端 25 小时缓存防重放,Hmac.php:139 允许 ±90000 秒时钟漂移)。排错时每次重试必须换 nonce 重新签名;宿主机与应用时钟偏差大先对时。
7.6 日志文件 tail 挂起
Apache error.log 若被链接到标准输出(官方 php 镜像默认行为),进入应用环境 tail -f 会阻塞无输出。改从编排层日志驱动取(命令见部署篇第十节)。
八、常见问题
Q1: 忘记密码怎么办?
A: 用 CLI 以管理员身份重置或走站内邮件重置。CLI 支持 -u/--as 指定用户执行子命令;无邮件服务器时,直接改库:更新 elgg_users_entity 对应实体的密码哈希需经 Elgg API(推荐 php vendor/bin/elgg-cli 环境内调用 _elgg_services()->userAuthenticationService),最稳妥是备份后重建管理员账号。
Q2: 通知邮件发不出去?
A: 默认未配 SMTP 时通知只入 elgg_queue,由 cron 的 Enqueue/投递任务处理;配 settings.php 的 mail_* 键族指向 SMTP 后验证:建一条站内信,看 elgg_queue 是否先增后清零。
Q3: 改完 elgg-plugin.php 不生效?
A: 插件配置在激活时快照进数据库。plugins:deactivate <id> && plugins:activate <id> 重载,再 cache:clear。
Q4: plugins:list 显示某插件 Inactive 但后台点激活报依赖错误?
A: CLI 等价操作 plugins:activate <id>:<priority> 支持带优先级;冲突插件用 force 路径处理(CLI activate 会先解冲突再激活)。
Q5: 数据目录能挪走吗?
A: 能。settings.php 的 dataroot 改成新路径并同步 cacheroot,注意保持 www-data 可写;挪动后 cache:clear 一次。