Skip to main content

成功搞定zfs上运行mysql/mariadb容器如何使用duplicati备份: bash脚本使用coproc来启动mysql子进程,先FLUSH TABLES WITH READ LOCK锁住整个数据库,再执行zfs snapshot,完成后就能释放unlock tables ;整个脚本作为duplicati配置的run-script-before,不想保留快照可以再配置run-script-after删掉创建的快照Claude给的bash脚本:

  1. 成功搞定zfs上运行mysql/mariadb容器如何使用duplicati备份: bash脚本使用coproc来启动mysql子进程,先FLUSH TABLES WITH READ LOCK锁住整个数据库,再执行zfs snapshot,完成后就能释放unlock tables ;整个脚本作为duplicati配置的run-script-before,不想保留快照可以再配置run-script-after删掉创建的快照

    Claude给的bash脚本:

    
    #!/bin/bash
    
    # 配置
    ZFS_DATASET="pool/mysql/data"
    SNAPSHOT_NAME="duplicati_backup"
    MYSQL_SOCKET="/var/run/mysqld/mysqld.sock"  # 或使用TCP连接
    
    # 清理函数
    cleanup() {
        if [ -n "$COPROC_PID" ]; then
            echo "UNLOCK TABLES;" >&${COPROC[1]}
            echo "QUIT;" >&${COPROC[1]}
            wait $COPROC_PID 2>/dev/null
        fi
    }
    trap cleanup EXIT
    
    # 删除旧快照
    if zfs list -t snapshot "${ZFS_DATASET}@${SNAPSHOT_NAME}" &>/dev/null; then
        zfs destroy "${ZFS_DATASET}@${SNAPSHOT_NAME}" || exit 1
    fi
    
    # 启动MySQL协进程
    coproc mysql --unbuffered -u root
    
    # 发送锁命令
    echo "FLUSH TABLES WITH READ LOCK;" >&${COPROC[1]}
    echo "SELECT 'LOCKED';" >&${COPROC[1]}
    
    # 等待锁确认
    while IFS= read -r line <&${COPROC[0]}; do
        if [[ "$line" == "LOCKED" ]]; then
            break
        fi
    done
    
    # 创建快照
    if ! zfs snapshot "${ZFS_DATASET}@${SNAPSHOT_NAME}"; then
        echo "快照创建失败" >&2
        exit 1
    fi
    
    # 释放锁
    echo "UNLOCK TABLES;" >&${COPROC[1]}
    echo "QUIT;" >&${COPROC[1]}
    
    wait $COPROC_PID
    echo "备份完成"