准备
mysqldump、mysql 开头的命令。按 Win+R,输入 cmd 回车打开。不要用 PowerShell。SELECT、SHOW、CREATE、DROP 等开头的 SQL 语句,在 root 连接的编辑区执行。Workbench 打开 root 的连接,复制下面整段,按 Ctrl+Shift+Enter 执行,把 teaching 库恢复成标准数据。
Workbench 中整段执行下载 .sql-- 第 10 章上机练习:准备数据(在 Workbench 中用 root 整段执行,可以反复执行) -- 重建教材的 teaching 库:c 课程、s 学生、t 教师、sc 选课、tc 授课 CREATE DATABASE IF NOT EXISTS teaching DEFAULT CHARACTER SET utf8mb4; USE teaching; -- 删除第 7 章实验建的视图 DROP VIEW IF EXISTS s_view, s_sc_c_view, s_maj_view, s_update_view, c_count_view, maj_view, s_sc_view, s_lxy_view; -- 删除旧的表。先暂时关闭外键检查,库里有别的表引用它们时也能删除 SET FOREIGN_KEY_CHECKS = 0; DROP TABLE IF EXISTS sc, tc, avgsal, classroom, s, c, t; SET FOREIGN_KEY_CHECKS = 1; -- 课程表 CREATE TABLE c ( cno CHAR(4) NOT NULL, cn VARCHAR(30) NOT NULL, ct INT, PRIMARY KEY (cno) ); -- 学生表 CREATE TABLE s ( sno CHAR(4) NOT NULL, sn VARCHAR(20) NOT NULL, sex CHAR(2), age INT, maj VARCHAR(30), dept VARCHAR(30), PRIMARY KEY (sno) ); -- 教师表 CREATE TABLE t ( tno CHAR(4) NOT NULL, tn VARCHAR(20) NOT NULL, sex CHAR(2), age INT, prof VARCHAR(20), maj VARCHAR(30), dept VARCHAR(30), sal DECIMAL(8,2), PRIMARY KEY (tno) ); -- 选课表 CREATE TABLE sc ( sno CHAR(4) NOT NULL, cno CHAR(4) NOT NULL, score DECIMAL(5,2), PRIMARY KEY (sno, cno), FOREIGN KEY (sno) REFERENCES s (sno), FOREIGN KEY (cno) REFERENCES c (cno) ); -- 授课表 CREATE TABLE tc ( tno CHAR(4) NOT NULL, cno CHAR(4) NOT NULL, tcdate DATE, PRIMARY KEY (tno, cno), FOREIGN KEY (tno) REFERENCES t (tno), FOREIGN KEY (cno) REFERENCES c (cno) ); INSERT INTO c VALUES ('c1','Java程序设计',40), ('c2','程序设计基础',48), ('c3','线性代数',48), ('c4','数据结构',64), ('c5','数据库系统',56), ('c6','数据挖掘',32), ('c7','高等数学',60), ('c8','控制理论',32); INSERT INTO s VALUES ('s1','王彤','女',18,'计算机','信息学院'), ('s2','苏乐','男',20,'信息','信息学院'), ('s3','林欣怡','女',19,'信息','信息学院'), ('s4','陶然','男',19,'自动化','工学院'), ('s5','魏立','男',17,'数学','理学院'), ('s6','何欣荣','女',21,'计算机','信息学院'), ('s7','赵琳琳','女',19,'数学','理学院'), ('s8','李轩','男',18,'自动化','工学院'); INSERT INTO t VALUES ('t1','刘杨','男',38,'教授','计算机','信息学院',3800.00), ('t2','石丽','女',28,'讲师','计算机','信息学院',2800.00), ('t3','顾伟','男',35,'副教授','计算机','信息学院',3200.00), ('t4','赵礼','男',45,'教授','自动化','工学院',4267.90), ('t5','赵希希','女',33,'副教授','数学','理学院',3332.67), ('t6','张刚','男',30,'讲师','计算机','工学院',2600.00); INSERT INTO sc VALUES ('s1','c1',90.50), ('s1','c2',88.00), ('s2','c4',70.00), ('s2','c5',57.00), ('s2','c6',81.50), ('s2','c7',NULL), ('s3','c1',75.00), ('s3','c2',76.50), ('s3','c4',85.00), ('s4','c1',93.00), ('s4','c2',82.00), ('s4','c6',NULL), ('s4','c7',68.00), ('s5','c2',79.00), ('s5','c7',84.00), ('s7','c3',77.00), ('s7','c5',62.00), ('s7','c7',100.00), ('s8','c2',66.00), ('s8','c3',96.00); INSERT INTO tc VALUES ('t1','c1','2021-09-03'), ('t1','c2','2021-09-04'), ('t2','c5','2021-03-06'), ('t2','c6','2021-09-06'), ('t3','c2','2021-03-08'), ('t3','c4','2021-09-08'), ('t4','c3','2021-03-10'), ('t5','c7','2021-09-12'), ('t5','c8','2021-03-15'); DROP TABLE IF EXISTS c_copy; -- 检查数据 SELECT COUNT(*) AS 学生数 FROM s; SELECT COUNT(*) AS 选课数 FROM sc;应看到最后两个结果:学生数 8,选课数 20。
命令行 cmd 打开 cmd,进入 MySQL 的 bin 文件夹,确认能找到 mysqldump。
命令行 cmd 中执行cd /d "C:\Program Files\MySQL\MySQL Server 8.0\bin" mysqldump --version
注意如果装的是别的版本,把路径里的 8.0 换成实际的文件夹名。这个 cmd 窗口整节课都别关。
应看到一行版本信息,例如 mysqldump Ver 8.0.xx for Win64。
命令行 cmd 建一个专门放备份的文件夹。
命令行 cmd 中执行mkdir D:\db_backup
注意电脑没有 D 盘的,把本页所有 D:/db_backup 都换成 C:/db_backup。
应看到没有任何提示就是成功了。提示「已经存在」也没关系。
备份整个库
命令行 cmd 把整个 teaching 库备份到 D:/db_backup/teaching_full.sql。
格式
mysqldump -u 用户 -p 库名 > 文件路径回车后输入 root 的口令(输入时不显示)看答案
命令行 cmd 中执行mysqldump -u root -p teaching > D:/db_backup/teaching_full.sql
应看到输完口令后没有任何输出,又回到了命令提示符。
命令行 cmd 用记事本打开备份文件,看看里面是什么。
命令行 cmd 中执行notepad D:\db_backup\teaching_full.sql
应看到全是 SQL 语句:每张表一段 DROP TABLE IF EXISTS、CREATE TABLE、INSERT INTO。往上翻找一找——文件里没有 CREATE DATABASE。看完关掉记事本。
备份部分表
命令行 cmd 只备份学生表 s,文件名 teaching_s.sql。
格式
mysqldump -u 用户 -p 库名 表名 > 文件路径看答案
命令行 cmd 中执行mysqldump -u root -p teaching s > D:/db_backup/teaching_s.sql
应看到输完口令,没有输出。
命令行 cmd 同时备份学生表 s 和课程表 c,文件名 teaching_s_c.sql。
提示多个表名之间用空格隔开。
看答案
命令行 cmd 中执行mysqldump -u root -p teaching s c > D:/db_backup/teaching_s_c.sql
应看到输完口令,没有输出。
命令行 cmd 列出备份文件夹里的文件,比一比大小。
命令行 cmd 中执行dir D:\db_backup
应看到3 个 .sql 文件。teaching_full.sql 最大,teaching_s.sql 最小。
删库,再还原
Workbench 制造事故:删掉 teaching 库,再看看库还在不在。
Workbench 中执行DROP DATABASE teaching; SHOW DATABASES;
注意执行前确认第 2 项里看到了 teaching_full.sql,不然就真的找不回来了。
应看到库列表里没有 teaching 了。
Workbench 备份文件里没有 CREATE DATABASE,所以先建一个空库。
Workbench 中执行CREATE DATABASE teaching DEFAULT CHARACTER SET utf8mb4;
应看到1 row(s) affected。
命令行 cmd 换回 cmd,用 teaching_full.sql 还原。
提示和备份命令比,只改两处:
mysqldump换成mysql,>换成<。看答案
命令行 cmd 中执行mysql -u root -p teaching < D:/db_backup/teaching_full.sql
应看到输完口令,等一两秒,没有输出就是成功。
Workbench 检查数据回来没有。
Workbench 中执行USE teaching; SHOW TABLES; SELECT COUNT(*) AS 学生数 FROM s; SELECT COUNT(*) AS 选课数 FROM sc;
应看到c、s、t、sc、tc 都在;学生数 8,选课数 20,和删库前一样。
导出与导入
Workbench 查一下 MySQL 允许读写文件的文件夹。
Workbench 中执行SHOW VARIABLES LIKE 'secure_file_priv';
应看到一般是 C:\ProgramData\MySQL\MySQL Server 8.0\Uploads\。下面两步的路径要和它一致,并把 \ 写成 /。
Workbench 把课程表 c 导出到 Uploads 文件夹的 c.txt,字段之间用逗号隔开。
Workbench 中执行SELECT * FROM teaching.c INTO OUTFILE 'C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/c.txt' FIELDS TERMINATED BY ',';
应看到8 row(s) affected。
Workbench 建一张结构和 c 一样的空表 c_copy,把 c.txt 导进去,再查。
Workbench 中执行CREATE TABLE teaching.c_copy LIKE teaching.c; LOAD DATA INFILE 'C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/c.txt' INTO TABLE teaching.c_copy CHARACTER SET utf8mb4 FIELDS TERMINATED BY ','; SELECT * FROM teaching.c_copy;
应看到c_copy 里有 8 行,和 c 表一模一样,中文也正常。
查看日志
Workbench 查看错误日志的位置和最近几条内容。
Workbench 中执行SHOW VARIABLES LIKE 'log_error'; SELECT LOGGED, PRIO, DATA FROM performance_schema.error_log ORDER BY LOGGED DESC LIMIT 5;
应看到第一句给出错误日志文件的路径;第二句列出最近 5 条记录:时间、级别(System、Warning、Error)、内容。
Workbench 看看二进制日志开没开,有哪些文件。
Workbench 中执行SHOW VARIABLES LIKE 'log_bin'; SHOW BINARY LOGS;
应看到log_bin 是 ON;下面列出若干个文件,名字形如 xxx-bin.000012。记下最后一个的名字。
Workbench 打开最后一个二进制日志,找一找删库的记录。
Workbench 中执行SHOW BINLOG EVENTS IN 'xxx-bin.000012';
注意把引号里的文件名换成上一步记下的那个。
应看到在 Info 列里能找到 DROP DATABASE teaching,后面紧跟着还原时的 CREATE TABLE 和 INSERT。修改数据的操作都被记下来了,这正是它能用来恢复数据的原因。
捉一条慢查询
Workbench 看看慢查询日志现在的状态。
Workbench 中执行SHOW VARIABLES LIKE 'slow_query_log'; SHOW VARIABLES LIKE 'long_query_time';
应看到slow_query_log 是 OFF,long_query_time 是 10.000000(秒)。
Workbench 打开慢查询日志,阈值改成 1 秒;并让它同时记到一张表里,方便用 SQL 查看。
Workbench 中执行SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 1; SET GLOBAL log_output = 'FILE,TABLE';
应看到三句都执行成功。
把 root 的标签页关掉,再双击打开(新阈值只对新连接有效),然后在 Workbench 执行一条要等 2 秒的语句。
Workbench 中执行SELECT SLEEP(2);
应看到大约 2 秒后返回 0。
Workbench 看看慢查询日志记下了什么。
Workbench 中执行SHOW VARIABLES LIKE 'slow_query_log_file'; SELECT start_time, query_time, CONVERT(sql_text USING utf8mb4) AS 语句 FROM mysql.slow_log;应看到第一句是日志文件的位置;第二句里有一行:query_time 约 00:00:02,语句是 SELECT SLEEP(2)——被抓到了。
Workbench 收尾:把三个设置都改回默认值。
Workbench 中执行SET GLOBAL slow_query_log = OFF; SET GLOBAL long_query_time = 10; SET GLOBAL log_output = 'FILE';
应看到三句都执行成功。
练习结束
今天用到的命令,记住它们在哪里执行:
| 做什么 | 命令 | 在哪执行 |
|---|---|---|
| 备份 | mysqldump -u root -p 库 [表] > 文件 | 命令行 cmd |
| 还原 | mysql -u root -p 库 < 文件 | 命令行 cmd |
| 导出 | SELECT … INTO OUTFILE '文件' | Workbench |
| 导入 | LOAD DATA INFILE '文件' INTO TABLE 表 | Workbench |
| 看日志设置 | SHOW VARIABLES LIKE '…' | Workbench |
DROP TABLE IF EXISTS teaching.c_copy;