【主机初始化工作】
一、初始化:
安装时:最小化【/boot,swap,/】
安装后:
1、配置固定IP
#!/bin/bash# 检查是否以root权限运行
if [ "$(id -u)" -ne 0 ]; thenecho "错误:此脚本需要以root权限运行。请使用sudo或切换到root用户。" >&2exit 1
fi# 提示用户输入IP地址和子网掩码
read -p "请输入要设置的IP地址和子网掩码(例如:192.168.1.100/24): " IP_ADDR# 验证IP地址格式(简单验证)
if ! [[ $IP_ADDR =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$ ]]; thenecho "错误:IP地址格式不正确。请使用类似192.168.1.100/24的格式。" >&2exit 1
fi# 提示用户输入网关
read -p "请输入要设置的网关地址(例如:192.168.1.1): " GATEWAY# 验证网关格式(简单验证)
if ! [[ $GATEWAY =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; thenecho "错误:网关地址格式不正确。请使用类似192.168.1.1的格式。" >&2exit 1
fi# 设置DNS服务器
DNS="114.114.114.114"echo "正在配置ens33网卡..."# 使用nmcli配置网络(适用于使用NetworkManager的系统)
if command -v nmcli &> /dev/null; then# 检查连接是否存在,如果存在则修改,否则创建if nmcli connection show "ens33" &> /dev/null; thennmcli connection modify ens33 ipv4.addresses $IP_ADDRnmcli connection modify ens33 ipv4.gateway $GATEWAYnmcli connection modify ens33 ipv4.dns $DNSnmcli connection modify ens33 ipv4.method manualnmcli connection up ens33elsenmcli connection add type ethernet con-name ens33 ifname ens33 ipv4.addresses $IP_ADDR ipv4.gateway $GATEWAY ipv4.dns $DNS ipv4.method manualnmcli connection up ens33fi
else# 如果没有nmcli,尝试直接修改接口(临时生效)echo "警告:未找到nmcli,将使用ifconfig临时配置网络(重启后失效)"ifconfig ens33 $IP_ADDRroute add default gw $GATEWAY ens33# 配置DNSecho "nameserver $DNS" > /etc/resolv.conf
fiecho "网络配置已完成,当前配置如下:"
echo "-------------------------"
ip addr show ens33 | grep inet
echo "网关: $GATEWAY"
echo "DNS: $DNS"
echo "-------------------------"
#!/bin/bash
# CentOS 7最小化安装基础配置脚本
# 需以root权限执行(sudo -i)
# 确保脚本在出错时退出
set -e
# 1. 系统更新与基础工具安装
echo "=== 开始系统更新和基础工具安装 ==="
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
yum install -y wget
wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
yum update -y
yum install -y \bash-completion \vim \net-tools \psmisc \unzip \ntpdate \tree \curl \bind-utils \sudo \git \lftp
# 2. 防火墙配置(允许SSH和HTTP/HTTPS,按需调整)
echo "=== 配置防火墙 ==="
systemctl stop firewalld && systemctl disable firewalld
# 立即生效且不重启系统
systemctl mask firewalld
iptables -F
# 清空当前 iptables 防火墙的所有规则
# 3. 时间同步配置
echo "=== 配置时间同步 ==="
if ntpdate ntp.aliyun.com; thenecho "时间同步成功"
elseecho "时间同步失败,请检查网络连接"
fi# 4. SELinux配置(临时关闭,如需永久关闭需修改配置文件)
echo "=== 临时关闭SELinux ==="
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config# 7. 清理缓存并完成配置
echo "=== 清理系统缓存 ==="
yum clean all
rm -rf /var/cache/yum/*echo "=== 基础配置完成!建议重启系统使配置生效 ==="
echo "重启命令:reboot"
#!/bin/bash
# 专用检查脚本:验证CentOS 7基础配置脚本执行结果
# 需以root权限执行# 定义颜色输出
GREEN="\033[0;32m"
RED="\033[0;31m"
NC="\033[0m" # 无颜色echo -e "\n===== 开始配置验证 ====="# 1. 检查yum源替换(阿里云)
echo -e "\n[1] 验证yum源配置"
base_repo="/etc/yum.repos.d/CentOS-Base.repo"
epel_repo="/etc/yum.repos.d/epel.repo"if grep -q "mirrors.aliyun.com" "$base_repo" && grep -q "mirrors.aliyun.com" "$epel_repo"; thenecho -e " ${GREEN}✓ 阿里云yum源配置正确${NC}"
elseecho -e " ${RED}✗ 错误:yum源未正确替换为阿里云${NC}"echo " 检查文件: $base_repo 和 $epel_repo"
fi# 2. 检查基础工具安装
echo -e "\n[2] 验证基础工具安装"
required_tools=("bash-completion" "vim-enhanced" "net-tools""psmisc" "unzip" "ntpdate" "tree""curl" "bind-utils" "sudo" "git" "lftp"
)missing=()
for tool in "${required_tools[@]}"; doif ! rpm -q "$tool" &>/dev/null; thenmissing+=("$tool")fi
doneif [ ${#missing[@]} -eq 0 ]; thenecho -e " ${GREEN}✓ 所有必需工具均已安装${NC}"
elseecho -e " ${RED}✗ 以下工具未安装:${missing[*]}${NC}"
fi# 3. 检查防火墙配置
echo -e "\n[3] 验证防火墙状态"
firewalld_active=$(systemctl is-active firewalld 2>/dev/null)
firewalld_enabled=$(systemctl is-enabled firewalld 2>/dev/null)
firewalld_masked=$(systemctl is-masked firewalld 2>/dev/null)
if [ "$firewalld_active" = "unknown" ] &&[ "$firewalld_enabled" = "masked" ] ;thenecho -e " ${GREEN}✓ 防火墙已关闭、禁用并锁定${NC}"
elseecho -e " ${RED}✗ 防火墙状态异常${NC}"echo " 运行状态: $firewalld_active (预期: unknown)"echo " 开机自启: $firewalld_enabled (预期: masked)"
fi
FIREWALLD_SERVICE="/etc/systemd/system/firewalld.service"echo "=== 检查 firewalld 是否被 mask ==="# 检查文件是否存在且为符号链接
if [ -L "$FIREWALLD_SERVICE" ]; then# 获取符号链接的目标路径LINK_TARGET=$(readlink "$FIREWALLD_SERVICE")# 检查目标是否为 /dev/nullif [ "$LINK_TARGET" = "/dev/null" ]; thenecho "✅ firewalld 已被 mask(单元文件链接到 /dev/null)"elseecho "❌ firewalld 是符号链接,但未指向 /dev/null(目标:$LINK_TARGET)"fi
else# 文件不存在或不是符号链接(未被 mask)echo "❌ firewalld 未被 mask(单元文件不存在或不是符号链接)"
fi
# 检查iptables规则
iptables_rules=$(iptables -L 2>/dev/null | wc -l)
if [ "$iptables_rules" -le 10 ]; then # 空规则通常小于10行echo -e " ${GREEN}✓ iptables规则已清空${NC}"
elseecho -e " ${RED}✗ iptables规则未清空${NC}"
fi# 4. 检查时间同步
echo -e "\n[4] 验证时间同步"
# 显示当前系统时间
current_time=$(date "+%Y-%m-%d %H:%M:%S")
echo " 当前系统时间: $current_time"# 5. 检查SELinux配置
echo -e "\n[5] 验证SELinux状态"
selinux_current=$(getenforce)
selinux_config=$(grep "^SELINUX=" /etc/selinux/config | cut -d= -f2)if [ "$selinux_current" = "Disabled" ] && [ "$selinux_config" = "disabled" ]; thenecho -e " ${GREEN}✓ SELINUX已临时关闭并永久禁用${NC}"
elseecho -e " ${RED}✗ SELINUX状态异常${NC}"echo " 当前状态: $selinux_current (预期: Permissive)"echo " 配置文件: $selinux_config (预期: disabled)"
fi# 6. 检查缓存清理
echo -e "\n[6] 验证缓存清理"
cache_dir="/var/cache/yum/"
if [ -z "$(ls -A $cache_dir 2>/dev/null)" ]; thenecho -e " ${GREEN}✓ 系统缓存已清理${NC}"
elseecho -e " ${RED}✗ 缓存目录未清空${NC}"echo " 剩余文件: $(ls -A $cache_dir | wc -l) 个"
fiecho -e "\n===== 验证完成 ====="
echo -e "提示:所有标${RED}✗${NC}的项需要重新配置"
echo -e "建议执行: reboot 使所有配置生效\n"
2、替换base源
阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区
- curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
- yum install -y wget
- wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
- epel-release:扩展软件源(很多工具需要依赖此源)
用途:提供官方源之外的大量常用软件包,比如 htop、iftop 等
安装:yum install -y epel-release
3、下载常用工具
- bash-completion:bash 命令自动补全工具(增强命令行输入效率,支持命令、参数、文件名等补全)
用途:输入命令 / 路径时按 Tab 键自动补全,减少手动输入错误,提升终端操作效率
安装:yum install -y bash-completion
- vim-enhanced:增强版 Vim 编辑器(比基础 vim 增加语法高亮、多级撤销、代码折叠等功能)
用途:编辑文本文件、代码(支持多种编程语言语法高亮)、配置文件等
安装:yum install -y vim-enhanced
- net-tools:传统网络工具集(包含 ifconfig、netstat、route 等经典网络命令)
用途:查看 / 配置网络接口信息(ifconfig)、查看网络连接状态(netstat)、管理路由表(route)等
安装:yum install -y net-tools
- psmisc:进程管理工具集(包含 pstree、killall、fuser 等实用命令)
用途:以树形展示进程关系(pstree)、按进程名批量终止进程(killall)、查看占用文件的进程(fuser)等
安装:yum install -y psmisc
- unzip:ZIP 格式解压缩工具(专门用于解压.zip 后缀的压缩文件)
用途:提取 ZIP 压缩包中的文件,支持查看压缩包内容、指定解压目录等
安装:yum install -y unzip
- ntpdate:网络时间同步工具(通过 NTP 服务器校准系统时间)
用途:手动同步服务器时间到公共 NTP 服务器(如ntpdate ntp.aliyun.com
)。
安装:yum install -y ntpdate
- tree:目录树形结构展示工具(以可视化树形图显示目录和文件层级关系)
用途:快速查看目录结构(如tree /home
),分析文件组织,生成目录文档等
安装:yum install -y tree
(1)网络相关
-
curl:网络请求工具(支持 HTTP/HTTPS 等,比 wget 功能更丰富)
用途:测试接口、下载文件、模拟请求等
安装:yum install -y curl
-
telnet:远程端口测试工具
用途:检测目标主机的端口是否开放(如telnet 192.168.1.1 80
)
安装:yum install -y telnet
-
traceroute:路由追踪工具
用途:查看数据包从本地到目标主机的路径(排查网络延迟 / 丢包节点)
安装:yum install -y traceroute
-
bind-utils:DNS 工具集(包含 nslookup、dig 等)
用途:解析域名、查询 DNS 记录(如dig www.baidu.com
)
安装:yum install -y bind-utils
(2)
-
gcc & gcc-c++:C/C++ 编译器
用途:编译源码包(如安装自定义软件时需要)
安装:yum install -y gcc gcc-c++
-
git:版本控制工具
用途:拉取代码仓库(如 GitHub 项目)、管理代码版本
安装:yum install -y git
-
lftp:文件传输工具
用途:通过 FTP、FTPS、SFTP 等协议进行文件上传 / 下载、管理远程文件目录、支持断点续传和批量操作
安装:yum install -y lftp
4、关闭SELinux
sestatus //查看当前 SELinux 状态
# 预计输出:
#SELinux status: enabled
#SELinuxfs mount: /sys/fs/selinux
#SELinux root directory: /etc/selinux
#Loaded policy name: targeted
#Current mode: enforcing
#Mode from config file: enforcing
#Policy MLS status: enabled
#Policy deny_unknown status: allowed
#Max kernel policy version: 31
setenforce 0 //临时关闭
# 改变的:Current mode: permissive
vim /etc/selinux/config
# 原配置 SELINUX=enforcing # 修改后 SELINUX=disabled
reboot
5、关闭防火墙
systemctl stop firewalld && systemctl disable firewalld #立即生效且不重启系统
systemctl stop firewalld #临时关闭防火墙(立即生效,重启后恢复)
systemctl status firewalld #验证是否已关闭:输出inactive
systemctl disable firewalld #永久关闭防火墙(重启后仍保持关闭)
systemctl is-enabled firewalld #验证是否永久禁用:disabled
systemctl mask firewalld # disable 只是禁止服务开机自启,但仍可通过 systemctl start firewalld 手动启动。mask 会创建一个指向 /dev/null 的符号链接替代服务的启动文件,使得无论是手动启动(start)还是开机自启,都会失败
iptables -F #清空当前 iptables 防火墙的所有规则
6、确认时间同步
date
# 输出:2025年 09月 06日 星期六 09:55:50 CST
ntpdate ntp.aliyun.com #阿里云NTP服务器
ntpdate time1.cloud.tencent.com # 腾讯NTP服务器
ntpdate pool.ntp.org # 公共NTP服务器池
#输出:6 Sep 09:56:16 ntpdate[1619]: adjust time server 203.107.6.88 offset 0.000684 sec
二、练习一:
完成如下环境中web服务的部署
- 主机环境规划
主机名规划方式,Sylvia-host-1,依次类推
hostnamectl set-hostname Sylvia-host-1
hostname
# sylvia-host-1
bash #重新加载当前终端的环境,让提示符立即显示新主机名
序号 | IP地址 | 主机名 | 角色分配 |
1 | 192.168.140.10 | Sylvia-host-0 | DNS/CA/中间件 |
2 | 192.168.140.11 | Sylvia-host-1 | web |
3 | 192.168.140.12 | Sylvia-host-2 | mysql-master |
4 | 192.168.140.13 | Sylvia-host-3 | mysql-slave |
5 | |||
6 |
-
所有主机配置ssh免密
[root@sylvia-host-0 ~] ssh-keygen -t rsa
[root@sylvia-host-0 ~] ls .ssh/
id_rsa id_rsa.pub# 将 host-0 的公钥(id_rsa.pub)添加到目标主机
[root@sylvia-host-0 ~] ssh-copy-id root@192.168.140.10 -p 12345
#如果不执行 ssh-copy-id root@192.168.140.10 -p 12345(不给 host-0 自己添加公钥),会导致其他主机(host-1/2/3)无法免密登录 host-0
[root@sylvia-host-0 ~] ssh-copy-id root@192.168.140.11
[root@sylvia-host-0 ~] ssh-copy-id root@192.168.140.12
[root@sylvia-host-0 ~] ssh-copy-id root@192.168.140.13# 将 host-0 的私钥复制到其他主机
[root@sylvia-host-0 ~] scp ~/.ssh/id_rsa root@192.168.140.11:.ssh/
# id_rsa 100% 1679 638.5KB/s 00:00
[root@sylvia-host-0 ~] scp ~/.ssh/id_rsa root@192.168.140.12:.ssh/
# id_rsa 100% 1679 128.9KB/s 00:00
[root@sylvia-host-0 ~] scp ~/.ssh/id_rsa root@192.168.140.13:.ssh/
# id_rsa 100% 1679 649.5KB/s 00:00 #若在 host-1 上执行 ssh-copy-id root@192.168.140.10 -p 12345 ,本质是将相同的共享公钥添加到 host-0 的 ~/.ssh/authorized_keys 中,这与在 host-0 上执行该命令的结果完全一致(因为公钥内容相同)。
- 所有主机配置计划任务,每隔2小时同步一次时间
[root@sylvia-host-0 ~] crontab -e
[root@sylvia-host-3 ~] crontab -l
# 0 */2 * * * /usr/sbin/ntpdate ntp.aliyun.com >/dev/null 2>&1
- 客户端通过DNS解析可正常访问网站
[root@sylvia-host-0 ~] vim /etc/named.conf
[root@sylvia-host-0 ~] vim /etc/named.rfc1912.zones
[root@sylvia-host-0 ~] vim /var/named/linux.com.zone
[root@sylvia-host-0 ~] named-checkconf #无输出,说明主配置文件(named.conf)没有语法错误
[root@sylvia-host-0 ~] named-checkzone linux.com /var/named/linux.com.zone
# zone linux.com/IN: loaded serial 4 成功加载区域文件,且文件中的序列号(Serial)为 4
# OK 区域文件无语法错误、记录格式正确,可以被 BIND 服务正常解析。
[root@sylvia-host-0 ~] systemctl restart named.service
-
在web服务器上部署网站wordpress
# 安装PHP 7.4
[root@sylvia-host-1 ~] yum install -y yum-utils # 安装工具包(提供yum-config-manager)
[root@sylvia-host-1 ~] rpm -Uvh https://rpms.remirepo.net/enterprise/remi-release-7.rpm
[root@sylvia-host-1 ~] ls /etc/yum.repos.d/remi-php74.repo # 应显示文件路径
# /etc/yum.repos.d/remi-php74.repo
[root@sylvia-host-1 ~] yum-config-manager --enable remi-php74 # 启用remi-php74仓库
[root@sylvia-host-1 ~] yum repolist enabled | grep remi-php74 # 验证仓库已启用
# * remi-php74: mirrors.tuna.tsinghua.edu.cn
# remi-php74 Remi's PHP 7.4 RPM repository for Enterprise Linux 7 - x 469
[root@sylvia-host-1 ~] yum install -y php php-fpm php-mysqlnd php-gd php-mbstring php-xml php-json php-opcache # 安装PHP 7.4及完整组件
[root@sylvia-host-1 ~] systemctl start php-fpm
[root@sylvia-host-1 ~] systemctl enable php-fpm
#Created symlink from /etc/systemd/system/multi-user.target.wants/php-fpm.service to /usr/lib/systemd/system/php-fpm.service.
[root@sylvia-host-1 ~] php -v #验证php版本
#PHP 7.4.33 (cli) (built: Jun 5 2024 05:05:14) ( NTS )
#Copyright (c) The PHP Group
#Zend Engine v3.4.0, Copyright (c) Zend Technologies
# with Zend OPcache v7.4.33, Copyright (c), by Zend Technologies
# 下载nginx
[root@sylvia-host-1 ~] wget https://nginx.org/download/nginx-1.26.2.tar.gz
[root@sylvia-host-1 ~] yum install -y gcc openssl-devel zlib-devel pcre-devel
[root@sylvia-host-1 ~] tar xf nginx-1.26.2.tar.gz
[root@sylvia-host-1 ~] cd nginx-1.26.2/
[root@sylvia-host-1 nginx-1.26.2] ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module
[root@sylvia-host-1 nginx-1.26.2] make && make install
[root@sylvia-host-1 nginx-1.26.2] vim /etc/rc.local
[root@sylvia-host-1 nginx-1.26.2] chmod a+X /etc/rc.d/rc.local
[root@sylvia-host-1 nginx-1.26.2] /usr/local/nginx/sbin/nginx
# 配置网站
[root@sylvia-host-1 nginx-1.26.2] vim /usr/local/nginx/conf/nginx.conf
include /usr/local/nginx/conf/conf.d/*.conf;
[root@sylvia-host-1 nginx-1.26.2] mkdir /usr/local/nginx/conf/conf.d
[root@sylvia-host-1 nginx-1.26.2] vim /usr/local/nginx/conf/conf.d/wordpress.conf
[root@sylvia-host-1 nginx-1.26.2] /usr/local/nginx/sbin/nginx -t
# nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
# nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@sylvia-host-1 nginx-1.26.2] /usr/local/nginx/sbin/nginx -s reload
server {listen 80;server_name wordpress.linux.com; root /usr/local/nginx/wordpress; location / {index index.php index.html;}location ~ \.php$ {fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;include fastcgi_params;}
}
# 下载wordpress
[root@sylvia-host-1 ~] lftp 10.11.0.254
lftp 10.11.0.254:~> cd software/wordpress/
lftp 10.11.0.254:/software/wordpress> get wordpress-6.6.2-zh_CN.zip
# 27309922 bytes transferred in 3 seconds (10.07M/s)
lftp 10.11.0.254:/software/wordpress> exit
[root@sylvia-host-1 ~] ls
# wordpress-6.6.2-zh_CN.zip
[root@sylvia-host-1 ~] unzip wordpress-6.6.2-zh_CN.zip
[root@sylvia-host-1 ~] ls
# wordpress wordpress-6.6.2-zh_CN.zip
[root@sylvia-host-1 ~] cp -ra wordpress/* /usr/local/nginx/wordpress/
Nginx:
- 主进程(master):root(负责启动和管理,不处理实际请求);
- 工作进程(worker):nobody
- 接收客户端请求;
- 读取静态文件(如
index.html
、图片、CSS、JS 等)并返回给浏览器; - 将 PHP 请求(
.php
文件)转发给 PHP-FPM 处理。 - 只需要 “读权限”(
r
),不需要写权限 —— 因为 Nginx 本身不修改文件,只负责传输已存在的内容。
PHP-FPM:
- 主进程(master):root(负责管理工作进程);
- 工作进程(pool www):apache(处理 PHP 代码执行、文件读写,如 WordPress 的上传 / 插件安装等)。
- 读取 PHP 代码文件(如
index.php
)并执行; - 与数据库交互(读取 / 写入数据);
- 对所有 WordPress 文件有 “读权限”(否则无法执行 PHP 代码);对需要写入的目录(如wp-content/及其子目录)有 “写权限”(w),其他核心文件(如wp-admin/、wp-includes/)保持只读即可(更安全)。
- 读取 PHP 代码文件(如
所以!
chown -R apache:apache /usr/local/nginx/wordpress
# 所有目录设置为755(所有者可读写执行,其他用户只读执行)
find /usr/local/nginx/wordpress -type d -exec chmod 755 {} \;
# 所有文件设置为644(所有者可读写,其他用户只读)
find /usr/local/nginx/wordpress -type f -exec chmod 644 {} \;
此时访问
-
数据库部署
- 补充:如何彻底删除 MySQL 相关的所有组件(包括服务、进程、配置文件和数据)
systemctl stop mysqld.service
netstat -tunlp | grep mysql # 无输出则表示进程已终止
rpm -qa | grep mysql # 列出所有包含"mysql"的包
# mysql-community-client-8.0.43-1.el7.x86_64
# mysql80-community-release-el7-11.noarch
# mysql-community-common-8.0.43-1.el7.x86_64
# mysql-community-libs-8.0.43-1.el7.x86_64
# mysql-community-icu-data-files-8.0.43-1.el7.x86_64
# mysql-community-libs-compat-8.0.43-1.el7.x86_64
# mysql-community-client-plugins-8.0.43-1.el7.x86_64
# mysql-community-server-8.0.43-1.el7.x86_64
rpm -qa | grep mariadb #部分系统可能用mariadb(MySQL的分支),也需要检查,可能无输出
yum remove -y mysql*rpm -qa | grep mysql # 列出所有包含"mysql"的包
rm -rf /var/lib/mysql # 删除数据目录(默认存储数据库文件,重要!会丢失所有数据)
rm -rf /etc/my.cnf /etc/my.cnf.d/ # 删除配置文件
rm -rf /var/log/mysqld.log /var/run/mysqld/ # 删除日志和临时文件(如有)ps -ef |grep mysql |grep -v grep #检查进程
netstat -tunlp | grep -E "3306|mysql" #检查端口
rpm -qa | grep -E "mysql|mariadb" #检查安装包
# 如果以上命令均无输出,说明 MySQL 已彻底删除。
- host-2和host-3都写,这里只写一个
[root@sylvia-host-2 ~] rpm -ivh https://repo.mysql.com/mysql80-community-release-el7.rpm
[root@sylvia-host-2 ~] yum install mysql-community-server -y
[root@sylvia-host-2 ~] vim /etc/my.cnf
- 1、创建逻辑卷,文件系统ext4,作为数据目录使用 (df -hT挂载信息截图)
[root@sylvia-host-2 ~] fdisk /dev/sdb
[root@sylvia-host-2 ~] pvcreate /dev/sdb1 /dev/sdb2 /dev/sdb6
# Physical volume "/dev/sdb1" successfully created.
# Physical volume "/dev/sdb2" successfully created.
# Physical volume "/dev/sdb6" successfully created.
[root@sylvia-host-2 ~] vgcreate vg_sdb /dev/sdb1 /dev/sdb2 /dev/sdb6
# Volume group "vg_sdb" successfully created
[root@sylvia-host-2 ~] lvcreate -L 8G -n lv_mysql vg_sdb
# Logical volume "lv_mysql" created.
[root@sylvia-host-2 ~] lvcreate -l 100%free -n lv_other vg_sdb
# Logical volume "lv_other" created.
[root@sylvia-host-2 ~] lvscan
# ACTIVE '/dev/vg_sdb/lv_mysql' [8.00 GiB] inherit
# ACTIVE '/dev/vg_sdb/lv_other' [<7.99 GiB] inherit
[root@sylvia-host-2 ~] mkfs -t ext4 /dev/vg_sdb/lv_mysql
[root@sylvia-host-2 ~] vim /etc/fstab
/dev/vg_sdb/lv_mysql /mysql_date ext4 defaults 0 0
[root@sylvia-host-2 ~]# mkdir /mysql_date
[root@sylvia-host-2 ~] chown -R mysql.mysql /mysql_date
[root@sylvia-host-2 ~] mount -a
[root@sylvia-host-2 ~] ls /mysql_date
# lost+found
[root@sylvia-host-2 ~] rm -rf /mysql_date/lost+found/
2、创建独立的硬盘,文件系统xfs,作为二进制日志存储目录 (df -hT挂载信息截图)
[root@sylvia-host-2 ~] mkfs.xfs /dev/sdc
[root@sylvia-host-2 ~] mkdir /mysql_logbin
[root@sylvia-host-2 ~] chown -R mysql.mysql /mysql_logbin
[root@sylvia-host-2 ~] vim /etc/fstab
/dev/sdc /mysql_logbin xfs defaults 0 0
[root@sylvia-host-2 ~] mount -a
3、数据库开启慢查询日志 (my.cnf配置文件核心内容截图)
主从服务器的区别
- 主服务器(如 host-2):
server-id = 2
(保持唯一即可) - 从服务器(如 host-3):
server-id = 3
(必须与主服务器不同)
其他配置(GTID、慢查询、日志路径等)主从保持一致即可。
[mysqld]
# 1. 基础标识与路径配置
server-id = 2 # 主服务器用2,从服务器用3(必须唯一)
datadir = /mysql_date # 数据目录(对应逻辑卷挂载点)
socket = /var/lib/mysql/mysql.sock
pid-file = /var/run/mysqld/mysqld.pid
log-error=/var/log/mysqld.log# 2. 慢查询日志配置(已要求开启)
slow_query_log = 1 # 启用慢查询日志
slow_query_log_file = /var/log/mysql/mysql-slow.log # 慢查询日志路径
long_query_time = 2 # 慢查询阈值(秒,超过此时间的查询会被记录)# 3. GTID主从复制核心配置(主从均需开启GTID)
gtid_mode = ON # 启用GTID模式
enforce_gtid_consistency = ON # 强制GTID一致性(确保事务符合GTID规范)
log_slave_updates = ON # 从服务器同步的事务也记录到自身二进制日志(支持角色切换)# 4. 二进制日志配置(主服务器必须,从服务器建议开启以便角色切换)
log_bin = /mysql_logbin/mysql-bin # 二进制日志路径(对应独立硬盘挂载点)
binlog_format = row # 二进制日志格式(row模式最安全,适合复制)
expire_logs_days = 7 # 二进制日志保留7天(避免占满磁盘)
[root@sylvia-host-3 ~] systemctl start mysqld
[root@sylvia-host-3 ~] systemctl enable mysqld
[root@sylvia-host-2 ~] grep -i password /var/log/mysqld.log
# 2025-09-06T08:16:12.649359Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: 8Znqrqm,feWf
[root@sylvia-host-2 ~] mysql -uroot -p'8Znqrqm,feWf'
mysql> alter user 'root'@'localhost' identified by "Su@548165";
mysql> flush privileges;
4、两台数据库间部署主从复制环境
主库(Master)配置与操作
-- 正确创建用户(一行或紧凑格式,避免特殊字符)
CREATE USER 'repl'@'192.168.140.12' IDENTIFIED WITH mysql_native_password BY 'Repl@548165';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.140.12';
-- 刷新权限(可选,确保立即生效)
FLUSH PRIVILEGES;
-- 查看主库二进制日志信息(记录File和Position,用于从库定位)
SHOW MASTER STATUS;
从库(Slave)配置与操作
-- 从库执行
CHANGE MASTER TOMASTER_HOST = '192.168.140.12', -- 主库IPMASTER_USER = 'repl', -- 复制用户(主库创建的repl)MASTER_PASSWORD = 'Repl@548165', -- 复制用户密码MASTER_PORT = 3306, -- 主库端口MASTER_LOG_FILE = 'mysql-bin.000003', -- 主库当前binlog文件名MASTER_LOG_POS = 197; -- 主库当前binlog位置
START SLAVE;
-- 检查同步状态(确保 Slave_IO_Running 和 Slave_SQL_Running 均为 Yes)
SHOW SLAVE STATUS\G
部署以GTID主从复制环境 (show slave status\G截图,要体现GTID信息)
-- 主从都查
mysql> show variables like '%gtid%';
# enforce_gtid_consistency ON
# gtid_mode ON--主库
-- 正确创建用户(一行或紧凑格式,避免特殊字符)
CREATE USER 'repl'@'192.168.140.12' IDENTIFIED WITH mysql_native_password BY 'Repl@548165';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.140.12';
-- 刷新权限(可选,确保立即生效)
FLUSH PRIVILEGES;
-- 查看主库二进制日志信息(记录File和Position,用于从库定位)
SHOW MASTER STATUS;
-- 从库
mysql> CHANGE MASTER TO-> MASTER_HOST='192.168.140.13',-> MASTER_USER='repl',-> MASTER_PASSWORD='Repl@548165',-> MASTER_AUTO_POSITION=1;
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G
补充:常见的GTID 事务执行冲突
典型错误原因:从库在启动 GTID 同步前,已有主库后续事务才会创建的对象(库 / 表 / 用户)。
GTID 的核心原则:
-
主从数据初始必须完全一致(可通过主库备份 + 从库恢复实现);
-
从库禁止手动执行写操作(所有写操作必须在主库执行,通过 GTID 同步)。
典型错误表现:Slave_SQL_Running: No,Last_SQL_Error 提示 “Worker failed executing transaction 'GTID 号 '”
-
错误码 1396:主库执行 CREATE USER/DROP USER,从库已有该用户(或无该用户),导致 GTID 事务重放失败。
-
错误码 1007:主库执行 CREATE DATABASE/CREATE TABLE,从库已存在同名库 / 表,GTID 事务执行时冲突。
典型错误表现:恢复备份时提示 ERROR 3546: @@GLOBAL.GTID_PURGED cannot be changed: the added gtid set must not overlap with @@GLOBAL.GTID_EXECUTED
案例:从库已执行过部分 GTID 事务(如 38e6c867...:1-319),而主库备份文件中的 GTID_PURGED 包含这些事务(如 1-320),恢复时两者重叠,MySQL 拒绝修改 GTID_PURGED。
一、错误码 1396:用户操作冲突(CREATE USER/DROP USER 失败)
场景 1:主库执行 CREATE USER 'xxx'@'xxx',从库已存在该用户
STOP SLAVE;
DROP USER IF EXISTS 'xxx'@'xxx';
FLUSH PRIVILEGES;
START SLAVE;
SHOW SLAVE STATUS\G
场景 2:主库执行 DROP USER 'xxx'@'xxx',从库无该用户
-- 跳过该 GTID 事务(从库无此用户,删除操作无意义,直接跳过):
STOP SLAVE;
SET GTID_NEXT='失败的GTID号';
BEGIN; COMMIT; -- 执行空事务,相当于跳过该 GTID
SET GTID_NEXT='AUTOMATIC'; -- 恢复自动 GTID 分配
START SLAVE;
SHOW SLAVE STATUS\G二、错误码 1007:库 / 表已存在冲突(CREATE DATABASE/CREATE TABLE 失败)
场景 1:主库执行 CREATE DATABASE db_name,从库已存在该库
STOP SLAVE;
DROP DATABASE IF EXISTS db_name;
START SLAVE;
场景 2:主库执行 CREATE TABLE db_name.tb_name,从库已存在该表
STOP SLAVE;
DROP TABLE IF EXISTS db_name.tb_name;
START SLAVE;
SHOW TABLES FROM db_name LIKE 'tb_name';三、根治方案:主从数据初始化对齐(避免重复冲突)
-- 如果频繁出现 1396/1007 错误,说明从库数据与主库长期不一致,建议通过 “主库全量备份 + 从库恢复” 彻底对齐数据:
-- 主库备份(含 GTID 信息):
mysqldump -u root -p --single-transaction --set-gtid-purged=ON --all-databases > master_backup.sql
-- 从库清除旧数据和 GTID 历史:
STOP SLAVE;
RESET MASTER; -- 清空从库 GTID 记录
DROP DATABASE IF EXISTS 冲突库名; -- 清除所有已知冲突库
RESET SLAVE ALL;
-- 验证 GTID 是否已清空(执行后应返回空值)
SELECT @@GLOBAL.GTID_EXECUTED;
SELECT @@GLOBAL.GTID_PURGED;
mysql -u root -p < /tmp/master_backup.sql
-- 登录从库 MySQL
mysql -u root -p
RESET SLAVE ALL;
CHANGE MASTER TOMASTER_HOST='主库IP',MASTER_USER='repl',MASTER_PASSWORD='密码',MASTER_AUTO_POSITION=1;
START SLAVE;
SHOW SLAVE STATUS\G
5、在主从复制环境运行正常情况下,切换主从角色,并将前端业务切换连接到新主服务器,保证业务可正常访问 (业务数据库连接信息配置文件截图)
-- 新主库(13)执行
mysql> STOP SLAVE;
mysql> RESET SLAVE ALL;
CREATE USER 'repl'@'192.168.140.12' -- 允许旧主库IP(12)连接
IDENTIFIED WITH mysql_native_password BY 'Repl@548165';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.140.12';
FLUSH PRIVILEGES;
-- 旧主库(192.168.140.12)执行
CHANGE MASTER TOMASTER_HOST = '192.168.140.13', -- 新主库IPMASTER_USER = 'repl', -- 新主库创建的repl用户(授权给192.168.140.12)MASTER_PASSWORD = 'Repl@548165', -- 复制用户密码MASTER_PORT = 3306, -- 新主库端口MASTER_LOG_FILE = 'mysql-bin.000005', -- 新主库当前binlog文件名MASTER_LOG_POS = 893; -- 新主库当前binlog位置-- 启动复制
START SLAVE;-- 检查同步状态(确保 Slave_IO_Running 和 Slave_SQL_Running 为 Yes)
SHOW SLAVE STATUS\G
mysql> create user 'word'@'192.168.140.1' identified by 'Word@548165';
Query OK, 0 rows affected (0.01 sec)mysql> create database word_db CHARACTER SET utf8mb4 ;
Query OK, 1 row affected (0.02 sec)mysql> GRANT ALL PRIVILEGES ON word_db.* TO 'word'@'192.168.140.1';
Query OK, 0 rows affected (0.00 sec)mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| word_db |
| wordpress |
+--------------------+
6 rows in set (0.02 sec)
6、在数据库中间件服务器上对后端数据库进行读写分离配置,并确认正常 (读写分离测试效果截图)
mysql> CREATE USER IF NOT EXISTS 'proxyuser'@'192.168.140.10' IDENTIFIED BY 'Proxy@548165';
Query OK, 0 rows affected (0.03 sec)mysql> GRANT ALL PRIVILEGES ON word_db.* TO 'proxyuser'@'192.168.140.10';
Query OK, 0 rows affected (0.01 sec)mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)mysql> create user 'health'@'192.168.140.10' identified by 'Health@548165';
Query OK, 0 rows affected (0.01 sec)mysql> grant select on *.* to 'health'@'192.168.140.10';
Query OK, 0 rows affected (0.00 sec)mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)mysql> select user,host from mysql.user;
+------------------+----------------+
| user | host |
+------------------+----------------+
| word | 192.168.140.1 |
| health | 192.168.140.10 |
| proxyuser | 192.168.140.10 |
| repl | 192.168.140.12 |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+----------------+
8 rows in set (0.00 sec)
[root@host-10 ~]# systemctl start proxysql
[root@host-10 ~]# netstat -tunlp |grep 6032
tcp 0 0 0.0.0.0:6032 0.0.0.0:* LISTEN 1343/proxysql
[root@host-10 ~]# netstat -tunlp |grep 6033
tcp 0 0 0.0.0.0:6033 0.0.0.0:* LISTEN 1343/proxysqlmysql> insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(1,"192.168.140.13",3306,1,"write group");
mysql> insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(2,"192.168..140.12",3306,1,"read group");
mysql> load mysql servers to runtime;
mysql> save mysql servers to disk;
mysql> load mysql users to runtime;
mysql> save mysql users to disk;
mysql> SELECT hostgroup_id, hostname, port, status FROM mysql_servers;
+--------------+----------------+------+--------+
| hostgroup_id | hostname | port | status |
+--------------+----------------+------+--------+
| 1 | 192.168.140.13 | 3306 | ONLINE |
| 2 | 192.168.140.12 | 3306 | ONLINE |
+--------------+----------------+------+--------+mysql> DELETE FROM mysql_query_rules WHERE rule_id IN (1, 2,3);mysql> INSERT INTO mysql_query_rules (rule_id, active, match_digest,destination_hostgroup,apply)
VALUES (1,1,'^INSERT|^UPDATE|^DELETE|^REPLACE|^SELECT .* FOR UPDATE',1, 1);
mysql> INSERT INTO mysql_query_rules (rule_id, active, match_digest, destination_hostgroup, apply) VALUES (2,1,'^SELECT',2,1);LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;mysql> SET mysql-monitor_username = 'health';
mysql> SET mysql-monitor_password = 'Health@548165';
mysql> LOAD MYSQL VARIABLES TO RUNTIME;
mysql> SAVE MYSQL VARIABLES TO DISK;
7、将前端业务的数据库连接切换到中间件服务器,保证业务可正常访问(业务中间件连接信息配置文件截图)
8、将业务数据库备份到独立的存储设备 (备份命令、以运行结果截图)
# 确认独立存储设备已挂载(假设挂载路径为 /mnt/backup_disk)
df -h | grep /mnt/backup_disk
mysqldump -u root -p --single-transaction --set-gtid-purged=ON wordpress | gzip >
ls -lh /mnt/backup_disk/ | grep wordpress
# -rw-r--r-- 1 root root 1.5M 9月 19 16:30 wordpress_20250919_163022.sql.gz
# 查看压缩文件内容(前10行)
zcat /mnt/backup_disk/wordpress_20250919_163022.sql.gz | head -n 10
编写脚本
1、每隔1分钟,检测web服务的运行状态,运行正常则输出1,否则输出0
2、编写脚本,检测从库和主库间是否存在延时
3、编写脚本,检测从库IO、SQL线程的状态
4、编写脚本,检测主库的连接数,连接数超时10显示警告,否则显示正常