MySQL 1Z0-908 练习题:47 题带解析
按 1Z0-908(Oracle Certified Professional, MySQL 8.0 Database Administrator)考纲整理的 47 道练习题,覆盖八个模块。
考试本体是 73 题、120 分钟、62% 及格,全部单选加多选,没有实验题。所以这里也全是场景判断题——不考语法拼写,考的是这个场景下该用哪个工具、哪组参数。
想在页面上直接点选、即时判分、记错题,用 交互版练习台。
先自己答,再展开每题下面的「答案与解析」。解析里写清了错误选项错在哪,比只记答案有用。
八个模块的权重
| 模块 | 参考占比 | 考察重点 |
|---|---|---|
| 架构 | 8% | InnoDB 内部机制、内存结构、数据字典 |
| 安装配置 | 13% | 初始化、选项文件优先级、SET PERSIST、升级、sql_mode |
| 安全 | 18% | 认证插件、角色、动态权限、TLS、加密与 keyring |
| 监控维护 | 11% | 四类日志、Performance Schema、MDL 与死锁诊断 |
| 查询优化 | 7% | 执行计划、索引设计、直方图、EXPLAIN ANALYZE |
| 备份恢复 | 14% | 逻辑与物理备份、PITR、binlog 格式 |
| 复制 | 13% | 三个线程、GTID、半同步、多源、延迟复制 |
| 高可用 | 16% | MGR、InnoDB Cluster、MySQL Router、故障切换 |
权重是按几份真题题库的分布整合的估算,官方只公布主题、不公布百分比。定复习优先级够用,别当精确数字背。
架构
1. InnoDB 的 doublewrite buffer 主要解决什么问题?
- A. 提高 redo log 的写入吞吐
- B. 防止页写入过程中崩溃导致的数据页损坏(partial page write)
- C. 加速崩溃后的事务回滚
- D. 减少 undo 表空间的占用
答案与解析
答案:B
InnoDB 页默认 16KB,而操作系统块通常是 4KB,一个页的写入不是原子操作。若写到一半断电,就会留下半新半旧的“碎页”,而这种损坏 redo log 修不了(redo 只记录页内偏移的变更,前提是页本身完好)。所以 InnoDB 先把页顺序写进 doublewrite 区(连续、开销小),再写数据文件;崩溃恢复时用 doublewrite 里的完整副本把碎页补回来。
2. 关于 InnoDB redo log,下列说法正确的是?
- A. redo log 记录数据页的最终值,用于回滚未提交事务
- B. redo log 是固定总容量的环形文件,写满后必须推进 checkpoint 才能继续写
- C. redo log 只有一份,无法配置多个文件
- D. 从 MySQL 8.0.30 起 redo log 被移除,改由 binlog 承担
答案与解析
答案:B
redo log 是物理逻辑日志,记录“在某个页的某个偏移做了什么修改”,用于前滚重放,不用于回滚(回滚靠 undo)。它循环使用:写满就必须推进 checkpoint,把脏页刷盘后释放空间。8.0.30 起用 innodb_redo_log_capacity 统一控制总容量,文件放在 #innodb_redo 目录下(默认 32 个),但环形复用的本质没变。此前可用 innodb_log_files_in_group 配多个文件,所以“只有一份、无法配置多个”这个说法也是错的。
3. MySQL 8.0 中,表结构和元数据(数据字典)存放在哪里?
- A. 每张表一个 .frm 文件
- B. InnoDB 内部的事务性数据字典表(位于 mysql.ibd)
- C. 每张表一个 .MYD 文件
- D. 只存在于内存,重启后从 binlog 重建
答案与解析
答案:B
8.0 最大的架构变化之一就是移除 .frm,把数据字典改成 InnoDB 里的一组事务性表,存放在 mysql.ibd。带来的好处:DDL 具备原子性(8.0 支持原子 DDL)、崩溃后元数据不会再和数据不一致、INFORMATION_SCHEMA 查询性能大幅提升(不再是打开表文件去读)。
4. buffer pool 的 LRU 链表被分成 young 区和 old 区,这样设计的目的是?
- A. 支持多线程并发读取,减少 latch 争用
- B. 防止全表扫描或预读这类一次性大量读取把真正的热数据挤出内存
- C. 降低 buffer pool 的元数据内存开销
- D. 让 checkpoint 能批量刷脏页
答案与解析
答案:B
新读入的页先进 old 区(默认占 3/8,由 innodb_old_blocks_pct 控制)。只有在 old 区停留超过 innodb_old_blocks_time(默认 1000ms)后再次被访问,才有资格晋升到 young 区。这样一次全表扫描读进来的几千个页,扫完就被淘汰,不会污染热数据。
5. 关于 change buffer(写缓冲),下列说法正确的是?
- A. 它对唯一索引同样有效
- B. 它缓存对非唯一二级索引的写操作,把随机读延后到索引页被读入时合并
- C. 它是 redo log 的一个组成部分
- D. 它只在只读实例上启用
答案与解析
答案:B
当要修改的二级索引页不在 buffer pool 中,InnoDB 把这次修改记进 change buffer,等该索引页因为其他原因被读入内存时再 merge,避免为了写一条记录而产生大量随机 I/O。唯一索引不适用——因为必须立刻读页做唯一性检查,缓冲就没有意义了。注意 change buffer 本身也是持久化的(有对应的系统表空间页),并且受 innodb_change_buffering 控制。
6. 下列哪些属于 InnoDB 的内存结构? (多选)
- A. buffer pool
- B. log buffer
- C. redo log 文件
- D. adaptive hash index
答案与解析
答案:A、B、D
buffer pool 缓存数据页和索引页;log buffer 暂存 redo 记录,按 innodb_flush_log_at_trx_commit 的时机刷盘;AHI 建在 buffer pool 之上,用哈希加速等值查找。redo log 文件是磁盘上的持久化文件,不属于内存结构(内存里那个叫 log buffer)。“内存 vs 磁盘”的区分是架构题的固定陷阱。
安装配置
7. 在 Linux 上,MySQL 参数优先级的正确顺序是?
- A. 选项文件 > 命令行参数 > 编译时默认值
- B. 命令行参数 > 选项文件 > 编译时默认值
- C. 编译时默认值 > 命令行参数 > 选项文件
- D. 三者同级,后写生效
答案与解析
答案:B
命令行参数优先级最高,其次是选项文件,最后才是编译进二进制的默认值。多个选项文件之间也有顺序(/etc/my.cnf → /etc/mysql/my.cnf → $MYSQL_HOME/my.cnf → ~/.my.cnf → ~/.mylogin.cnf),后读取的覆盖先读取的。排查“我明明改了配置为什么不生效”,第一个要查的就是后面还有文件把它覆盖了。
8. 要让一个全局变量的修改既立即生效、又写入 mysqld-auto.cnf 持久化,应使用?
- A. SET GLOBAL var = value
- B. SET PERSIST var = value
- C. SET SESSION var = value
- D. 改 my.cnf 后重启实例
答案与解析
答案:B
SET PERSIST 既改运行时值又写进 mysqld-auto.cnf(重启后仍在)。SET PERSIST_ONLY 只写文件不生效,专门用于只读/静态变量(比如 innodb_buffer_pool_size 之外的启动参数),改完重启才起作用。SET GLOBAL 只改内存,重启丢失。RESET PERSIST 可以撤销这些持久化项。
9. mysqld –initialize 与 mysqld –initialize-insecure 的区别是?
- A. 前者创建空密码 root,后者生成随机密码
- B. 前者为 root 生成一个随机临时密码并写入错误日志,后者直接创建空密码 root
- C. 两者完全等价,只是别名不同
- D. 后者不会创建系统表空间
答案与解析
答案:B
--initialize 生成随机临时密码,输出在 error log 里,第一次登录必须改密码(否则什么都不能做)。--initialize-insecure 直接给空密码,方便自动化搭建,但生产环境绝对不能用。注意初始化前 datadir 必须是空的,否则会拒绝启动——这是新手最常踩的坑。
10. 把 5.7 升级到 8.0 之前,官方推荐的兼容性预检工具是?
- A. mysql_upgrade 命令
- B. MySQL Shell 的 util.checkForServerUpgrade()
- C. mysqldump –compatible=mysql80
- D. pt-upgrade
答案与解析
答案:B
mysql_upgrade 在 8.0.16 已经被移除——8.0 启动时会自动完成数据字典升级。mysqlsh 的 util.checkForServerUpgrade() 才是官方预检工具,会扫出保留字冲突、不支持的数据类型、认证插件不兼容、字符集问题等一堆坑。升级前一定要跑,并且做好全备。
11. 默认 sql_mode 中的 STRICT_TRANS_TABLES 带来的行为是?
- A. 插入超长字符串时自动截断并只给一条 warning
- B. 写入不符合列定义的数据时直接报错,事务表会回滚该语句,而不是静默截断或补零
- C. 只影响 SELECT 的返回结果
- D. 会禁用外键约束检查
答案与解析
答案:B
严格模式下,超长字符串、非法日期、数值溢出都会直接抛错而不是“猜一个值存进去”。MySQL 8.0 默认 sql_mode 包含 STRICT_TRANS_TABLES、ONLY_FULL_GROUP_BY、NO_ZERO_DATE 等。从 5.7 升级到 8.0 后大量应用报错,八成就是旧代码依赖了非严格模式的行为。
安全
12. MySQL 8.0 默认的认证插件是?
- A. mysql_native_password
- B. caching_sha2_password
- C. sha256_password
- D. auth_socket
答案与解析
答案:B
8.0 把默认插件从 mysql_native_password 换成了 caching_sha2_password,用 SHA-256 加盐挑战应答,并带一个服务端缓存来避免每次连接都做完整握手。代价是老客户端(旧版 JDBC、Navicat 老版本、PHP 老驱动)连不上,必须升级驱动或显式指定 mysql_native_password。
13. 创建角色 r 并让用户 u1、u2 登录后自动拥有其权限,正确的一组语句是?
- A. CREATE ROLE r; GRANT SELECT ON db1.* TO r; GRANT r TO u1, u2; SET DEFAULT ROLE r TO u1, u2;
- B. CREATE ROLE r; GRANT r TO u1; GRANT SELECT ON db1.* TO r;
- C. GRANT ROLE r TO u1, u2;
- D. CREATE USER r; GRANT ALL ON . TO r; GRANT r TO u1;
答案与解析
答案:A
关键在最后一步 SET DEFAULT ROLE。只做 GRANT r TO u1,角色默认是未激活状态,用户登录上去查不到任何东西,必须手动 SET ROLE r 才生效。要么设默认角色,要么把角色放进 mandatory_roles(强制对所有用户生效)。
14. 启用 partial_revokes 系统变量后,可以实现什么?
- A. 让部分用户免密登录
- B. 从全局权限中精确排除某一部分(例如用户有全局 SELECT,但单独收回它对 db2 的 SELECT)
- C. 只回收列级权限而不影响表级权限
- D. 让角色对某些会话不生效
答案与解析
答案:B
默认情况下 MySQL 权限只有“加法”——用户有全局 SELECT 就拥有一切库的 SELECT,无法再局部收回。partial_revokes=ON 打开后可以做减法:REVOKE SELECT ON db2.* FROM u1,即使 u1 持有全局 SELECT 也能生效。这是 8.0 新增能力,也是权限模型题的高频考点。
15. 要求所有客户端都必须通过加密连接访问,应设置哪个参数?
- A. 服务端 ssl_mode=REQUIRED
- B. require_secure_transport=ON
- C. skip_ssl
- D. bind-address=127.0.0.1
答案与解析
答案:B
require_secure_transport=ON 是服务端强制项:未加密的连接(含本地 socket,除非配了共享内存/命名管道加密)会被直接拒绝并报错。ssl_mode 是客户端参数(DISABLED/PREFERRED/REQUIRED/VERIFY_CA/VERIFY_IDENTITY),管的是客户端要不要加密、要不要校验证书,管不住别人不加密连进来。
16. 客户端 –ssl-mode=VERIFY_IDENTITY 比 VERIFY_CA 多做了什么校验?
- A. 没有任何区别,只是名字不同
- B. 在校验证书链由可信 CA 签发的基础上,还校验证书中的主机名与客户端实际连接的主机名一致
- C. VERIFY_IDENTITY 只加密不校验证书
- D. VERIFY_CA 不加密传输,VERIFY_IDENTITY 才加密
答案与解析
答案:B
五个档位的递进关系:DISABLED(不加密)→ PREFERRED(能加密就加密,默认值)→ REQUIRED(必须加密,但不验证证书)→ VERIFY_CA(验证证书由可信 CA 签发)→ VERIFY_IDENTITY(再加上主机名匹配)。只有最后一档能防中间人拿一张合法但属于别的域名的证书来冒充。
17. 关于 InnoDB 表空间加密,下列说法正确的是?
- A. 加密密钥直接明文存在表空间头部
- B. 主密钥由 keyring 组件保管,表空间密钥用主密钥加密后存在表空间头部
- C. 只加密 redo log,不加密数据页
- D. 只能对新建表生效,已有表必须导出重建
答案与解析
答案:B
两层密钥结构:keyring 插件/组件持有主密钥(master key),每个表空间有自己的表空间密钥,用主密钥加密后存在表空间头(所以备份表空间文件本身不会泄露密钥)。已有表可以 ALTER TABLE t ENCRYPTION='Y' 原地加密。keyring 一定要提前配好并单独备份,主密钥丢了所有加密表都打不开。
18. 关于 caching_sha2_password,下列说法正确的有? (多选)
- A. 它是 MySQL 8.0 的默认认证插件
- B. 非 TLS 连接的首次认证需要走 RSA 公钥交换,客户端未配置公钥时会报错
- C. 密码以可逆加密方式存储,服务端可以还原出明文
- D. 服务端带缓存,同一用户重复认证时可走快速路径
答案与解析
答案:A、B、D
密码存的是 SHA-256 加盐哈希,不可逆,所以“服务端能还原明文”是错的。非加密连接的首次认证,客户端要用服务端下发的公钥加密密码,老驱动没配 allowPublicKeyRetrieval=true 就会报 Public Key Retrieval is not allowed。认证成功后结果被缓存,后续连接走快速路径,不必每次做完整 RSA 交换。
监控维护
19. MySQL 8.0 中 INFORMATION_SCHEMA.INNODB_LOCKS 和 INNODB_LOCK_WAITS 发生了什么变化?
- A. 仍然可用,内容和 5.7 一样
- B. 已被移除(8.0.1 起),改用 performance_schema.data_locks 和 data_lock_waits
- C. 改名为 INNODB_TRX_LOCKS
- D. 搬到了 sys 库下
答案与解析
答案:B
8.0 把锁信息迁到了 performance_schema.data_locks(每一把锁一行)和 data_lock_waits(等待关系),字段更全、粒度更细。老的 I_S 表在 8.0 直接不存在了,照着 5.7 的脚本去查会报表不存在。查“谁堵了谁”,8.0 的标准写法是 join 这两张表拿 REQUESTING_ENGINE_TRANSACTION_ID 和 BLOCKING_ENGINE_TRANSACTION_ID。
20. 想抓出执行时间超过 2 秒、以及没走索引的 SQL,需要开启哪些配置?
- A. 只开 general_log 就够了
- B. slow_query_log=ON、long_query_time=2、log_queries_not_using_indexes=ON
- C. 只看 error log 里的告警
- D. performance_schema=OFF 以降低开销
答案与解析
答案:B
慢日志默认只记录超过 long_query_time 的语句;log_queries_not_using_indexes=ON 才会额外记录未使用索引的语句。生产上开这个要配合 log_throttle_queries_not_using_indexes,否则小表全扫会把日志刷爆、磁盘写满。general_log 记录所有语句,开销大,只适合短时间排障。
21. 线上出现“所有查询突然都卡住、连最简单的 SELECT 都不返回”,最可能的原因是?
- A. 磁盘空间不足
- B. 有长事务未提交,长期持有元数据锁(MDL),导致后面的 DDL 拿不到排他 MDL 而堵塞,进而把该表上所有后续请求全部排队
- C. buffer pool 设置太小
- D. 网络带宽打满
答案与解析
答案:B
这是典型的 MDL 雪崩:一个大查询(或忘了提交的事务)持有表的 MDL 共享锁 → 有人执行 ALTER TABLE 排队等排他 MDL → 后面所有访问该表的语句都排在 ALTER 后面。表现就是“改个字段跑了半小时,整站挂了”。排查看 performance_schema.metadata_locks 的 OWNER_THREAD_ID,或用 sys.schema_table_lock_waits。
22. 想找出“哪类 SQL 模板累计耗时最高”,最直接的来源是?
- A. performance_schema.events_waits_current
- B. performance_schema.events_statements_summary_by_digest
- C. information_schema.TABLES
- D. mysql.slow_log
答案与解析
答案:B
events_statements_summary_by_digest 把 SQL 归一化成 digest(把常量替换成 ?)后做聚合,按 SUM_TIMER_WAIT 或 COUNT_STAR 排序就能立刻定位“哪类语句在吃数据库”。sys.statement_analysis 是对它的友好封装视图。慢日志能看单条,但看不出模板级的总量分布。
23. 希望所有死锁信息都自动写进错误日志(而不只是最近一次能用 SHOW ENGINE INNODB STATUS 看到),应开启?
- A. innodb_print_all_deadlocks=ON
- B. innodb_deadlock_detect=OFF
- C. log_error_verbosity=1
- D. 只能靠外部脚本轮询
答案与解析
答案:A
默认只有最近一次死锁保留在 SHOW ENGINE INNODB STATUS 的输出里,翻页就没了。innodb_print_all_deadlocks=ON 会把每次死锁的完整信息(两个事务的 SQL、持有和等待的锁)都写进 error log,是排查死锁必开的开关,开销很小。
查询优化
24. EXPLAIN 输出中 type 列为 ALL,意味着?
- A. 使用了主键等值查询
- B. 全表扫描,通常是需要重点优化的信号
- C. 使用了覆盖索引
- D. 使用了索引合并(index merge)
答案与解析
答案:B
type 的性能排序从好到差大致是:system > const > eq_ref > ref > range > index > ALL。ALL 是全表扫描,index 是扫整棵索引树(虽然不读表但仍要遍历全部索引项)。看到 ALL 先别急,小表几十行扫也无所谓;要看的是 rows 估算值和 filtered 比例。
25. 联合索引 (a, b, c),下面哪个 WHERE 条件能用上该索引?
- A. WHERE b = 1 AND c = 2
- B. WHERE a = 1 AND c = 2
- C. WHERE a = 1 AND b = 2
- D. WHERE c = 2
答案与解析
答案:C
最左前缀原则:必须从索引最左边的列开始连续匹配。WHERE a=1 AND c=2 只能用到 a 这一列(c 断了,跳不过 b);WHERE b=1 AND c=2 和 WHERE c=2 完全用不上。注意范围查询会截断后续列:WHERE a>1 AND b=2 里 b 无法用于索引定位,但仍可能被用于覆盖索引扫描。
26. 想在删除某个索引之前先验证“删掉会不会变慢”,8.0 的正确做法是?
- A. 直接 DROP INDEX,慢了再加回来
- B. ALTER TABLE … ALTER INDEX idx INVISIBLE 让优化器忽略它,观察一段时间后再决定是否真删
- C. 在 SQL 里加 hint 强行忽略索引
- D. 执行 OPTIMIZE TABLE 重建表
答案与解析
答案:B
不可见索引(8.0 新增)对优化器隐藏、但对写入仍然维护,所以随时可以 VISIBLE 一键回滚,不用重建立索引(大表重建可能要几十分钟)。这是做索引治理的标准流程:先 INVISIBLE 观察一周 → 无异常再 DROP。hint 只能管你自己写的 SQL,管不了别的应用发来的语句。
27. EXPLAIN ANALYZE 与普通 EXPLAIN 的关键区别是?
- A. 它会真正执行语句,输出各算子的实际耗时与实际返回行数
- B. 它只给出估算值,但格式更漂亮
- C. 它只能用于 DELETE 语句
- D. 两者输出完全一致,只是命令名不同
答案与解析
答案:A
EXPLAIN ANALYZE(8.0.18 起)会真实执行 SQL 并用 TREE 格式输出每个算子的 actual time 和 rows,可以和优化器的估算值直接对比——估算 rows=1 实际 rows=100000,说明统计信息不准,这才是定位性能问题的关键线索。注意它会真的跑一遍语句,别在生产上对慢 SQL 随便用。
28. 关于直方图(histogram)统计,下列说法正确的是?
- A. 只能对已建索引的列创建
- B. 可以对未建索引的列收集数据分布,改善优化器对选择性的估算;但需要手工 ANALYZE TABLE … UPDATE HISTOGRAM 更新
- C. 数据变化后会自动实时更新
- D. 仅支持数值类型,不支持字符串
答案与解析
答案:B
直方图最大的价值就是给没索引的列提供分布信息(比如 status 这种枚举列),让优化器知道“这个值只占 0.1%”从而选对连接顺序。它不会自动刷新,数据分布变了要重新收集;8.0.19 起持久化到数据字典(之前只在内存,重启即丢)。
29. 下列哪些写法会导致索引无法正常使用? (多选)
- A. WHERE DATE(create_time) = ‘2026-01-01’
- B. varchar 列与数字比较,如 WHERE phone = 13800138000
- C. WHERE name LIKE ‘%张’
- D. WHERE id = 100 ORDER BY id
答案与解析
答案:A、B、C
① 列上套函数会让 B+树的有序性失效,要改成范围条件 create_time >= '2026-01-01' AND create_time < '2026-01-02';② 隐式类型转换等价于对列做 CAST,同样失效——这是线上最高频的坑,参数类型必须和列类型一致;③ 前导通配符无法做前缀定位。④ 是主键等值查询加排序,索引完全可用。
备份恢复
30. mysqldump –single-transaction 能保证一致性的前提是?
- A. 使用 MyISAM 引擎
- B. 被备份的表是 InnoDB(依靠 REPEATABLE READ 快照),且备份期间没有并发的 DDL
- C. 必须先 FLUSH TABLES WITH READ LOCK 全程锁库
- D. 必须停止业务写入
答案与解析
答案:B
--single-transaction 在备份开始时开启一个可重复读事务,靠 MVCC 拿到一致性快照,全程不锁表、不阻塞写入。但两点限制:MyISAM 表不受 MVCC 保护,仍然不一致;备份期间如果有人做 DDL(比如 ALTER TABLE),会导致快照失效或备份失败。--master-data(8.0.26 起改名 --source-data)会记录备份起点的 binlog 位点,是 PITR 的关键。
31. 要做 PITR(时间点恢复)把库恢复到“今天 10:00 误删之前”的状态,必须准备什么?
- A. 只需要最新的一份全备
- B. 一份早于故障点的全备(含当时的 binlog 位点或 GTID)+ 从该位点到故障点的全部 binlog
- C. 只需要 binlog,不需要全备
- D. 只需要物理备份文件,不需要任何日志
答案与解析
答案:B
PITR 的标准流程:先恢复全备(它带着起点的 binlog 位点/GTID),再用 mysqlbinlog 把从那个起点到误操作之前的 binlog 重放一遍。缺任何一环都做不了。所以 binlog_expire_logs_seconds 别设太短,至少要覆盖“你发现故障所需的时间”。
32. binlog_format=ROW 且 binlog_row_image=MINIMAL 时,binlog 里记录的是?
- A. 整行的完整前镜像和后镜像
- B. 前镜像只记录主键/唯一键列,后镜像只记录实际被修改的列
- C. 不记录任何列值,只记录 SQL 语句
- D. 只能配合 STATEMENT 格式使用
答案与解析
答案:B
MINIMAL 大幅减小 binlog 体积,但代价是:某些依赖前镜像的操作用不了(比如带 WHERE 的 UPDATE/DELETE 在没有主键或唯一键时,从库无法定位行会报错),以及部分审计/闪回工具拿不到完整数据。FULL 记录整行前后镜像,最安全但也最大。生产上一般用 ROW + FULL。
33. 用 mysqlbinlog 重放时只重放指定的 GTID 集合,应使用?
- A. –start-position / –stop-position
- B. –include-gtids(配合 –skip-gtids 避免重复执行报错)
- C. –stop-datetime
- D. –database
答案与解析
答案:B
--include-gtids='uuid:1-100' 只重放该范围内的事务,--exclude-gtids 排除。--skip-gtids 让重放时不写 GTID(把语句当普通事务执行),常用于把数据导入到一个已经跑过这些 GTID 的实例上,否则会因 GTID 重复而跳过。--start-position 是按位点、--stop-datetime 是按时间,是老式做法。
34. MySQL Enterprise Backup 对 InnoDB 表做热备时,备份期间?
- A. 完全阻塞所有读写
- B. 仍然可以正常读写,备份通过跟踪 redo 保证一致性
- C. 只能在只读从库上执行
- D. 不支持增量备份,只能全备
答案与解析
答案:B
MEB 是物理热备工具,对 InnoDB 表在线备份,备份过程中业务可继续读写,通过记录备份期间的 redo 来保证恢复时的一致性。它支持增量备份(基于 LSN)、部分备份、单表恢复。社区版没有 MEB,替代方案是 Percona XtraBackup 或 mysqlsh util.dumpInstance(逻辑、并行、速度快)。
35. 下列哪些属于逻辑备份? (多选)
- A. mysqldump
- B. mysqlpump
- C. MySQL Shell 的 util.dumpInstance()
- D. MySQL Enterprise Backup(mysqlbackup)
答案与解析
答案:A、B、C
前三个导出的都是 SQL / TSV 文本,属逻辑备份:可读、可跨版本、能只恢复某张表,但 TB 级库很慢。MEB 直接复制数据文件页,是物理备份:快、适合大库,但版本与平台绑定,且只能用同版本恢复。8.0 里 mysqlpump 已边缘化,官方更推荐 mysqlsh 的 dump/load 工具(并行、压缩、支持增量)。
复制
36. 传统异步复制架构中,从库的 SQL 线程负责?
- A. 从主库拉取 binlog 并写入本地 relay log
- B. 读取 relay log 中的事件并应用到从库数据上
- C. 在从库上生成自己的 binlog
- D. 管理 GTID 集合
答案与解析
答案:B
三线程分工:主库的 dump 线程把 binlog 推给从库;从库的 IO 线程接收并写入 relay log;从库的 SQL 线程(8.0 多线程复制下是 worker 线程组)读取 relay log 并重放。瓶颈通常出在 SQL 线程(重放跟不上),这就是延迟的来源,也是要开并行复制的原因。
37. GTID 复制相比基于 binlog 位点的复制,最主要的优势是?
- A. 复制速度更快
- B. 故障切换时从库能自动定位已执行到哪个事务(auto-positioning),不需要人工计算 binlog 文件名和位点
- C. 不再需要 binlog
- D. 可以让 MyISAM 表也参与复制
答案与解析
答案:B
每个事务有全局唯一编号 server_uuid:事务序号,从库用 gtid_executed 就能表达“我执行过哪些”。主从切换时直接 CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION=1,从库自己去找差集,不用 DBA 手算位点——这是 GTID 最大的价值。代价是要开 enforce_gtid_consistency,一些老写法(如 CREATE TABLE … SELECT 在旧版本)会被限制。
38. 从库报错 1236(Got fatal error 1236 from source),最常见的原因是?
- A. 主库 binlog 已被 purge 删除,从库需要的起点事务在主库上已经不存在了
- B. 从库连接主库的密码错误
- C. 从库磁盘空间不足
- D. 主库端口不通
答案与解析
答案:A
1236 本质是“从库要的那个位点/GTID,主库找不到了”。典型场景:从库停机太久,主库的 binlog 已经按 binlog_expire_logs_seconds 清理掉。处理方式:重建从库(重新全备 + 追 binlog),或者在 GTID 模式下用 SET GTID_NEXT 注入空事务跳过——但后者有丢数据风险,只适合明确知道影响范围时用。密码错是 1045,端口不通是连接错误,别混淆。
39. 想保留一个“延迟一小时”的从库,用于误删操作后的快速回补,应设置?
- A. read_only=ON
- B. 在 CHANGE REPLICATION SOURCE TO 中设置 SOURCE_DELAY=3600
- C. relay_log_purge=OFF
- D. super_read_only=OFF
答案与解析
答案:B
SOURCE_DELAY(老名字 MASTER_DELAY)让 SQL 线程故意晚指定的秒数再重放。发现主库误删后,只要在一小时内把延迟从库的复制停掉,它还停在故障前的时间点,可以直接导数据回来,比 PITR 快得多。read_only 只防写入,跟延迟没关系。
40. 半同步复制中,rpl_semi_sync_source_timeout 超时之后主库会?
- A. 永久阻塞所有写入
- B. 自动降级为异步复制,等有从库追上后再自动恢复半同步
- C. 把超时的从库踢出集群
- D. 重启实例
答案与解析
答案:B
半同步的保证是“至少一个从库收到并写入 relay log 后才向客户端返回成功”。一旦等待超时(默认 10 秒),主库为了保证可用性会自动退化为异步复制继续服务,并记录 Rpl_semi_sync_source_timeout 状态。当从库追上后会自动切回半同步。所以半同步是“提高数据安全性”,但不等于零丢失。
41. 8.0 的多源复制中,如何区分来自不同主库的复制链路?
- A. 靠不同的端口号区分
- B. 用 FOR CHANNEL ‘通道名’ 显式指定通道,每条链路的 IO/SQL 线程和 relay log 相互独立
- C. 靠不同的复制账号区分
- D. 靠 relay_log 文件编号区分
答案与解析
答案:B
CHANGE REPLICATION SOURCE TO ... FOR CHANNEL 'ch1'、START REPLICA FOR CHANNEL 'ch1'。每条通道有独立的 relay log、独立的事务重放状态,可以分别启停和监控(performance_schema.replication_applier_status_by_worker 里有 CHANNEL_NAME 列)。常用于把多个业务库汇总到一台分析库。
42. 关于 GTID 复制,下列说法正确的有? (多选)
- A. 每个事务被赋予全局唯一编号,格式为 server_uuid:事务序号
- B. 开启 gtid_mode=ON 时必须同时开启 enforce_gtid_consistency=ON
- C. 从库设置 SOURCE_AUTO_POSITION=1 后能自动算出还缺哪些事务
- D. GTID 模式下可以随意跳过某个事务,不影响数据一致性
答案与解析
答案:A、B、C
GTID 只是给事务编号,跳过就意味着这部分数据永久缺失,一致性必然被破坏——虽然语法上可以用 SET GTID_NEXT 注入空事务“假装执行过”,但那是止损手段,不是无损操作。enforce_gtid_consistency 是硬前提,它禁掉那些无法用单个 GTID 安全表达的操作,否则编号会错乱。
高可用
43. Group Replication 中,一个事务要提交,需要多少节点认证通过?
- A. 只需本地节点
- B. 多数派(超过成员总数一半)认证通过
- C. 全部节点都必须通过
- D. 任意两个节点通过即可
答案与解析
答案:B
MGR 基于 Paxos 变体,事务在多数派节点上认证通过即可提交,不需要全部节点。这也是集群能容忍少数派故障的原因:3 节点容忍 1 台挂,5 节点容忍 2 台挂。反过来说,如果存活节点不过半数,整个组会停止接受写——这叫“失去多数派保护”,宁可不可用也不能脑裂。
44. InnoDB Cluster 由哪些组件构成?
- A. MySQL Server + Group Replication + MySQL Shell(AdminAPI) + MySQL Router
- B. MySQL Server + ProxySQL + Keepalived
- C. MySQL + Redis + Nginx
- D. MySQL + MHA + HAProxy
答案与解析
答案:A
四件套缺一不可:Group Replication 提供成员间的一致性复制和自动选主;MySQL Shell 的 AdminAPI(dba.createCluster() / cluster.addInstance() / cluster.status())负责编排;MySQL Router 对外提供读写/只读端口并自动感知拓扑变化。它是 Oracle 官方的一体化方案,不用自己拼 MHA、Keepalived。
45. MySQL Router 执行 –bootstrap 的作用是?
- A. 安装 MySQL Server
- B. 连接集群元数据,自动生成路由配置(读写端口、只读端口)并随拓扑变化自动更新,不需要手写配置文件
- C. 执行全量备份
- D. 监控慢查询
答案与解析
答案:B
mysqlrouter --bootstrap user@host:port 会去读集群的元数据表,生成 mysqlrouter.conf,默认给出 6446(读写)、6447(只读)、6448/6449(X Protocol)四个端口。之后集群主节点切换,Router 会自动把写请求转到新主,应用端完全无感——这是它比静态 HAProxy 配置强的地方。
46. MGR 单主模式下,主节点意外宕机且多数派仍然存活,集群会?
- A. 必须人工执行选主后才能恢复写入
- B. 自动选举出新的主节点,集群继续提供写入
- C. 整个集群进入只读状态直到原主恢复
- D. 自动切换为多主模式
答案与解析
答案:B
单主模式下主节点故障,只要剩余成员仍构成多数派,GR 会自动选出新主(基于成员权重和 UUID 顺序),新主自动设为可写。这正是 InnoDB Cluster 能做到分钟级(通常几秒到几十秒)故障恢复的原因。反例:如果只剩 1 台存活(不足多数派),集群就彻底拒绝写入了。
47. 网络分区导致某节点被隔离出少数派,该节点的行为是?
- A. 继续对外提供服务,只是变慢
- B. 被组内其他成员驱逐,进入 ERROR 状态,不再接受写请求
- C. 自动成为新的主节点
- D. 自动重启并重新加入
答案与解析
答案:B
多数派会把这个失联节点从组里踢掉(group_replication_member_expel_timeout 控制等待多久后驱逐)。被驱逐的节点状态变成 ERROR,此时它还活着但绝不能对外提供写(否则就脑裂了),需要人工或自动脚本执行 cluster.rejoinInstance() 让它重新加入并补齐数据。