【Devops】Debian12安装MySQL8

315 阅读5分钟

准备源(这里使用的清华源)

源URL:点击跳转

# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware 
# 以下安全更新软件源包含了官方源与镜像站配置,如有需要可自行修改注释切换
deb https://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware

额外配置

下面报错是因为debian12 默认使用的libssl3,而 MySQL 包需要 libssl1.1

root@mysql2:/mnt# apt install mysql-server
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 mysql-community-client : Depends: libssl1.1 (>= 1.1.1) but it is not installable
                          Depends: mysql-community-client-core (= 8.0.37-1debian11) but it is not going to be installed
 mysql-community-server-core : Depends: libssl1.1 (>= 1.1.1) but it is not installable
                               Recommends: mecab-ipadic-utf8 but it is not going to be installed
E: Unable to correct problems, you have held broken packages.

安装 libssl1.1

# 添加 Debian 11 (bullseye) 源以获取 libssl1.1
echo "deb http://mirrors.tuna.tsinghua.edu.cn/debian bullseye main" > /etc/apt/sources.list.d/bullseye.list

# 更新包列表
apt update

# 安装 libssl1.1
apt install libssl1.1 -y

# 删除 bullseye 源(安装完成后)
rm /etc/apt/sources.list.d/bullseye.list
apt update

安装mysql

wget https://repo.mysql.com/mysql-apt-config_0.8.29-1_all.deb
apt install gnupg2 -y
dpkg -i mysql-apt-config_0.8.29-1_all.deb
apt update
apt install mysql-community-server mysql-community-client -y

主从配置

这里我的主库的数据位置在trueNas下的ssd池中,从库数据存取位置在trueNas下的hdd池中,所以我主库位置在/mnt/mysql_master,从库位置在/mnt/mysql_slave

配置主节点MySQL

mv /var/lib/mysql /var/lib/mysql.bak

停止服务

systemctl stop mysql

初始化数据目录

mysqld --initialize-insecure --user=[用户名] --datadir=/mnt/mysql_master/mysql

配置文件

vim /etc/mysql/mysql.conf.d/mysqld.cnf

[mysqld]
# 基本配置
server_id = 45
port = 3306
datadir = /mnt/mysql_master/mysql
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid

# 字符集配置
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci

# 二进制日志配置
log_bin = mysql-bin
binlog_format = ROW
sync_binlog = 1
binlog_expire_logs_seconds = 604800

# 错误日志配置
log_error = /mnt/mysql_master/mysql/error.log

备份原数据目录

mv /var/lib/mysql /var/lib/mysql.bak

创建新的数据目录

mkdir -p /mnt/mysql_master/mysql chown -R mysql:mysql /mnt/mysql_master/mysql

创建必要目录

mkdir -p /var/run/mysqld 
chown mysql:mysql /var/run/mysqld

启动

systemctl start mysql

配置用户

# 登录MySQL
mysql -u root

# 创建复制用户
CREATE USER 'repl'@'192.168.21.%' IDENTIFIED BY 'Repl_123456';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.21.%';
FLUSH PRIVILEGES;

# 查看主服务器状态
SHOW MASTER STATUS;[查看文件号和位置]

配置从结点

仅需要修改server_id与相对路径,其余可以保持一致

# 基本配置
server_id = 46
port = 3306
datadir = /mnt/mysql_slave/mysql
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid

# 字符集配置
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci

# 中继日志配置
relay-log = relay-bin
relay-log-index = relay-bin.index
read_only = 1

# 错误日志配置
log_error = /mnt/mysql_slave/mysql/error.log

从节点配置

    CHANGE MASTER TO
    MASTER_HOST='192.168.21.50', -- 主节点信息
    MASTER_USER='repl',  -- 主节点信息
    MASTER_PASSWORD='xxxxxxxxxxxxx!',
    MASTER_PORT=3306,
    MASTER_LOG_FILE='mysql-bin.000001',  -- 更正为正确的文件号
    MASTER_LOG_POS=878,                  -- 更正为正确的位置
    GET_MASTER_PUBLIC_KEY=1;
    
    
    START SLAVE;
    
    SHOW SLAVE STATUS\G -- 查看状态

