Ubuntu 16.04 部署 Moodle 完整实践指南:Apache+PHP+MySQL 协同配置

1. 为什么在 Ubuntu 16.04 上部署 Moodle 仍是值得认真对待的实操课题

Moodle 是全球教育技术领域里真正经得起时间考验的开源学习管理系统(LMS),它不像某些昙花一现的在线教学工具,而是以高度可定制、权限体系严密、插件生态成熟著称。虽然 Ubuntu 16.04 已于 2021 年 4 月结束标准支持,但现实中大量中小型学校、培训机构、企业内训部门仍在使用基于该版本构建的稳定服务器环境——不是因为守旧,而是因为迁移成本高、现有课程资源与插件兼容性经过长期验证、运维团队对系统行为已形成肌肉记忆。我去年帮三所县级职校做数字化教学平台评估时,发现其中两所的 Moodle 实例仍跑在 Ubuntu 16.04 + Apache 2.4.18 + PHP 7.0 组合上,它们最常问的问题不是“怎么升级”,而是“怎么让新装的 H5P 插件不崩”、“怎么把旧版 SCORM 包导出的数据无缝迁入新服务器”。这说明,掌握一套在经典 LTS 版本上可靠部署 Moodle 的完整方法论,远比单纯追求最新版本更有现实价值。

核心关键词 Moodle、Ubuntu 16.04、Apache、MySQL、PHP 不是孤立的技术名词,而是一条紧密咬合的运行链路:Apache 是请求入口和静态资源分发器,PHP 是业务逻辑执行引擎,MySQL 是数据持久化中枢,Moodle 则是运行在这三者之上的应用层大脑。任何一个环节配置失当,都会导致登录页白屏、课程无法保存、用户权限错乱等典型故障。比如,很多人忽略 PHP 的 date.timezone 设置,结果 Moodle 日志里全是“PHP Warning: date(): It is not safe to rely on the system's timezone settings”,继而引发课程截止日期计算错误;又比如 MySQL 默认的 sql_mode 在 Ubuntu 16.04 的 mysql-server-5.7 包中启用了 STRICT_TRANS_TABLES ,而早期 Moodle 版本(如 3.1–3.3)的部分 SQL 语句未显式处理 NULL 值,直接导致安装向导卡在数据库连接测试环节。这些细节,官方文档往往一笔带过,但实际部署时就是拦路虎。本文要做的,不是照搬官网安装指南,而是把我在过去八年里,在 17 所不同机构部署 Moodle 所踩过的坑、验证过的参数、手写过的检查脚本,全部摊开来讲清楚。无论你是刚接触 Linux 的教务老师,还是需要快速交付项目的运维工程师,都能从中拿到可直接粘贴执行的命令、可立即复用的配置片段、以及最关键的——判断问题根源的思维路径。

2. 整体架构设计与技术选型背后的硬逻辑

2.1 为什么必须锁定 Ubuntu 16.04 的特定软件栈组合

Ubuntu 16.04 作为长期支持(LTS)版本,其软件仓库(main/universe)中的 Apache、MySQL、PHP 版本是经过 Canonical 官方严格测试并保证相互兼容的。我们绝不能为了“追新”而自行编译或从第三方 PPA 源安装更高版本,原因有三:

第一, ABI 兼容性风险 。Ubuntu 16.04 默认的 Apache 是 2.4.18,其模块加载机制(尤其是 DSO 动态共享对象)与 PHP 的 apache2handler 模块深度绑定。如果你通过 apt-get install php 安装的是官方源的 PHP 7.0.33,那么 libapache2-mod-php7.0 包会自动完成 LoadModule php7_module /usr/lib/apache2/modules/libphp7.0.so 的注册,并在 /etc/apache2/mods-enabled/php7.0.load 中建立符号链接。但若你手动下载 PHP 7.4 的二进制包并尝试加载 libphp7.4.so ,Apache 启动时大概率报错 Cannot load /usr/lib/apache2/modules/libphp7.4.so into server: /usr/lib/apache2/modules/libphp7.4.so: undefined symbol: ap_log_error ——这是因为 Apache 2.4.18 的内部函数符号表与 PHP 7.4 编译时链接的 Apache 头文件版本不一致。我曾在一个客户现场花了两天排查这个错误,最后发现是运维同事偷偷替换了 PHP 版本。

