简介:这份资源是郑州大学计算机与人工智能学院《数据库系统原理》课程的实验报告文档,面向正在修读数据库课程、需要完成实验报告撰写或参考实验流程的本科生。内容围绕万里数据库GreatSQL展开,涵盖DBMS工作原理与系统构架认识、商用数据库的安装配置与启停管理、基本表视图触发器存储过程等逻辑组件,以及虚拟机CentOS环境下关闭SELinux与防火墙、安装依赖包、下载解压二进制包等完整实践环节,并强调实验截图编号、表格规范与结果分析反思的撰写要求。资源包共1个docx文件,约3.69MB,结构完整、图文对应,可直接作为实验报告模板与操作参照。目前已有509人学习,适合需要理清实验步骤、补齐报告格式或复盘GreatSQL部署细节的同学参考借鉴。
1. 从一台干净的 CentOS 7 说起:GreatSQL 8.0.32 装不上,多半是环境没清干净
虚拟机里刚装完 CentOS 7,命令行黑底白字,第一反应是“这玩意儿能跑数据库?”——我见过太多人卡在这一步,不是 GreatSQL 装不上,而是 SELinux 和 firewalld 在背后悄悄拦路。数据库原理实验里那套 GreatSQL 8.0.32-25 的二进制包,解压只要几秒,真正耗时间的是前面那堆环境准备:关 SELinux、停防火墙、补依赖包、建 mysql 用户、写 systemd 服务文件。任何一步漏了,后面systemctl start greatsql就是起不来,日志里翻半天才发现是权限或者端口被挡。这篇笔记按我实际装机的顺序走一遍,从环境清理到服务验证,中间穿插几个我踩过的坑,适合刚接触 Linux 下装数据库的开发者,也适合想把这套实验环境一次搭稳的人。
2. 装前环境清理:SELinux、防火墙和依赖包一个都不能少
2.1 关 SELinux 和 firewalld 的真实原因
很多人照着实验报告敲setenforce 0,敲完就过了,但没想过为什么。SELinux 是强制访问控制,它会给 mysqld 进程套一层策略,数据库要读写/var/lib/mysql、要监听 3306,策略没放行就直接拒绝,表现就是服务启动失败或者连不上。实验环境里关掉它是为了减少变量,生产上当然不能这么干,但本地虚拟机里我一般直接关:
# 临时关闭,立即生效,重启后恢复 setenforce 0 # 永久关闭,改配置文件,重启后依然生效 sed -i '/^SELINUX=/c\SELINUX=disabled' /etc/selinux/config # 停掉防火墙并禁止开机自启 systemctl stop firewalld systemctl disable firewalldsetenforce 0只改运行时状态,重启就回来了,所以必须配合改/etc/selinux/config。防火墙这边,CentOS 7 默认开 firewalld,3306 端口没放行的话,本机用 socket 能连、远程用 TCP 就连不上,实验里经常要拿客户端工具连,干脆停掉省事。注意disable和stop顺序无所谓,但两个都要执行,只 stop 不 disable,下次开机又起来了。
2.2 依赖包清单和安装命令
GreatSQL 的二进制包虽然叫 minimal,但它依赖的系统库一点不少。实验报告里列了一长串,我按用途拆一下:libaio-devel是异步 IO 库,InnoDB 刷盘要用;numactl-devel和numactl-libs是 NUMA 亲和性支持,多核机器上影响性能;openssl和openssl-devel给 SSL 连接用;jemalloc是内存分配器,GreatSQL 编译时链接了它;perl那一串是给 mysql 自带脚本用的,比如mysql_install_db之类的工具。一条命令装完:
yum install -y pkg-config perl libaio-devel numactl-devel numactl-libs \ net-tools openssl openssl-devel jemalloc jemalloc-devel \ perl-Data-Dumper perl-Digest-MD5 python2 perl-JSON perl-Test-Simplepython2在 CentOS 7 上是自带的,但有些最小化安装的镜像会缺,补上没坏处。net-tools提供netstat,虽然现在推荐ss,但排查时两个都留着方便。装完可以用rpm -qa | grep libaio确认一下,缺了后面初始化会报libaio.so.1: cannot open shared object file,这个报错很典型,看到就知道是依赖没装全。
2.3 下载二进制包并放到 /usr/local
GreatSQL 的下载地址在实验报告里给了,版本是8.0.32-25,glibc2.17 对应 CentOS 7 的 glibc 版本,x86_64 是架构,minimal 表示精简包。放到/usr/local下解压:
cd /usr/local wget https://product.greatdb.com/GreatSQL-8.0.32-25/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal.tar.xz tar xf GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal.tar.xz解压出来是个长目录名,后面配置里要反复用到,我一般先ls确认目录名没打错。这里有个细节:wget下来的包如果网络不稳可能不完整,解压时报xz: (stdin): Unexpected end of input就是包坏了,重新下就行。解压完目录权限先别动,等建完 mysql 用户再统一 chown。
3. 服务化配置:systemd 文件、my.cnf 和 mysql 用户
3.1 写 greatsql.service 并重载 systemd
二进制包不会自动注册服务,得手写一个 unit 文件。实验报告里让编辑/lib/systemd/system/greatsql.service,内容我按实际能跑通的版本补全:
[Unit] Description=GreatSQL Server After=network.target After=syslog.target [Install] WantedBy=multi-user.target [Service] User=mysql Group=mysql Type=forking PIDFile=/var/lib/mysql/mysqld.pid TimeoutSec=0 PermissionsStartOnly=true ExecStart=/usr/local/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal/bin/mysqld --defaults-file=/etc/my.cnf --daemonize LimitNOFILE=65535 Restart=on-failure RestartPreventExitStatus=1 PrivateTmp=false几个关键点:Type=forking配合--daemonize,mysqld 自己后台化,systemd 靠 PIDFile 跟踪;User=mysql和Group=mysql必须和后面建的用户一致;ExecStart里的路径要和你解压出来的目录完全对上,差一个字符就是status=203/EXEC。写完执行:
systemctl daemon-reloaddaemon-reload是让 systemd 重新读 unit 文件,不执行这一步,新写的 service 根本不认识。我见过有人改完文件直接systemctl start,报Unit greatsql.service not found,就是漏了这步。
3.2 my.cnf 的最小可用配置
/etc/my.cnf是全局配置,实验报告里只说了“编辑”,没给内容。我按 8.0 的惯例给一份能跑的最小配置:
[mysqld] user=mysql basedir=/usr/local/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock pid-file=/var/lib/mysql/mysqld.pid port=3306 log-error=/var/log/greatsql-error.log character-set-server=utf8mb4 collation-server=utf8mb4_general_ci [client] socket=/var/lib/mysql/mysql.sock default-character-set=utf8mb4basedir指向解压目录,datadir是数据目录,这两个不能混。socket路径要和[client]里一致,否则本地mysql命令连不上。log-error单独指到/var/log下,方便排查,默认写在 datadir 里也行,但日志和数据混在一起不好找。字符集设成utf8mb4,实验里插中文姓名不会乱码,utf8在 8.0 里已经不建议用了。
3.3 建 mysql 用户和目录权限
数据库进程不能用 root 跑,得建专用用户。实验报告里的命令是:
/sbin/groupadd mysql /sbin/useradd -g mysql mysql -d /dev/null -s /sbin/nologin-d /dev/null表示不给家目录,-s /sbin/nologin禁止登录 shell,这是服务账号的标准做法。然后建数据目录并改属主:
mkdir -p /var/lib/mysql chown -R mysql:mysql /var/lib/mysql chown -R mysql:mysql /var/log chown -R mysql:mysql /usr/local/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal/var/log整个目录 chown 有点粗暴,但实验环境里问题不大,精确一点可以只 chown 那个 error log 文件。/usr/local下的解压目录也要给 mysql 权限,因为 basedir 里的某些文件运行时需要读。权限不对的典型报错是Can't create/write to file '/var/lib/mysql/...' (Errcode: 13 - Permission denied),看到 Errcode 13 先查属主。
3.4 初始化数据目录
8.0 的二进制包第一次启动前要初始化,否则 datadir 是空的,服务起不来。用--initialize-insecure生成空密码的 root:
/usr/local/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal/bin/mysqld \ --defaults-file=/etc/my.cnf \ --initialize-insecure \ --user=mysql--initialize-insecure和--initialize的区别是前者 root 密码为空,后者生成随机密码写在 error log 里。实验环境用 insecure 方便,进去再改密码。初始化过程会往 datadir 写系统表,几十秒到一两分钟,看机器性能。如果报--initialize specified but the data directory has files in it,说明 datadir 不空,要么清空要么换个目录,别硬来。
4. 启动验证与常见故障排查
4.1 启动服务并确认进程和端口
初始化完就可以起了:
systemctl start greatsql systemctl status greatsqlstatus显示active (running)才算成功。再确认进程和端口:
ps -ef | grep mysqld ss -lntp | grep mysqldps能看到 mysqld 进程,ss能看到 3306 在 LISTEN。如果status是failed,先看/var/log/greatsql-error.log,里面通常直接写了原因。连上去验证:
/usr/local/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal/bin/mysql -uroot -S /var/lib/mysql/mysql.sock-S指定 socket 路径,和 my.cnf 里一致。进去后SHOW DATABASES;能看到mysql、sys这些系统库就说明初始化没问题。
4.2 常见问题:现象、原因、解决
现象一:systemctl start greatsql报Job for greatsql.service failed,日志里Permission denied。原因:datadir 或 basedir 属主不是 mysql,或者 SELinux 没关干净。解决:ls -ld /var/lib/mysql确认属主,getenforce确认是Disabled或Permissive,不是就回去执行 2.1 的命令并重启。
现象二:服务起来了,但mysql命令连不上,报Can't connect to local MySQL server through socket。原因:客户端和服务端的 socket 路径不一致,或者 my.cnf 里[client]段没配。解决:mysql --socket=/var/lib/mysql/mysql.sock显式指定,或者检查/etc/my.cnf的[client]段。
现象三:初始化时报libnuma.so.1: cannot open shared object file。原因:numactl-libs没装,或者装了但版本不对。解决:yum install -y numactl-libs,装完ldconfig刷新一下库缓存。
现象四:systemctl status显示start request repeated too quickly。原因:服务反复启动失败,systemd 的Restart=on-failure触发了限流。解决:先systemctl reset-failed greatsql清掉失败计数,再看 error log 找根因,别直接 restart。
现象五:改了 my.cnf 后服务起不来,报unknown variable。原因:8.0 移除了一些老参数,比如query_cache_size,从 5.7 的配置抄过来就会中招。解决:注释掉报错的那行,或者查 8.0 的变量清单,GreatSQL 基于 8.0.32,参数兼容性按 8.0 走。
5. 装完怎么验证跑通:从建库建表到一条查询
服务起来只是第一步,真正验证这套环境能用,得走一遍建库、建表、插数据、查询的完整链路。我一般按实验二的流程做一遍冒烟测试,顺便确认字符集、权限、SQL 兼容性都没问题。
先连进去建库:
CREATE DATABASE DB; USE DB; SHOW DATABASES;然后建一张带主键和约束的表,插几条中文数据:
CREATE TABLE STUDENTS ( Sno CHAR(9) PRIMARY KEY, Sname CHAR(10) NOT NULL, Sex CHAR(2), Birthday DATE, Speciality CHAR(20), Dno CHAR(4) ); INSERT INTO STUDENTS VALUES ('201705001', '张华', '男', '1999-12-16', '计算机', 'CS'), ('201705002', '张晓霞', '女', '1999-01-01', '软件工程', 'SE'); SELECT * FROM STUDENTS WHERE Speciality = '计算机';如果中文能正常显示、WHERE能过滤出结果,说明字符集和基本 SQL 没问题。再验证一下索引:
CREATE INDEX Student_Dept ON STUDENTS (Dno); SHOW INDEX FROM STUDENTS;SHOW INDEX能看到Student_Dept就说明 DDL 正常。最后确认服务管理闭环:
systemctl restart greatsql systemctl status greatsql重启后数据还在,SELECT COUNT(*) FROM STUDENTS;还是 2 条,这套环境就算真正跑通了。我习惯在装完任何数据库后都走一遍“建库→建表→插数据→查询→重启→再查询”的流程,看起来笨,但能提前暴露字符集、权限、持久化这三类最容易在后期才炸的问题。从那以后我每次搭完 GreatSQL 都强制走一遍这个冒烟链路,不跳过,希望帮到你。
本文还有配套的精品资源,点击获取