Elgg 日常运维手册

Elgg 7.1.2 运维实测手册:plugins:list/upgrade/cron/缓存三命令巡检基线,mariadb-dump+tar 备份与 17/17 表恢复验证,system_log 与通知队列监控,upgrade 幂等空跑与回滚要点,含 plugins:list 静默退出码 2(缺 composer.json)等六条运行期排障实录。

ElggElggMariaDBPHP 应用2026/11/02

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 恢复演练清单

  1. 停应用入口(保留数据库)
  2. mariadb -u elgg -p... elgg < elgg-db-<日期>.sql
  3. 解归档数据目录、chown www-data
  4. 启动应用,php vendor/bin/elgg-cli cache:clear
  5. 登录 + 打开一个已知 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 单体应用,扩容路径按瓶颈分三层(本环境为单实例,以下为架构性建议,未做压力实测,如实标注):

  1. 应用层:多副本共享同一代码目录与数据目录(网络文件系统需支持 POSIX 随机读写),前置负载均衡;会话与缓存都在数据库/数据目录中,天然可多实例。
  2. 数据库层:elgg_entities+elgg_metadata 是主要热点,优先加内存与索引巡检;读写分离可用 MariaDB 复制,但 Elgg 无原生只读库路由,需代理层(如 MaxScale)承接。
  3. 缓存层:视图/系统缓存全部落数据目录文件系统,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 一次。

九、参考链接

Elgg 日常运维手册 - Quzuo