测试

# 在主服务器上创建测试数据
mysql -u root
CREATE DATABASE testdb;
USE testdb;
CREATE TABLE test (id INT, name VARCHAR(50));
INSERT INTO test VALUES (1, 'test');

# 在从服务器上验证
mysql -u root
USE testdb;
SELECT * FROM test;

备份,这里使用的是Percona XtraBackup

安装

安装依赖
apt update
apt install -y wget gnupg2 lsb-release curl

下载 Percona 仓库包
wget https://repo.percona.com/apt/percona-release_latest.generic_all.deb

安装仓库包
dpkg -i percona-release_latest.generic_all.deb

启用仓库
percona-release setup ps80

安装 Percona XtraBackup
apt update
apt install -y percona-xtrabackup-80

创建备份

创建主备份目录
mkdir -p /mnt/mysql_slave/backup/mysql/full
mkdir -p /mnt/mysql_slave/backup/mysql/incremental
mkdir -p /mnt/mysql_slave/backup/mysql/logs

设置权限
chown -R mysqlslave:mysql /mnt/mysql_slave/backup/mysql
chmod -R 750 /mnt/mysql_slave/backup/mysql

创建备份脚本 /usr/local/bin/mysql_backup.sh

#!/bin/bash

# 配置
BACKUP_DIR="/backup/mysql"
FULL_BACKUP_DIR="${BACKUP_DIR}/full"
INCR_BACKUP_DIR="${BACKUP_DIR}/incremental"
LOG_DIR="${BACKUP_DIR}/logs"
DATE=$(date +%Y%m%d_%H%M%S)
DOW=$(date +%u)  # 1-7 (星期一到星期日)
RETENTION_DAYS=7
MYSQL_USER="your_backup_user"
MYSQL_PASSWORD="your_backup_password"

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a ${LOG_DIR}/backup_${DATE}.log
}

# 创建备份目录
mkdir -p ${FULL_BACKUP_DIR}/${DATE}
mkdir -p ${LOG_DIR}

# 全量备份(每周日)
if [ "$DOW" = "7" ]; then
    log "Starting full backup..."
    xtrabackup --backup \
        --target-dir=${FULL_BACKUP_DIR}/${DATE} \
        --user=${MYSQL_USER} \
        --password=${MYSQL_PASSWORD} \
        --parallel=4 2>> ${LOG_DIR}/backup_${DATE}.log

    # 准备备份以使其一致
    log "Preparing full backup..."
    xtrabackup --prepare \
        --target-dir=${FULL_BACKUP_DIR}/${DATE} \
        2>> ${LOG_DIR}/backup_${DATE}.log

    # 创建最新全量备份的符号链接
    ln -snf ${FULL_BACKUP_DIR}/${DATE} ${FULL_BACKUP_DIR}/latest

else
    # 增量备份
    LATEST_FULL=$(readlink ${FULL_BACKUP_DIR}/latest)
    
    if [ -z "$LATEST_FULL" ]; then
        log "No full backup found. Running full backup instead..."
        xtrabackup --backup \
            --target-dir=${FULL_BACKUP_DIR}/${DATE} \
            --user=${MYSQL_USER} \
            --password=${MYSQL_PASSWORD} \
            --parallel=4 2>> ${LOG_DIR}/backup_${DATE}.log

        xtrabackup --prepare \
            --target-dir=${FULL_BACKUP_DIR}/${DATE} \
            2>> ${LOG_DIR}/backup_${DATE}.log

        ln -snf ${FULL_BACKUP_DIR}/${DATE} ${FULL_BACKUP_DIR}/latest
    else
        log "Starting incremental backup..."
        mkdir -p ${INCR_BACKUP_DIR}/${DATE}
        
        xtrabackup --backup \
            --target-dir=${INCR_BACKUP_DIR}/${DATE} \
            --incremental-basedir=${FULL_BACKUP_DIR}/latest \
            --user=${MYSQL_USER} \
            --password=${MYSQL_PASSWORD} \
            --parallel=4 2>> ${LOG_DIR}/backup_${DATE}.log
    fi
