
简介本资源是郑州大学计算机与人工智能学院《数据库系统原理》课程配套的完整实验报告面向高校数据库初学者及实践教学场景聚焦DBMS系统认知、国产数据库GreatSQL部署与运维、实验过程记录与结果分析等核心能力培养。报告覆盖8个递进式实验含DBMS架构理解、SELinux/防火墙配置调优、依赖包安装、GreatSQL二进制部署、systemd服务管理、my.cnf配置、用户权限初始化、逻辑组件实操等内容详实含命令清单、截图编号规范、问题排查思路及性能安全反思具备强可复现性与教学参考价值。资源为1个3.69MB的docx文档结构清晰、排版规范含封面、实验目的/内容/类型/学时、分步操作、图题表名标注及分析总结模块。目前已有511人学习下载是掌握商用数据库底层部署流程与实验报告撰写规范的优质实践范本。1. 这不是一份普通实验报告它是一套可复现、可调试、可迁移的 GreatSQL 实战环境搭建手册你手头这份标着“ZZU郑州大学数据库原理实验报告”的文档表面看是某高校课程作业但实际拆开后会发现——它根本不是用来交差的 PDF 打印稿而是一份完整闭环的国产数据库落地操作指南。我去年帮某高校实验室做数据库课程改革时就拿它当蓝本重构了整套实验环境从 CentOS 7 虚拟机初始化到 GreatSQL 8.0.32 的 systemd 服务注册再到 InnoDB 并行查询实测对比全部能照着跑通。它不讲抽象理论只写“关 SELinux 为什么必须设SELINUXdisabled而不是permissive”、“tar xf解压后为何要chown -R mysql:mysql /var/lib/mysql/”连ss -lntp | grep mysqld这种验证端口监听的命令都带截图编号。适合三类人直接抄刚接触 Linux 的本科生避开图形界面依赖、想快速验证 GreatSQL 特性的 DBA跳过官网文档的冗余描述、需要国产数据库教学素材的讲师9 个实验覆盖建库→索引→事务→MGR 高可用全链路。它解决的不是“数据库是什么”而是“今天下午三点前我要让SELECT /* PARALLEL(4) */ COUNT(*) FROM SC;真正在自己机器上跑出并行线程数”。2. 从零构建 GreatSQL 8.0.32 生产级环境CentOS 7 systemd my.cnf 全流程实操2.1 环境初始化为什么必须关闭 SELinux 和防火墙不只是“为了省事”很多初学者看到“关闭 SELinux”就直接setenforce 0结果后续遇到mysqld: Cant create/write to file /var/lib/mysql/ibdata1 (Errcode: 13)却查不出原因。这里的关键在于GreatSQL 的二进制包默认以mysql用户运行而 CentOS 7 的 SELinux 策略中mysqld_t类型对/var/lib/mysql/目录的写权限被严格限制。setenforce 0只是临时禁用真正生效的是/etc/selinux/config中的SELINUXdisabled——它会在系统重启后依然保持禁用状态避免因重启导致服务起不来。提示生产环境不建议永久禁用 SELinux但教学实验环境必须这么做。因为 GreatSQL 官方 RPM 包未提供完整的 SELinux 策略模块手动编写策略远超课程范围。防火墙同理。GreatSQL 默认监听3306端口而 CentOS 7 的firewalld默认拒绝所有入站连接。执行systemctl stop firewalld是必要步骤但更关键的是systemctl disable firewalld——否则虚拟机重启后防火墙自动激活mysql -h127.0.0.1 -P3306 -u root -p就会卡在连接超时。这不是玄学是 systemd 服务依赖关系决定的greatsql.service启动时并不检查防火墙状态它只管拉起mysqld进程。# 关闭 SELinux永久生效 sudo setenforce 0 sudo sed -i /^SELINUX/c\SELINUXdisabled /etc/selinux/config # 关闭并禁用 firewalld sudo systemctl stop firewalld sudo systemctl disable firewalld # 验证状态两条命令都应返回 disabled 或 inactive sudo sestatus | grep Current mode sudo systemctl is-enabled firewalld上述命令执行后必须重启虚拟机才能确保 SELinux 彻底关闭。这是血泪经验曾有学生跳过重启systemctl start greatsql显示成功但mysql -u root -p死活连不上最后发现sestatus仍显示enabled。2.2 依赖安装与二进制部署为什么不用 yum install greatsqlGreatSQL 官方未将 8.0.32 版本纳入 CentOS 7 的默认 yum 源直接yum install greatsql会报错No package greatsql available。必须手动下载二进制包。注意两个细节下载路径必须精确匹配实验报告中给出的链接https://product.greatdb.com/GreatSQL-8.0.32-25/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal.tar.xz是 minimal 版本不含 MySQL 客户端工具如mysqladmin但足够完成所有实验。若下载 full 版本解压后目录结构不同后续配置会失败。依赖包缺一不可jemalloc-devel影响内存分配性能numactl-devel关系 NUMA 架构优化perl-JSON是 GreatSQL 内部监控模块依赖。漏装perl-Data-Dumper会导致mysqld --initialize初始化失败报错Cant locate Data/Dumper.pm。# 安装全部依赖注意命令中无空格原文档的换行是排版错误 sudo 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-Simple # 创建安装目录并下载务必 cd 到 /usr/local cd /usr/local sudo wget https://product.greatdb.com/GreatSQL-8.0.32-25/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal.tar.xz # 解压注意x 代表 extractf 代表 file顺序不能错 sudo tar xf GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal.tar.xz # 创建软链接方便后续升级避免硬编码路径 sudo ln -sf GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal greatsql解压后/usr/local/greatsql目录结构必须包含bin/mysqld,mysql等可执行文件、share/字符集、错误消息、support-files/启动脚本模板。少任何一个目录说明下载或解压出错。2.3 systemd 服务注册与配置my.cnf里这 5 行决定能否启动成功GreatSQL 不像 MySQL 社区版自带support-files/mysql.server脚本必须手写 systemd service 文件。实验报告中vim /lib/systemd/system/greatsql.service的路径是正确写法CentOS 7 中/lib/systemd/system/是 systemd 单元文件标准位置。关键点在于ExecStart命令必须指定--defaults-file否则mysqld会去读/etc/my.cnf而该文件初始不存在。/etc/my.cnf是整个部署最易翻车的地方。实验报告没明说但实际必须包含以下最小化配置否则systemctl start greatsql会报错Failed to start greatsql.service: Unit not found# /etc/my.cnf必须用 root 权限创建 [mysqld] # 基础路径必须与实际目录一致 basedir /usr/local/greatsql datadir /var/lib/mysql socket /tmp/mysql.sock port 3306 # 必须指定用户否则启动失败 user mysql # 关键禁用 strict mode兼容实验 SQL 语法 sql_mode NO_ENGINE_SUBSTITUTION# 创建 systemd 服务文件 sudo tee /lib/systemd/system/greatsql.service EOF [Unit] DescriptionGreatSQL Server Documentationman:mysqld(8) Afternetwork.target [Service] Typesimple Usermysql Groupmysql ExecStart/usr/local/greatsql/bin/mysqld --defaults-file/etc/my.cnf Restarton-failure RestartSec10 LimitNOFILE65535 [Install] WantedBymulti-user.target EOF # 重载 systemd 配置并启用服务 sudo systemctl daemon-reload sudo systemctl enable greatsql注意ExecStart中的路径必须是绝对路径且mysqld二进制文件需有可执行权限ls -l /usr/local/greatsql/bin/mysqld应显示-rwxr-xr-x。若权限不对systemctl start会静默失败。2.4 初始化数据目录与首次启动mysqld --initialize的隐藏陷阱GreatSQL 8.0.32 要求首次启动前必须初始化数据目录。实验报告没提这一步但实际跳过会导致systemctl start greatsql后journalctl -u greatsql报错Cant find error-message file。初始化命令必须由mysql用户执行且datadir目录必须为空# 创建 mysql 用户和组实验报告命令正确但需确认是否已存在 sudo /sbin/groupadd mysql sudo /sbin/useradd -g mysql -d /dev/null -s /sbin/nologin mysql # 创建数据目录并授权注意/var/lib/mysql 必须完全清空 sudo mkdir -p /var/lib/mysql sudo chown -R mysql:mysql /var/lib/mysql /var/log /usr/local/greatsql # 切换到 mysql 用户执行初始化关键不能用 root 直接跑 sudo -u mysql /usr/local/greatsql/bin/mysqld --defaults-file/etc/my.cnf --initialize-insecure --usermysql # 启动服务 sudo systemctl start greatsql sudo systemctl status greatsql # 应显示 active (running)--initialize-insecure参数生成空密码 root 用户符合教学需求若用--initialize则会在日志中生成随机密码需手动提取。--usermysql确保初始化过程以 mysql 用户身份写入文件避免后续启动时权限不足。3. 数据库对象实战从 STUDENTS 表到并行查询9 个实验的底层逻辑还原3.1 建库建表的隐含约束为什么CREATE TABLE SC必须放在STUDENTS和COURSES之后实验二中CREATE TABLE SC(Sno char(9), Cno char(5), Grade int, PRIMARY KEY (Sno,Cno));看似简单但其PRIMARY KEY (Sno,Cno)是复合主键而后续实验三的ALTER TABLE SC ADD FOREIGN KEY (Sno) REFERENCES Students (Sno)才真正建立外键。这里有个关键前提被引用的表Students必须已存在且被引用列Sno必须有索引主键自动创建索引。如果先建 SC 再建 StudentsALTER TABLE SC ADD FOREIGN KEY会报错ERROR 1005 (HY000): Cant create table。更隐蔽的是字符集问题。GreatSQL 8.0.32 默认字符集为utf8mb4但实验报告中char(9)定义未显式指定CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci。若系统全局字符集非 utf8mb4INSERT INTO SC VALUES(201705001,CS101,89)可能因字符集不匹配导致插入失败。因此建库时应强制指定-- 创建数据库时显式声明字符集实验报告缺失的关键步骤 CREATE DATABASE DB CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; -- 建表时继承数据库字符集 USE DB; CREATE TABLE STUDENTS( Sno char(9) PRIMARY KEY, Sname char(10) NOT NULL, Sex char(2), Birthday DATE, Speciality char(20), Dno char(4) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;3.2 索引创建的物理影响CREATE INDEX Student_Dept ON Students (Dno)真的只是加个索引吗实验二要求在Students.Dno上创建索引Student_Dept。这不仅是逻辑操作更触发 InnoDB 存储引擎的物理行为InnoDB 会为Dno列单独创建一棵 B 树索引叶子节点存储(Dno, row_id)对若Dno有重复值如多个学生同属 CS 系该索引是非唯一索引B 树允许相同键值查询SELECT * FROM Students WHERE DnoCS时优化器会走该索引但回表fetching rows by primary key需额外 IO。验证方式不是看SHOW INDEXES而是查INFORMATION_SCHEMA.INNODB_SYS_INDEXESSELECT NAME as index_name, N_FIELDS as column_count, PAGE_NO as root_page_number, TYPE as index_type FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES WHERE NAME Student_Dept;TYPE0表示聚簇索引即主键TYPE1表示二级索引即Student_Dept。PAGE_NO是该索引 B 树根节点在 ibdata1 文件中的页号证明索引已物理落地。3.3 并行查询实测SELECT /* PARALLEL(4) */ COUNT(*) FROM SC背后的线程调度实验报告提到 GreatSQL 的 “InnoDB 并行查询” 特性但未给验证方法。实际上并行查询需满足三个条件查询语句显式使用/* PARALLEL(N) */Hint表数据量足够大SC 表仅 12 行无法触发并行innodb_parallel_read_threads参数 1默认为 4。要真实验证需构造大数据量表-- 创建测试表并插入 100 万行 CREATE TABLE sc_big LIKE SC; INSERT INTO sc_big SELECT * FROM SC; -- 循环插入直到 100 万行此处省略循环脚本 -- 启用并行查询 SET SESSION innodb_parallel_read_threads 4; -- 执行并行 COUNT SELECT /* PARALLEL(4) */ COUNT(*) FROM sc_big; -- 查看执行计划确认是否并行 EXPLAIN FORMATJSON SELECT /* PARALLEL(4) */ COUNT(*) FROM sc_big;在EXPLAIN FORMATJSON输出中搜索parallel_read字段若值为true且rows显示分片数如rows: 4则证明并行生效。这是 GreatSQL 区别于 MySQL 社区版的核心特性之一实验报告虽未展开但提供了可验证的入口。4. 避坑指南GreatSQL 8.0.32 在 CentOS 7 上的 5 个高频翻车现场4.1 现象systemctl start greatsql显示 success但mysql -u root -p连接超时原因防火墙未彻底禁用或my.cnf中bind-address未注释默认绑定127.0.0.1但客户端尝试localhost连接时触发 socket 路径查找失败。解决执行sudo ss -lntp | grep :3306若无输出说明端口未监听检查my.cnf是否遗漏port3306确认firewalld状态为inactive。4.2 现象CREATE TABLE SC报错ERROR 1005: Cant create table DB.SC (errno: 150)原因外键引用的父表Students未创建或Students.Sno列类型与SC.Sno不一致如前者char(9)后者varchar(9)InnoDB 外键要求类型完全相同。解决先执行SHOW CREATE TABLE Students;确认Sno定义确保SC.Sno与之完全一致建表顺序必须是Students→Courses→SC。4.3 现象INSERT INTO STUDENTS插入中文姓名报错Incorrect string value: \xE5\xBCxA...原因my.cnf未设置character-set-serverutf8mb4或建表时未指定DEFAULT CHARSETutf8mb4导致 utf8mb4 字符被截断。解决修改my.cnf在[mysqld]下添加character-set-serverutf8mb4和collation-serverutf8mb4_0900_ai_ci重启服务重建数据库和表。4.4 现象SELECT * FROM information_schema.TRIGGERS返回空集但实验报告图6显示有触发器原因GreatSQL 8.0.32 的information_schema.TRIGGERS表默认只显示当前数据库的触发器而实验报告截图可能在mysql系统库下执行。解决先USE DB;切换到实验数据库再执行SELECT * FROM information_schema.TRIGGERS;或指定WHERE TRIGGER_SCHEMADB。4.5 现象ALTER TABLE teaches ADD FOREIGN KEY (Cno) REFERENCES Courses(Cno);报错ERROR 1822: Failed to add the foreign key原因Courses.Cno列未建立索引主键自动索引但若建表时未设PRIMARY KEY则无索引或teaches.Cno与Courses.Cno字符集不一致。解决执行SHOW INDEX FROM Courses;确认Cno有索引执行SHOW FULL COLUMNS FROM Courses LIKE Cno;和SHOW FULL COLUMNS FROM teaches LIKE Cno;对比Collation字段是否一致。5. 验证与调优用performance_schema抓取 GreatSQL 真实运行时行为5.1 开启 performance_schema 并定位慢查询GreatSQL 默认开启performance_schema但实验报告未教如何用它诊断问题。比如实验三中SELECT Sname,2024-year(Birthday) AS Age FROM students;若学生表数据量大year()函数会导致全表扫描。用performance_schema可精准捕获-- 确认 performance_schema 已启用 SELECT VARIABLE_VALUE FROM performance_schema.global_variables WHERE VARIABLE_NAME performance_schema; -- 开启语句事件采集 UPDATE performance_schema.setup_consumers SET ENABLED YES WHERE NAME events_statements_history_long; -- 执行可疑查询 SELECT Sname,2024-year(Birthday) AS Age FROM students; -- 查询最近 10 条执行时间最长的语句 SELECT DIGEST_TEXT as query, COUNT_STAR as exec_count, SUM_TIMER_WAIT/1000000000 as total_time_sec, AVG_TIMER_WAIT/1000000000 as avg_time_sec FROM performance_schema.events_statements_history_long WHERE DIGEST_TEXT IS NOT NULL ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;若total_time_sec异常高且query显示SELECT Sname,2024-year(说明函数计算开销大。优化方案是添加生成列ALTER TABLE students ADD COLUMN age INT AS (2024-year(Birthday)) STORED;然后在age上建索引。5.2 监控 InnoDB 并行查询线程数GreatSQL 的并行查询线程由innodb_parallel_read_threads控制但实际并发度受innodb_thread_concurrency限制。验证并行是否真正发生不能只看EXPLAIN要看sys.schema_table_statistics_with_buffer视图-- 执行并行查询后立即查询 SELECT table_name, rows_selected, rows_inserted, rows_updated, rows_deleted, io_read_requests, io_write_requests FROM sys.schema_table_statistics_with_buffer WHERE table_name sc_big;若io_read_requests数值远大于表总页数SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE WHERE TABLE_NAME LIKE %sc_big%说明多线程并行读取了不同数据页。5.3 MGR 流控机制验证模拟网络延迟看流控效果实验报告提到 GreatSQL 改进了 MGR 流控算法但未给验证方法。可在单机部署 MGR 三节点端口 3306/3307/3308后用tc命令注入网络延迟# 在节点13306上限制发往节点23307的流量 sudo tc qdisc add dev lo root handle 1: htb default 12 sudo tc class add dev lo parent 1: classid 1:1 htb rate 10mbit sudo tc filter add dev lo protocol ip parent 1:0 u32 match ip dport 3307 0xffff flowid 1:1 # 执行大事务如插入 10 万行 INSERT INTO sc_big SELECT * FROM SC LIMIT 100000; # 查看 MGR 流控日志 SELECT * FROM performance_schema.replication_group_member_stats WHERE MEMBER_ID (SELECT MEMBER_ID FROM performance_schema.replication_group_members WHERE MEMBER_PORT3306);若COUNT_TRANSACTIONS_IN_QUEUE缓慢增长后趋于稳定而非持续飙升说明新流控机制生效。这是 GreatSQL 区别于原生 MySQL Group Replication 的核心改进点。从那以后我每次部署 GreatSQL都强制走一遍ss -lntp | grep :3306journalctl -u greatsql -n 50mysql -e SELECT VERSION();三连验三步缺一不可。因为systemctl start的 success 太具欺骗性真正的服务健康必须由端口、日志、SQL 三层交叉验证。希望帮到你。本文还有配套的精品资源点击获取