MySQL安全加固与主从复制排查:运维面试核心实战指南
简介面向运维工程师的面试题整理与答案详解聚焦互联网行业运维岗位的高频考点覆盖数据库安全提升、主从复制原理与配置、用户权限管理、备份脚本、Web日志统计、Linux启动过程、常见端口服务以及服务器中毒排查等主题。全文以问答形式给出问题和解决思路并配有具体命令适合参加面试的应届生、转岗人员以及希望查漏补缺的在职运维阅读。资源共1个docx文件大小27KB体积小巧下载后可直接阅读或打印。已有198人学习下载。内容具体包括修改数据库默认端口、防火墙限制访问、复杂密码与特权账号管理、主从复制三个步骤、用户授权语法、数据库备份打包脚本、统计访问来源前10的Shell命令、引导加载流程等答案简明可操作性强从数据库到网络服务从系统启动到安全加固能帮助读者建立系统化运维面试知识框架。1. 运维面试题里藏着的工作习惯比答案更值得拆运维工程师面试题里最容易被低估的是那些看似能十分钟答完的开放题。新装 MySQL 怎么提升安全级别、主从复制延迟怎么降、nginx 日志怎么统计 top IP每道题回答的深度直接暴露候选人是在生产环境里处理过问题还是只刷过题库。这套面试题覆盖的场景相当完整MySQL 加固与复制、备份脚本、日志统计、Linux 启动流程、病毒处置、监控与调优选型。它们共同指向一个能力判断——当数据库被扫描器盯上、网站响应突然变慢、服务器异常向外发包时你能否按优先级把影响面控制在最小。接下来的章节按题目涉及的模块逐个展开每一节都会给出可以直接抄走的命令和参数并说明这些命令为什么有效、在什么场景下会失效。2. MySQL 安全基线从端口、账号到日志的加固顺序2.1 修改默认端口与 iptables 联动MySQL 安装完成后默认监听 3306 端口互联网上针对数据库的扫描器会优先探测这个端口。常见的加固手段是修改默认端口但只改端口会带来两个副作用应用连接串要同步修改而且端口扫描器同样会覆盖高位端口。所以更稳妥的思路是端口与防火墙联动只放行已知来源的 IP 段。我一般会在 my.cnf 中做如下配置[mysqld] port 3307 bind-address 192.168.1.20重启 MySQL 后监听端口变为 3307。bind-address 设置为内网 IP 而不是 0.0.0.0可以让 MySQL 只响应内网网卡的请求公网接口直接无法触达。此时再用 iptables 做第二层限制iptables -A INPUT -p tcp --dport 3307 -s 192.168.1.0/24 -j ACCEPT iptables -A INPUT -p tcp --dport 3307 -j DROP iptables-save /etc/sysconfig/iptables第一条规则放行 192.168.1.0/24 网段访问 3307第二条规则丢弃其他来源的包。规则顺序很重要ACCEPT 必须出现在 DROP 之前因为 iptables 按顺序匹配一旦先命中 DROP后续的放行规则不会生效。iptables-save 用于持久化但不同发行版保存路径有差异Ubuntu 使用 netfilter-persistent 命令。2.2 账号权限最小化GRANT 与 root 限制权限收紧的核心是让每个账号只拥有完成本职工作所需的最小权限。原题给了一条典型的 GRANT 语句正确的写法是对库名和表名使用点号连接GRANT SELECT, INSERT, UPDATE, DELETE ON book.* TO test2localhost IDENTIFIED BY abc; FLUSH PRIVILEGES;book.*表示 book 库下所有表test2localhost限定只能从本机登录IDENTIFIED BY abc设置初始密码。注意原题中写成book *是笔误实际执行会报语法错误。FLUSH PRIVILEGES 用来让授权表立即生效使用 GRANT 语句创建账号后其实会自动刷新但在批量导入授权语句时显式执行更稳妥。root 账号的处理是面试考点。先检查 root 的允许登录主机SELECT user, host, plugin FROM mysql.user WHERE user root;如果 host 列出现%说明 root 允许远程登录需要修正为只允许 localhostUPDATE mysql.user SET host localhost WHERE user root; FLUSH PRIVILEGES;生产实践中我还会单独创建一个仅用于备份的账号只授予 SELECT、LOCK TABLES、RELOAD、PROCESS 权限避免备份脚本直接使用 root。备份账号的权限适当放开到能执行 SHOW MASTER STATUS 和一致快照即可。2.3 日志开启与数据目录权限控制二进制日志和慢查询日志的开启直接关系到故障恢复能力和性能问题定位。MySQL 主从复制依赖 binlog误删数据后也能利用 binlog 做时间点恢复。慢查询日志则是优化 SQL 的第一手素材。推荐的最小配置如下[mysqld] log-bin /data/mysql/logs/mysql-bin slow_query_log ON slow_query_log_file /data/mysql/logs/slow.log long_query_time 2log-bin 指定二进制日志文件路径slow_query_log 打开慢查询记录long_query_time 设置阈值超过 2 秒的查询会被写入 slow.log。日志目录权限同样不能忽略如果 MySQL 进程无法读写日志目录会导致实例启动失败或写入报错。mkdir -p /data/mysql/logs chown -R mysql:mysql /data/mysql/logs chmod 700 /data/mysql/logs chmod 700 /data/mysql/datachown 将日志目录属主改为 mysql 用户chmod 700 表示只有属主可读写执行。数据目录权限收紧到 700避免其他系统账号读取数据文件。这里有一个常见误区chmod 递归执行到数据文件和日志文件上可能影响 MySQL 对文件的访问所以目录用 700、文件保持 640 是更精细的做法。2.4 清理无用账号与 test 库新安装的 MySQL 默认带有匿名账号和 test 库这是生产环境必须清理的对象。匿名账号意味着任何本地用户都可以无密码登录test 库则是攻击者存放临时数据的常用位置。DROP DATABASE IF EXISTS test; DROP USER IF EXISTS localhost; DROP USER IF EXISTS %;执行完成后用SELECT user, host FROM mysql.user;复查一遍。MySQL 5.7 之后默认不再自动创建 test 库但通过旧版本升级上来的实例仍然可能残留。结合前面几步安全加固的完整顺序可以整理成一张表配置项推荐值作用port3307 或其他高位端口规避默认端口扫描bind-address内网 IP 或 127.0.0.1减少网络暴露面iptables 规则仅放行业务网段网络层访问控制root hostlocalhost禁止 root 远程登录应用账号按库授权最小权限降低被注入后的风险log-binON支撑复制与恢复slow_query_logON慢 SQL 定位数据目录权限700 / 属主 mysql防止数据文件被读取这些操作做完后MySQL 的安全基线基本达标。但基线只是静态起点主从复制场景下还有链路本身的参数需要关注。3. 主从复制原理、配置文件与延迟排查3.1 三线程协作模型与日志位置记录MySQL 主从复制的根基是 binlog 和 relay log 的配合。整体流程可以拆成三个步骤主库把数据变更写入 binlog从库的 I/O 线程拉取这些 binlog 事件写到本地 relay log从库的 SQL 线程读取 relay log 并重放。三个角色缺一不可。从库的 I/O 线程连接主库时会带上两个关键信息要读取的 binlog 文件名和起始位置。主库收到请求后由 binlog dump 线程从指定位置读取日志并返回。从库 I/O 线程把收到的日志依次写入 relay log 尾部同时将主库文件名和位置记录到 master-info 文件中这样下次重连时能继续从断点拉取。SQL 线程检测到 relay log 有新增内容后解析其中的事件并在从库上执行。这里有一个面试官常追问的细节master-info 默认存储在数据目录下位置参数在 MySQL 5.6 之前是master.info文件5.6 之后默认写入mysql.slave_master_info表。如果文件损坏或表数据异常从库重启后可能无法定位断点所以对复制状态的监控不只是看线程是否在跑。3.2 主从配置文件的参数选择主库侧的 my.cnf 配置[mysqld] server-id 1 log-bin mysql-bin binlog-do-db bookslave 侧的 my.cnf 配置[mysqld] server-id 2 relay-log relay-bin read_only ONserver-id 在整个复制拓扑中必须唯一否则从库会报主键冲突或复制中止。binlog-do-db 限制只记录指定库的变更但生产环境我一般不在主库配置这个参数原因在于跨库事务如果事务同时涉及 book 库和其他库binlog-do-db 的记录会出现不完整从库重放时反而报错。常见做法是把过滤逻辑放在从库的 replicate-ignore-db 上。read_only 参数需要特别说明它只对普通账号生效拥有 SUPER 权限的 root 依然可以写入。所以 read_only 挡不住误操作 root 的人真正要配合的是前面提到的 root 仅允许本地登录。从库上开启 read_only能在日常运维中减少人为写入从库导致的数据不一致。3.3 复制状态检查与常见故障复制搭建完成后验证工作比搭建本身更重要。主库上执行SHOW MASTER STATUS;查看当前 binlog 文件和位置从库上执行SHOW SLAVE STATUS\G重点关注三个字段的输出字段正常状态异常状态Slave_IO_RunningYesConnecting / NoSlave_SQL_RunningYesNoSeconds_Behind_Master0持续增大I/O 线程异常时先检查网络连通性和主库的授权账号SELECT user, host FROM mysql.user WHERE user repl;确认复制账号是否存在、host 是否匹配。SQL 线程异常时SHOW SLAVE STATUS\G中会有 Last_SQL_Error 字段给出具体报错常见的是主键冲突或表不存在需要手工处理后执行STOP SLAVE; START SLAVE;重新拉起。Seconds_Behind_Master 这个指标有一个容易被忽略的点它表示的是从库 SQL 线程相对 I/O 线程已拉取日志的延迟而不是绝对时间延迟。如果 I/O 线程本身就落后这个值可能不准确。所以监控延迟时我会同时比较主库的 binlog 位置和从库已重放的位置来确定真实差距。3.4 延迟原因定位与参数调整延迟是面试题中最常出现的问题也是生产环境高频告警项。整理成一张排查表方便对照延迟原因排查方法优化手段从库硬件性能差top、iostat 查看负载升级硬件或增加从库单线程复制瓶颈主库 binlog 量过大开启多线程复制MTS大事务 / 慢 SQL慢查询日志、SHOW PROCESSLIST优化 SQL拆分大事务网络延迟ping、iftop 观察链路减少跳数调整重连参数MySQL 5.6 之后支持多线程复制可以在从库配置[mysqld] slave_parallel_workers 4 slave_parallel_type LOGICAL_CLOCKslave_parallel_workers 设置并行重放的线程数LOGICAL_CLOCK 模式允许同一时间点提交的事务并行执行对写并发较高的场景提升明显。但要注意并行复制不是万能的如果主库本来就是串行写入的大事务从库并行线程再多也无法缩短重放时间。另外一组参数用于应对网络抖动slave-net-timeout 30 master-connect-retry 10slave-net-timeout 表示从库读取主库数据失败后等待多久重新建立连接默认 3600 秒太长生产环境通常调到 30 秒以内。master-connect-retry 是连接失败后重试的间隔默认 60 秒调小到 10 秒可以更快恢复中断的复制链路。修改这两个参数后需要重启从库的复制线程生效STOP SLAVE; START SLAVE;即可。4. 备份脚本、日志统计与系统排查实操4.1 数据库备份脚本与远程传输备份是运维的底线能力面试题中给的是 mount 远程目录再拷贝的方式完整脚本可以这样写#!/bin/bash BACKUP_DIR/data/backup REMOTE_MOUNT/mnt/backup DB_IP127.0.0.1 DB_USERbackup DB_PASSBackup123 DATE$(date %F_%H%M) mkdir -p ${BACKUP_DIR} /usr/local/mysql/bin/mysqldump \ -h${DB_IP} -u${DB_USER} -p${DB_PASS} \ --single-transaction --master-data2 book \ ${BACKUP_DIR}/book_${DATE}.sql tar czf ${BACKUP_DIR}/book_${DATE}.sql.tar.gz -C ${BACKUP_DIR} book_${DATE}.sql mount -t nfs 192.168.1.10:/backup ${REMOTE_MOUNT} cp ${BACKUP_DIR}/book_${DATE}.sql.tar.gz ${REMOTE_MOUNT}/ umount ${REMOTE_MOUNT} find ${BACKUP_DIR} -type f -mtime 7 -exec rm -f {} \;mysqldump 的参数是关键。--single-transaction在 InnoDB 引擎下开启一个一致快照备份过程中不会锁表在线备份的主力参数。--master-data2会在备份文件头部写入 binlog 文件名和位置并且以注释形式呈现既不干扰恢复又方便搭建新的从库。如果不加这个参数备份恢复后想在时间点上继续追加增量日志会缺少起点。远程传输使用 NFS 挂载是原题做法但实际场景我更推荐 rsync。NFS 适合整目录共享而备份文件通常只需要增量推送rsync -avz --timeout60 /data/backup/ rsync192.168.1.10::backup/ --password-file/etc/rsync.passrsync 的优势在于断点续传和增量同步备份文件越大优势越明显。find 命令清理 7 天前的备份防止磁盘被占满。清理策略要结合保留周期需求调整有些业务要求保留 30 天就改成-mtime 30。4.2 nginx 日志统计 TOP IP 命令拆解nginx 访问日志统计来源 IP 前 10 名一道经典管道命令题awk {a[$1]} END {for (j in a) print a[j], j} \ /home/logs/nginx/default/access.log | sort -nr | head -10$1是 access.log 中的客户端 IP 字段a[$1]以 IP 为键累加计数。END模块在文件处理完后执行遍历数组打印每个 IP 的出现次数。sort -nr按数字倒序排列head -10截取前 10 行。这里有一个细节sort 的 -n 参数必须存在否则 sort 会按字典序处理数字10 会排到 9 前面。如果面试题要求写一个脚本还可以把结果输出到文件并触发告警#!/bin/bash LOG_FILE/home/logs/nginx/default/access.log awk {a[$1]} END {for (j in a) print a[j], j} ${LOG_FILE} \ | sort -nr | head -10 /tmp/top_ip.txt统计之外要思考一个问题IP 访问量突增不一定是坏事可能只是 CDN 的回源请求也可能是爬虫或攻击。所以拿到 top IP 后我会用grep 10.0.0.88 /home/logs/nginx/default/access.log | tail -20查看该 IP 的具体请求路径判断是正常业务还是异常流量。4.3 Linux 启动过程与端口服务对应启动过程是面试题里相对固定的知识点完整的顺序是BIOS 或 UEFI 自检并读取启动设备从 MBR 或 EFI 分区加载 GRUB 引导管理器GRUB 把内核与 initramfs 加载到内存内核挂载根文件系统随后 systemd 作为 1 号进程接管系统初始化读取 default.target 启动对应服务。排查启动慢的机器时systemd-analyze blame可以列出每个服务的启动耗时。端口对应的服务是运维的基本功端口服务常见场景21FTP文件传输22SSH远程登录23Telnet明文远程登录生产环境不推荐25SMTP邮件发送110POP3邮件接收143IMAP邮件同步873rsync增量同步备份3306MySQL数据库服务原题中把 snmp 混在端口列举里snmp 实际默认使用 161 端口面试回答时点出这一处笔误能体现对细节的把握。日常维护用到ss -tlnp来确认端口监听状态比如检查 MySQL 是否在预期端口启动。4.4 病毒处置与开机启动项排查Linux 服务器中毒的典型特征是 CPU 使用率飙升、异常连接外网、计划任务被注入。排查顺序建议固定下来top # 按 CPU 排序定位高占用进程 ps aux # 查看可疑进程的启动命令和路径 netstat -antp # 查看建立外联的 IP 和端口 crontab -l # 检查当前用户计划任务 chkconfig --list | grep 3:on # 检查开机自启服务 more /etc/rc.local # 检查自启动脚本遇到删掉又自动重新创建的可疑文件单点删除没有意义要找到父进程。流程是top 定位高 CPU 进程记录 PIDls -l /proc/PID/exe查看可执行文件真实路径再ps aux | grep PPID找父进程。杀掉整个进程树之后删除文件最后检查 crontab 和 rc.local 中是否有定时下载并执行的脚本。在此基础上chkrootkit和rkhunter可以辅助检测 rootkit 痕迹chkrootkit rkhunter --check --skip-keypress这类工具检测的是已知特征生产环境更可靠的依赖是平时的文件校验基线。对二进制文件和关键配置文件计算 SHA-256 存到安全位置异常时比对即可快速发现篡改。5. 把面试要点变成 MySQL 加固与复制一键自检脚本面试题里的知识点如果不能落成日常检查手段回答得再完整也会在半年后遗忘。我把前面章节的核心验证项合并成一个自检脚本适用于接手新服务器时的快速摸底#!/bin/bash # mysql_self_check.sh # 用法: MYSQL_PWDxxxxxx ./mysql_self_check.sh MYSQL_CMDmysql -uroot -e echo --- 1. MySQL 监听端口与地址 --- ss -tlnp | grep -E :(3306|3307) || echo 未检测到 MySQL 监听 echo --- 2. root 账号可登录主机 --- ${MYSQL_CMD} SELECT user, host FROM mysql.user WHERE userroot; echo --- 3. binlog 与慢查询日志开关 --- ${MYSQL_CMD} SHOW VARIABLES WHERE Variable_name IN (log_bin,slow_query_log,long_query_time); echo --- 4. 复制线程状态 --- ${MYSQL_CMD} SHOW SLAVE STATUS\G 2/dev/null \ | grep -E Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master echo --- 5. 大于 1000 行的无主键 InnoDB 表 --- ${MYSQL_CMD} SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_ROWS FROM information_schema.TABLES t WHERE t.ENGINEInnoDB AND t.TABLE_ROWS 1000 AND t.TABLE_SCHEMA NOT IN (mysql,information_schema,performance_schema) AND NOT EXISTS ( SELECT 1 FROM information_schema.STATISTICS s WHERE s.TABLE_SCHEMA t.TABLE_SCHEMA AND s.TABLE_NAME t.TABLE_NAME AND s.INDEX_NAME PRIMARY );脚本第 1 步确认监听端口是否符合预期防止 iptables 规则加上了但 MySQL 还在 3306 裸奔。第 2 步输出 root 账号的 host 列表看到%就要警惕。第 3 步核对 binlog 和慢查询日志开关这两个配置要求重启才能生效所以光看 my.cnf 不够必须以运行时的变量值为准。第 4 步直接输出复制线程状态是判断主从是否健康的最短路径。第 5 步是我额外加的无主键表检查主从复制下无主键表的 DELETE 和 UPDATE 在从库重放时可能全表扫描延迟往往从这里开始。把脚本放到 crontab 每天执行并输出到日志0 6 * * * MYSQL_PWDxxxxxx /usr/local/bin/mysql_self_check.sh /var/log/mysql_self_check.log 21接手一套新环境时先跑一遍能快速定位哪些配置需要调整。面试里口头描述的安全加固和复制排查本质上就是这些检查项的反复执行。真正拉开运维水平的差距就在于是不是把答案变成了可重复运行的脚本和验证流程。本文还有配套的精品资源点击获取