fi

# 清理旧备份
log "Cleaning old backups..."
find ${FULL_BACKUP_DIR} -maxdepth 1 -type d -mtime +${RETENTION_DAYS} -exec rm -rf {} \;
find ${INCR_BACKUP_DIR} -maxdepth 1 -type d -mtime +${RETENTION_DAYS} -exec rm -rf {} \;
find ${LOG_DIR} -name "backup_*.log" -mtime +${RETENTION_DAYS} -delete

log "Backup completed successfully"

设置权限

chmod 700 /usr/local/bin/mysql_backup.sh
chown root:root /usr/local/bin/mysql_backup.sh

创建定时任务

crontab -e

# 添加以下行(每天凌晨2点执行)
0 2 * * * /usr/local/bin/mysql_backup.sh

恢复全量备份

# 停止 MySQL
systemctl stop mysql

# 清空数据目录
rm -rf /var/lib/mysql/*

# 恢复全量备份
xtrabackup --copy-back --target-dir=/backup/mysql/full/latest

# 修改权限
chown -R mysqlslave:mysql /var/lib/mysql

# 启动 MySQL
systemctl start mysql

恢复增量备份

# 首先准备全量备份
xtrabackup --prepare --apply-log-only \
    --target-dir=/backup/mysql/full/latest

# 然后应用增量备份
xtrabackup --prepare --apply-log-only \
    --target-dir=/backup/mysql/full/latest \
    --incremental-dir=/backup/mysql/incremental/YOUR_INCR_BACKUP_DIR

# 最后一个增量备份不需要 --apply-log-only
xtrabackup --prepare \
    --target-dir=/backup/mysql/full/latest \
    --incremental-dir=/backup/mysql/incremental/LAST_INCR_BACKUP_DIR

# 恢复数据
systemctl stop mysql
rm -rf /var/lib/mysql/*
xtrabackup --copy-back --target-dir=/backup/mysql/full/latest
chown -R mysqlslave:mysql /var/lib/mysql
systemctl start mysql

监控脚本 /usr/local/bin/check_backup.sh

#!/bin/bash

BACKUP_DIR="/backup/mysql"
LOG_DIR="${BACKUP_DIR}/logs"
LATEST_LOG=$(ls -t ${LOG_DIR}/backup_*.log 2>/dev/null | head -1)

if [ -z "$LATEST_LOG" ]; then
    echo "ERROR: No backup logs found"
    exit 1
fi

if grep -q "completed successfully" "$LATEST_LOG"; then
    BACKUP_AGE=$(( ( $(date +%s) - $(stat -c %Y "$LATEST_LOG") ) / 3600 ))
    
    if [ $BACKUP_AGE -gt 24 ]; then
        echo "WARNING: Latest successful backup is $BACKUP_AGE hours old"
        exit 1
    else
        echo "Backup check OK. Latest successful backup is $BACKUP_AGE hours old"
        exit 0
    fi
else
    echo "ERROR: Latest backup failed"
    exit 1
fi

备份用户权限配置

-- 删除旧用户(如果需要重新创建)
DROP USER IF EXISTS 'backup_user'@'localhost';

-- 创建新用户
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'bjst@1234!';

-- 授予所有必要权限
GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backup_user'@'localhost';
GRANT BACKUP_ADMIN ON *.* TO 'backup_user'@'localhost';
GRANT SELECT ON performance_schema.* TO 'backup_user'@'localhost';
GRANT SELECT ON mysql.* TO 'backup_user'@'localhost';

-- 如果使用 keyring
GRANT SELECT ON performance_schema.keyring_component_status TO 'backup_user'@'localhost';

-- 刷新权限
FLUSH PRIVILEGES;

测试命令

xtrabackup --backup \
    --target-dir=/mnt/mysql_slave/mysql_backup/test \
    --user=backup_user \
    --password=bjst@1234!