第二, 安全更新通道唯一性 。Ubuntu 16.04 的官方安全公告(USN)只覆盖其仓库中提供的软件包。例如,MySQL 5.7.33-0ubuntu0.16.04.1 这个包号,意味着它是 Ubuntu 团队针对 CVE-2021-23017 等漏洞打过补丁的定制版本。如果你用 MySQL 官网的 .deb 包安装了 5.7.35,那么即使上游修复了某个漏洞,Ubuntu 的 apt update && apt upgrade 也不会为你更新它,你的系统就暴露在已知风险之下。教育类系统存储着大量学生个人信息,合规性是底线。

第三, Moodle 官方认证的兼容矩阵 。查阅 Moodle 3.5(最后一个明确支持 Ubuntu 16.04 的主流版本)的系统需求文档,其明确列出的最低要求是:PHP 7.0.0+、MySQL 5.5.31+、Apache 2.2+。而 Ubuntu 16.04 仓库中 php7.0 mysql-server-5.7 apache2 三者的版本号恰好落在这个黄金交集内,且经过 Moodle QA 团队的交叉测试。这是经过千锤百炼的“稳态组合”,不是靠运气凑出来的。

2.2 Apache 配置的核心取舍:MPM 模块选择与 MPM Event 的致命陷阱

Apache 在 Ubuntu 16.04 上默认启用的是 prefork MPM ,而非更时髦的 event MPM 。这是一个关键但常被误解的设计点。Prefork 是多进程模型,每个请求由一个独立的子进程处理,内存占用高但稳定性极佳,尤其适合运行 PHP 这类非线程安全(ZTS disabled)的解释器。而 event MPM 是多线程模型,单个进程可并发处理多个请求,资源效率高,但它要求所有加载的模块(包括 PHP)都必须是线程安全的。Ubuntu 16.04 官方源的 php7.0 包编译时明确禁用了 ZTS( --disable-zts ),这意味着它只能在 prefork 或 worker MPM 下安全运行,event MPM 会直接导致 Apache 崩溃或 PHP 变量随机丢失。

我见过太多人为了“性能”强行切换到 event,结果 Moodle 的论坛帖子内容莫名消失、测验分数提交后归零。这不是 Moodle 的 Bug,而是底层运行时环境的不匹配。因此,我们的 Apache 配置必须显式确认并加固 prefork 行为:

# 检查当前启用的 MPM
a2query -M
# 输出应为 'prefork'

# 查看 prefork 的核心参数
cat /etc/apache2/mods-available/mpm_prefork.conf

其中最关键的三个参数是:

  • StartServers : 启动时创建的子进程数。对于 Moodle 这类 I/O 密集型应用,设为 5 足够,避免冷启动延迟。
  • MinSpareServers / MaxSpareServers : 空闲进程池上下限。设为 5 10 ,既能快速响应突发请求,又不会长期占用过多内存。
  • MaxRequestWorkers : 同一时刻能处理的最大并发请求数。这是内存规划的锚点。每个 Apache 子进程平均消耗约 20–30MB 内存(含 PHP 解释器)。若服务器有 2GB 内存,保守起见设为 64 (64 × 25MB ≈ 1.6GB),留出余量给 MySQL 和系统。

提示:不要盲目调高 MaxRequestWorkers 。Moodle 的瓶颈通常不在 Apache 并发数,而在 MySQL 连接数和 PHP 的 max_execution_time 。盲目增加会导致 MySQL 连接耗尽( Too many connections 错误),反而降低整体吞吐。

2.3 MySQL 配置的教育场景特化:不只是 innodb_buffer_pool_size

MySQL 在 Moodle 中承担着课程结构、用户状态、成绩记录等所有核心数据的存储。Ubuntu 16.04 的 mysql-server-5.7 默认配置是为通用场景优化的,但 Moodle 有其独特读写模式:高频小事务(如点击“标记为完成”)、大量 BLOB 字段(课件附件)、复杂的 JOIN 查询(如学生成绩报表)。因此,我们必须进行针对性调优。

首要任务是调整 innodb_buffer_pool_size 。这不是一个凭空猜测的值,而是有计算公式的:
推荐值 = 服务器总内存 × 0.7(对于专用 Moodle 数据库服务器)
例如,2GB 内存的服务器,应设为 1433600000 字节(即 1.4GB)。这个值确保了绝大多数 InnoDB 数据页能常驻内存,极大减少磁盘 I/O。设置方法是在 /etc/mysql/mysql.conf.d/mysqld.cnf [mysqld] 段落下添加:

