创建共享LVM

一、环境准备

存储识别

确保所有节点能看到相同的 SAN 设备:

lsblk | grep san      # 检查设备名称(如/dev/sdb、/dev/mapper/mpathc)
multipath -ll         # 多路径环境下确认路径聚合

禁用自动激活

# 修改所有节点的 LVM 配置,禁止自动激活 VG:
vi /etc/lvm/lvm.conf

auto_activation_volume_list = []  # 禁用自动激活
use_lvmetad = 0                   # 关闭 lvmetad 服务(避免缓存冲突)

二、创建共享 LVM 卷组

初始化物理卷(PV)

# 在任意一个节点执行(只需一次):
pvcreate /dev/mapper/mpathc

创建共享卷组(VG)

vgcreate vg_shared /dev/mapper/mpathc

设置 VG 为非自动激活

vgchange --setautoactivation n vg_shared

三、手动切换操作流程

场景:从节点 A 切换到节点 B

在节点 A 卸载文件系统并停用 VG

# 1. 卸载文件系统
umount /mnt/shared

# 2. 停用逻辑卷和卷组
lvchange -an vg_shared/lv_data  # 停用 LV
vgchange -an vg_shared          # 停用 VG

# 3. 确认 VG 已停用
vgdisplay vg_shared | grep Active  # 应显示 "NOT available"

在节点 B 激活 VG 并挂载

# 1. 扫描存储设备
pvscan --cache /dev/mapper/mpathc

# 2. 激活 VG 和 LV
vgchange -ay vg_shared          # 激活 VG
lvchange -ay vg_shared/lv_data  # 激活 LV(可选,通常 vgchange 已激活)

# 3. 挂载文件系统
mount /dev/vg_shared/lv_data /mnt/shared

# 4. 验证
df -h /mnt/shared

手动启停脚本

由于每次切换比较繁琐,建议使用脚本代替激活停用操作

激活挂载脚本

#!/bin/bash
# 文件名:san_lvm_activate.sh
# 功能:激活VG/LV并挂载文件系统(在目标节点执行)

# 配置区域 ========================================
VG_NAME="vg_shared"              # 卷组名称
LV_NAME="lv_data"                # 逻辑卷名称
MOUNT_POINT="/oracle"        # 挂载点
FS_TYPE="xfs"                    # 文件系统类型
LOG_FILE="/tmp/san_storage.log" # 日志路径

# 函数定义 ========================================
log() {
  echo "[$(date '+%Y-%m-%d %T')] [ACTIVATE] $1" | tee -a $LOG_FILE
}

# 主逻辑 ========================================
log "=== 开始激活流程 ==="

# 步骤1:激活VG
log "正在激活卷组..."
vgchange -ay $VG_NAME &>>$LOG_FILE || { log "错误:VG激活失败"; exit 1; }

# 步骤2:激活LV
log "正在激活逻辑卷..."
lvchange -ay $VG_NAME/$LV_NAME &>>$LOG_FILE || { log "错误:LV激活失败"; exit 2; }

# 步骤3:文件系统检查
log "正在检查文件系统..."
if ! blkid -t TYPE=$FS_TYPE /dev/$VG_NAME/$LV_NAME &>/dev/null; then
  case $FS_TYPE in
    xfs) xfs_repair /dev/$VG_NAME/$LV_NAME &>>$LOG_FILE ;;
    ext4) fsck -p /dev/$VG_NAME/$LV_NAME &>>$LOG_FILE ;;
    *) log "警告:未知文件系统类型,跳过检查" ;;
  esac
fi

# 步骤4:挂载
log "正在创建挂载点..."
mkdir -p $MOUNT_POINT &>/dev/null

log "正在挂载文件系统..."
mount -t $FS_TYPE /dev/$VG_NAME/$LV_NAME $MOUNT_POINT &>>$LOG_FILE || { log "错误:挂载失败"; exit 3; }

# 最终验证
if grep -q "$MOUNT_POINT" /proc/mounts; then
  log "挂载成功!使用 df -h 查看:"
  df -h $MOUNT_POINT | tee -a $LOG_FILE
else
  log "错误:最终挂载验证失败"
  exit 4
fi

卸载停用脚本

#!/bin/bash
# 文件名:san_lvm_unload.sh
# 功能:卸载文件系统并停用VG/LV(在当前节点执行)

# 配置区域 ========================================
VG_NAME="vg_shared"              # 卷组名称
LV_NAME="lv_data"                # 逻辑卷名称
MOUNT_POINT="/oracle"        # 挂载点
LOG_FILE="/tmp/san_storage.log" # 日志路径
FORCE_MODE=0                     # 强制模式(0:关闭 1:开启)

# 函数定义 ========================================
log() {
  echo "[$(date '+%Y-%m-%d %T')] [UNLOAD] $1" | tee -a $LOG_FILE
}

check_vg_active() {
  vgdisplay $VG_NAME | grep -i 'Active' | grep -iq 'yes'
  [ $? -eq 0 ] && echo "yes" || echo "no"
}

# 主逻辑 ========================================
log "=== 开始卸载流程 ==="

# 步骤1:检查挂载点
if grep -q "$MOUNT_POINT" /proc/mounts; then
  log "正在卸载文件系统..."
  umount $MOUNT_POINT &>>$LOG_FILE || { log "错误:卸载失败"; exit 1; }
else
  log "文件系统未挂载,跳过卸载"
fi

# 步骤2:停用LV和VG
log "正在停用逻辑卷..."
lvchange -an $VG_NAME/$LV_NAME &>>$LOG_FILE || log "警告:停用LV失败(可能未激活)"

log "正在停用卷组..."
vgchange -an $VG_NAME &>>$LOG_FILE

# 步骤3:二次确认
if [ "$(check_vg_active)" == "yes" ]; then
  if [ $FORCE_MODE -eq 1 ]; then
    log "强制执行全局停用..."
    vgchange -an $VG_NAME --config 'devices { global_filter=["r|.*|"] }' &>>$LOG_FILE
  else
    log "错误:VG仍处于活动状态!"
    exit 2
  fi
fi

log "操作完成。最终状态:VG激活=$(check_vg_active)"

 

 

四、关键注意事项

独占访问原则

确保同一时刻只有一个节点激活 VG,可通过以下命令强制释放:

# 在异常情况下强制停用 VG(谨慎使用)
vgchange -an vg_shared --config 'devices { global_filter=["r|/dev/mapper/mpathc|"] }'

文件系统一致性

使用 xfs_repair 或 fsck 检查文件系统:

# 在挂载前检查(尤其异常关机后)
xfs_repair /dev/vg_shared/lv_data

设备名称一致性

建议通过 UUID 或 WWID 挂载,避免依赖 /dev/sdX:

# 获取设备唯一标识
lvdisplay vg_shared/lv_data | grep "LV UUID"
mount /dev/disk/by-uuid/ /mnt/shared

五、操作验证脚本

#!/bin/bash
# 检查 VG 状态
check_vg_status() {
  node=$1
  ssh $node "vgdisplay vg_shared | grep -i active"
}

# 检查挂载点
check_mount() {
  node=$1
  ssh $node "grep '/mnt/shared' /proc/mounts"
}

echo "=== 节点 A 状态 ==="
check_vg_status nodeA
check_mount nodeA

echo "=== 节点 B 状态 ==="
check_vg_status nodeB
check_mount nodeB
posted @ 2025-04-26 10:45  小明123_123  阅读(51)  评论(0)    收藏  举报