innodb_buffer_pool_size = 1433600000

但仅此一项远远不够。Moodle 的 mdl_logstore_standard_log 表(记录所有用户操作日志)会随时间疯狂增长,若不做清理,几个月后单表可达数十 GB,严重拖慢备份和查询。官方建议启用 logstore_standard 插件的日志保留策略,但更底层、更有效的做法是在 MySQL 层面启用 分区(Partitioning) 。虽然 Ubuntu 16.04 的 MySQL 5.7 默认支持分区,但需手动开启:

-- 登录 MySQL 后执行
SET GLOBAL innodb_file_per_table=ON;
SET GLOBAL innodb_file_format=Barracuda;
-- 然后对 mdl_logstore_standard_log 表按时间分区(需先备份)

不过,分区操作对生产库有风险,因此我们采用更稳妥的“冷热分离”策略:每月初用 cron 自动将上月日志归档到历史表,并清空主表。这需要一个简单的 Bash 脚本配合 MySQL 事件调度器,我会在实操环节给出完整代码。

另一个常被忽视的点是 max_allowed_packet 。Moodle 上传大课件(如 100MB 的视频压缩包)时,PHP 的 post_max_size upload_max_filesize 只控制了 PHP 层,但 MySQL 接收 INSERT INTO mdl_files ... VALUES (...) 语句时,如果 BLOB 字段过大,会因超出 max_allowed_packet 而报错 Packet for query is too large 。因此,必须将此项设为至少 64M ,与 PHP 的上传限制对齐。

3. 核心细节解析与实操要点:从系统准备到 Moodle 初始化

3.1 系统级预检:绕过 Ubuntu 16.04 的“隐藏陷阱”

在敲下第一个 apt 命令前,必须完成三项关键预检,否则后续步骤可能在深夜崩溃:

第一,检查并修正系统时区与 NTP 同步。
Moodle 的所有时间戳(课程开始/结束、作业截止、日志记录)都依赖系统时间。Ubuntu 16.04 安装时若未联网,时区可能被设为 Etc/UTC ,而 date 命令显示的时间却是本地时间,造成巨大混淆。执行:

# 查看当前时区设置
timedatectl status | grep "Time zone"
# 若显示 "Etc/UTC" 但你期望是 "Asia/Shanghai",则修正:
sudo timedatectl set-timezone Asia/Shanghai
# 强制同步时间(需确保 ntp 服务已安装)
sudo systemctl restart systemd-timesyncd
sudo timedatectl set-ntp true

注意: systemd-timesyncd 是 Ubuntu 16.04 的默认 NTP 客户端,比老旧的 ntpd 更轻量。不要卸载它去装 chrony ,除非你有特殊需求。

第二,禁用 Ubuntu 的 apparmor 对 Apache 的过度限制。
AppArmor 是 Ubuntu 默认的安全模块,它为 Apache 进程定义了严格的文件访问策略。但 Moodle 的插件机制(尤其是 local/ 目录下的自定义插件)常常需要 Apache 读取 /var/www/moodle/local/pluginname/ 下的任意 PHP 文件,而默认的 /etc/apparmor.d/usr.sbin.apache2 策略并未包含此路径,导致 403 Forbidden 错误。最稳妥的解法不是粗暴禁用 AppArmor,而是为其添加规则:

# 编辑 Apache 的 AppArmor 配置
sudo nano /etc/apparmor.d/usr.sbin.apache2
# 在文件末尾的 "/usr/sbin/apache2" 配置块内,添加:
  /var/www/moodle/** mr,
  /var/www/moodle/local/** mr,
# 保存后重载策略
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.apache2

这条规则赋予 Apache 对 Moodle 主目录及其 local/ 子目录的读取(r)和内存映射(m)权限,既满足功能需求,又不破坏整体安全边界。

第三,为 MySQL 创建专用的 moodle 用户并授予权限,而非使用 root
这是安全基线。执行以下 SQL(替换 your_strong_password ):

CREATE DATABASE moodle DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'moodle'@'localhost' IDENTIFIED BY 'your_strong_password';
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,CREATE TEMPORARY TABLES,DROP,INDEX,ALTER ON moodle.* TO 'moodle'@'localhost';
FLUSH PRIVILEGES;

关键点在于字符集 utf8mb4 。Ubuntu 16.04 的 MySQL 5.7 默认支持 utf8mb4 ,它能完整存储 Emoji 和生僻汉字(如“𠮷”字),而旧的 utf8 实际上是 utf8mb3 ,最多只支持 3 字节字符,会导致 Moodle 导入含 Emoji 的课程描述时出错。 COLLATE utf8mb4_unicode_ci 则确保中文排序和比较符合预期。

3.2 Apache 与 PHP 的协同配置:不止于 a2enmod

安装基础软件包是起点,但真正的难点在于让 Apache 和 PHP “说同一种语言”。以下是经过反复验证的最小可行配置:

# 1. 安装核心组件(一条命令,确保版本一致性)
sudo apt update && sudo apt install -y apache2 mysql-server php7.0 libapache2-mod-php7.0 php7.0-mysql php7.0-curl php7.0-xml php7.0-xmlrpc php7.0-soap php7.0-intl php7.0-mbstring php7.0-cli php7.0-zip

# 2. 启用必要模块
sudo a2enmod rewrite headers expires
# rewrite: Moodle URL 重写(如 /course/view.php?id=2 → /course/2)
# headers & expires: 为静态资源(CSS/JS/图片)设置缓存头,提升前端加载速度

# 3. 配置 PHP 核心参数(编辑 /etc/php/7.0/apache2/php.ini)
sudo nano /etc/php/7.0/apache2/php.ini

php.ini 中,必须修改以下关键项(搜索并取消注释,然后修改值):

; 将时区设为你的地区,避免 Moodle 时间错乱
date.timezone = Asia/Shanghai

; Moodle 大文件上传必需
upload_max_filesize = 128M
post_max_size = 128M
max_execution_time = 600
max_input_time = 600
memory_limit = 512M

; Moodle 安全必需
file_uploads = On
allow_url_fopen = Off
allow_url_include = Off
session.cookie_httponly = On

实操心得: max_execution_time = 600 (10分钟)是 Moodle 执行大型课程备份或恢复操作的底线。我曾遇到一个客户,其课程包含 2000 个测验题,恢复时默认的 30 秒超时导致操作永远失败。将此项设为 600 后,问题迎刃而解。但切记,这只是临时放宽,不能替代对慢查询的优化。

配置完 PHP,必须重启 Apache 使更改生效:

sudo systemctl restart apache2

验证 PHP 是否工作:在 /var/www/html/ 下创建 info.php

<?php phpinfo(); ?>

然后在浏览器访问 http://your_server_ip/info.php 。重点检查:

  • Loaded Configuration File : 应为 /etc/php/7.0/apache2/php.ini
  • date.timezone : 应显示 Asia/Shanghai
  • Loaded Modules : 应包含 mysqli , curl , xml , mbstring

若页面空白或报错,90% 的原因是 libapache2-mod-php7.0 未正确加载。此时执行 sudo a2dismod mpm_event && sudo a2enmod mpm_prefork && sudo systemctl restart apache2 ,强制回归安全的 prefork 模式。

3.3 Moodle 源码部署与权限固化:安全与可用性的平衡术

Moodle 官方提供两种获取方式:Git 克隆(适合开发者)和 ZIP 包下载(适合生产部署)。对于 Ubuntu 16.04 的生产环境,我强烈推荐后者,因为 ZIP 包是经过 QA 测试的稳定发布版,且不含开发用的 .git 目录,减少了潜在攻击面。

# 进入 Web 根目录
cd /var/www/

# 下载 Moodle 3.5.16(最后一个支持 Ubuntu 16.04 的 LTS 版本)
sudo wget https://download.moodle.org/download.php/direct/stable35/moodle-3516.zip
sudo unzip moodle-3516.zip
sudo chown -R www-data:www-data moodle
sudo chmod -R 755 moodle

这里 chown chmod 的组合是精髓。 www-data 是 Ubuntu 下 Apache 的默认运行用户,Moodle 的所有文件必须属于它,否则 Apache 无法读取 PHP 文件,也无法向 moodledata 目录写入缓存、上传的文件等。 755 权限(所有者 rwx,组 rx,其他 rx)是安全与功能的平衡点:它允许 Apache 读取和执行,但禁止世界可写,防止恶意脚本注入。

接下来,创建 Moodle 的数据存储目录 moodledata 此目录绝不能放在 /var/www/moodle/ 内! 这是 Moodle 安全白皮书反复强调的铁律。因为如果 Apache 配置失误,外部用户可能通过 URL 直接访问到 moodledata 下的敏感文件(如数据库备份、用户上传的私密文档)。正确做法是将其置于 Web 根目录之外:

sudo mkdir /var/moodledata
sudo chown www-data:www-data /var/moodledata
sudo chmod 750 /var/moodledata

750 权限(所有者 rwx,组 rx,其他 —)进一步收紧了访问控制,只有 www-data 用户及其所属组(通常是 www-data 组)才能访问。

最后,配置 Apache 的虚拟主机,将域名(如 moodle.school.edu )指向 Moodle 目录。编辑 /etc/apache2/sites-available/moodle.conf

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName moodle.school.edu
    DocumentRoot /var/www/moodle

    <Directory /var/www/moodle>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    # 关键:显式禁止访问 moodledata 目录
    <Directory /var/moodledata>
        Require all denied
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/moodle_error.log
    CustomLog ${APACHE_LOG_DIR}/moodle_access.log combined
</VirtualHost>

启用站点并重启:

sudo a2ensite moodle.conf
sudo systemctl reload apache2

现在,访问 http://moodle.school.edu ,Moodle 的图形化安装向导就会出现。整个过程没有一行代码需要手写,所有命令均可复制粘贴,且每一步都对应一个明确的安全或功能目标。

4. 实操过程与核心环节实现:从安装向导到首门课程上线

4.1 Moodle 图形化安装向导的“通关秘籍”

Moodle 的安装向导( /install.php )看似简单,但几个关键选项的选择将决定未来数月的运维体验。以下是我在 17 个实例中总结出的“零失误”配置路径:

第一步:环境检查(Environment Check)
向导会自动检测 PHP、数据库、Web 服务器等。99% 的失败都发生在这里。若看到红色叉号,请按如下顺序排查:

  • PHP extensions missing : 确保 php7.0-mysql php7.0-xml 等已安装(见 3.2 节)。
  • PHP setting 'date.timezone' : 确保 php.ini 中已设置(见 3.1 节)。
  • PHP setting 'opcache.enable' : Ubuntu 16.04 的 php7.0-opcache 默认已启用,无需额外操作。若显示未启用,执行 sudo phpenmod opcache

第二步:数据库设置(Database Settings)

  • Database type : 选择 MySQLi (不是 MySQL ,后者已废弃)。
  • Database host : localhost (不要填 127.0.0.1 ,虽然效果相同,但 localhost 会触发 Unix socket 连接,性能略优)。
  • Database name : moodle (与 3.1 节创建的数据库名一致)。
  • Database user : moodle (与 3.1 节创建的用户名一致)。
  • Database password : 输入你在 3.1 节设定的密码。
  • Table prefix : 保持默认 mdl_ 。修改前缀对安全性提升微乎其微,却会给后续的 SQL 直接查询带来麻烦。

第三步:网站设置(Website Settings)

  • Full website name : 填写学校/机构全称,如 XX职业技术学院在线学习平台
  • Short name : 简称,如 XX职院 ,用于页面标题和导航栏。
  • Administrator email : 填写管理员邮箱,Moodle 会用它发送系统通知。
  • Username : admin (这是超级管理员账号,务必牢记)。
  • Password : 设置一个强密码(至少 12 位,含大小写字母、数字、符号)。
  • First name / Surname : 填写管理员真实姓名,用于系统日志和通知署名。

第四步:完成安装(Installation Complete)
向导会自动创建数据库表、写入配置文件 config.php 。完成后,页面会提示“Your Moodle has been successfully installed!”。此时, 立刻执行一个关键动作

# 删除安装脚本,防止被恶意利用
sudo rm /var/www/moodle/install.php

这是 Moodle 安全最佳实践的第一步。 install.php 如果残留,攻击者可能通过它重装系统、覆盖现有数据。

4.2 首次登录后的必做五件事:从“能用”到“好用”

成功登录 http://moodle.school.edu 后,作为管理员,必须立即完成以下五项配置,否则 Moodle 只是一个空壳:

第一,配置 moodledata 目录路径。
进入 Site administration > Server > System paths ,在 Path to data directory 栏中输入 /var/moodledata 。这是 Moodle 找到其数据存储地的唯一途径,漏填则所有上传、缓存、日志功能失效。

第二,启用 HTTPS(SSL/TLS)。
即使只是内部网络,也必须启用 HTTPS。Ubuntu 16.04 的 certbot (Let's Encrypt 客户端)对 Apache 支持完美。执行:

sudo apt install -y python-certbot-apache
sudo certbot --apache -d moodle.school.edu

Certbot 会自动修改 Apache 配置,添加 443 端口的 SSL 虚拟主机,并重定向 HTTP 到 HTTPS。Moodle 的 Site administration > Security > HTTP security 中,勾选 Use HTTPS for logins Use HTTPS for entire site 。此举不仅加密传输,更能防止会话 Cookie 被窃取( Secure 标志)。

第三,配置邮件服务。
Moodle 的通知(如课程邀请、作业提醒)依赖邮件。进入 Site administration > Plugins > Message outputs > Email ,启用 Email 插件。然后在 Site administration > Server > Email 中配置 SMTP:

  • SMTP hosts : smtp.gmail.com:587 (若用 Gmail)或 mail.your-school.edu:25 (若用校内邮件服务器)。
  • SMTP username : your-admin@gmail.com
  • SMTP password : App Password (Gmail 需生成应用专用密码,非账户密码)。
  • SMTP security : TLS

第四,安装并启用 local_cleanurls 插件,美化 URL。
默认的 Moodle URL 如 http://moodle.school.edu/course/view.php?id=2 极不友好。 local_cleanurls 插件可将其变为 http://moodle.school.edu/course/2 。下载地址:https://moodle.org/plugins/pluginversion.php?id=12345(以实际 ID 为准)。安装方法:

cd /var/www/moodle/local/
sudo wget https://github.com/your-repo/cleanurls/archive/master.zip
sudo unzip master.zip
sudo mv cleanurls-master cleanurls
sudo chown -R www-data:www-data cleanurls

然后在 Site administration > Plugins > Local plugins 中启用它。这一步大幅提升用户体验和 SEO。

第五,创建第一个课程并添加一名测试学生。
进入 Site administration > Courses > Add a new course ,填写课程名称、简称、描述。在 Course format 中,新手推荐 Topics (主题格式),比 Weekly (周格式)更直观。创建后,点击 Participants > Enrol users ,搜索并添加一个测试用户(如 student01 )。这是验证整个流程是否闭环的最终测试。

4.3 性能监控与日志分析:用原生工具做“医生”

Moodle 运行起来后,不能放任不管。Ubuntu 16.04 提供了强大的原生工具链,无需安装第三方 APM:

Apache 访问日志分析:
/var/log/apache2/moodle_access.log 记录了每一次 HTTP 请求。用 awk 快速统计 Top 10 最耗时的请求:

# 统计响应时间(第 7 列)最高的 10 个 URL
awk '{print $7, $11}' /var/log/apache2/moodle_access.log | sort -nr | head -10

若发现 /report/performance/index.php /admin/tool/phpunit/cli/util.php 频繁出现,说明有人在后台执行耗时操作,需关注。

MySQL 慢查询日志:
/etc/mysql/mysql.conf.d/mysqld.cnf 中启用:

slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 2

然后重启 MySQL。用 mysqldumpslow 分析:

sudo mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log

输出会显示执行时间最长的 10 个 SQL,如 SELECT * FROM mdl_course WHERE id = ? ,这提示你需要为 mdl_course.id 字段添加索引(它本就有,但若被误删则需重建)。

Moodle 自身日志:
Site administration > Reports > Logs 是最直观的界面。但更强大的是其数据库日志表 mdl_logstore_standard_log 。一个实用的 SQL 查询,找出最近一小时最活跃的用户:

SELECT userid, COUNT(*) as cnt 
FROM mdl_logstore_standard_log 
WHERE timecreated > UNIX_TIMESTAMP(NOW() - INTERVAL 1 HOUR) 
GROUP BY userid 
ORDER BY cnt DESC 
LIMIT 10;

这能帮你快速定位是哪个老师在批量导入课程,或是哪个学生在刷课。

5. 常见问题与排查技巧实录:来自 17 个真实现场的故障快查表

5.1 白屏(Blank Page):最常见也最易解决的“幽灵故障”

现象:访问 Moodle 首页或任何页面,浏览器只显示一片空白,无错误信息,查看源码也是空的。

排查路径(按优先级排序):

  1. 检查 PHP 错误日志 sudo tail -f /var/log/apache2/error.log 。最常见的原因是 PHP Fatal error: Allowed memory size of 134217728 bytes exhausted ,即 memory_limit 不足。解决方案:将 /etc/php/7.0/apache2/php.ini 中的 memory_limit 128M 提升到 256M 512M ,然后 sudo systemctl restart apache2
  2. 检查 Moodle config.php 权限 sudo ls -l /var/www/moodle/config.php 。如果权限不是 -rw-r--r-- (644),而是 -rw------- (600),则 Apache 无法读取它,导致白屏。修复: sudo chmod 644 /var/www/moodle/config.php
  3. 检查 moodledata 目录所有权 sudo ls -ld /var/moodledata 。如果所有者不是 www-data ,则 Moodle 无法写入缓存,导致初始化失败。修复: sudo chown www-data:www-data /var/moodledata

实操心得:我养成了一个习惯,在每次修改 php.ini config.php 后,都执行 sudo -u www-data php /var/www/moodle/admin/cli/check_database.php 。这个命令会以 Apache 用户身份运行 Moodle 的数据库检查脚本,能提前暴露权限和配置问题,比等用户报告白屏高效得多。

5.2 登录后无限重定向(Redirect Loop)

现象:输入用户名密码后,页面不断刷新,URL 在 /login/index.php /my/ 之间跳转,无法进入个人主页。

根本原因:HTTPS 配置不一致。
Moodle 的会话管理对协议极其敏感。如果 Apache 配置了 HTTPS 重定向,但 Moodle 的 config.php $CFG->wwwroot 仍为 http:// 开头,就会陷入重定向循环。

解决方案:

  1. 确认 Apache 的 HTTPS 虚拟主机已启用且工作正常(访问 https://moodle.school.edu 应能打开)。
  2. 编辑 /var/www/moodle/config.php ,找到 $CFG->wwwroot 行,将其改为 https://moodle.school.edu
  3. 清除浏览器缓存和 Cookie,重新登录。

5.3 上传大文件失败(Upload Max Filesize Exceeded)

现象:在课程中上传一个 50MB 的视频,选择文件后,页面弹出 File exceeds maximum file size 错误。

这不是单一配置问题,而是三层限制的叠加:

层级 配置项 位置 推荐值
PHP 层 upload_max_filesize /etc/php/7.0/apache2/php.ini 128M
PHP 层 post_max_size 同上 128M (必须 ≥ upload_max_filesize
Apache 层 LimitRequestBody /etc/apache2/sites-available/moodle.conf 134217728 (即 128MB)

操作步骤:

  1. 修改 php.ini 中的两个值。
  2. 在 Apache 虚拟主机配置的 <Directory> 块内,添加:
    LimitRequestBody 134217728
    
  3. 重启 Apache: sudo systemctl restart apache2

5.4 数据库连接失败(Can't connect to local MySQL server)

现象:安装向导卡在数据库测试步骤,或登录后首页报错 Error reading from database

排查清单:

  • sudo systemctl status mysql :确认 MySQL 服务正在运行。
  • sudo mysql -u moodle -p -D moodle :用 Moodle 数据库用户尝试登录,验证密码和权限。
  • sudo netstat -tlnp | grep :3306 :确认 MySQL 监听在 127.0.0.1:3306 ,而非 ::1:3306 (IPv6)。若只监听 IPv6,需在 /etc/mysql/mysql.conf.d/mysqld.cnf 中注释掉 bind-address = ::1 ,并添加 bind-address = 127.0.0.1
  • sudo cat /var/log/mysql/error.log :查看 MySQL 自身的错误日志,常有线索。

5.5 课程页面显示“Coding error detected”(编码错误)

现象:点击某个课程,页面报错 Coding error detected, it must be fixed by a programmer: Invalid get_string() identifier: 'pluginname'

这是典型的插件语言包缺失。
Moodle 的插件(如 mod_h5p , block_course_list )都有自己的语言包。如果插件是手动下载 ZIP 安装的,其语言包可能未被自动部署。

解决方案:

  1. 进入 `Site administration > Language >
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值