将 database-dump-via-docker-sock.sh 的文案和注释翻译为中文

This commit is contained in:
严浩
2025-12-19 23:11:35 +08:00
parent 68e1e2e3f1
commit de586999cc
3 changed files with 34 additions and 222 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.DS_Store

View File

@@ -1,189 +0,0 @@
#!/bin/sh
set -eu
# PostgreSQL backup triggered through the Docker Engine unix socket.
# Example: ./postgres-dump-zstd-via-docker-sock.sh --container=postgres17 --backup-prefix=pgvector17_all_databases_zstd_ --socket=/var/run/docker.sock --api-version=v1.51 --backup-dir=/backups
# Remote example: curl -fsSL https://git.1-h.cc/Scripts/Linux/raw/branch/main/postgres-dump-zstd-via-docker-sock.sh | sh -s -- --container=postgres17 --backup-prefix=pgvector17_all_databases_zstd_ --socket=/var/run/docker.sock --api-version=v1.51 --backup-dir=/backups
log() {
printf '%s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ') $*"
}
log_stream() {
log_stream_prefix=$1
log_stream_payload=$2
if [ -n "$log_stream_payload" ]; then
printf '%s\n' "$log_stream_payload" | while IFS= read -r log_stream_line; do
log "$log_stream_prefix: $log_stream_line"
done
fi
}
print_usage() {
cat <<EOF >&2
Usage: $0 [--socket=PATH] [--api-version=VERSION] --container=NAME [--backup-dir=DIR] --backup-prefix=PREFIX
Options:
--socket=PATH Docker Engine unix socket path (default: /var/run/docker.sock)
--api-version=VERSION Docker API version (default: v1.51)
--container=NAME PostgreSQL container name
--backup-dir=DIR Directory to store backups (default: /backups)
--backup-prefix=PREFIX Backup filename prefix
--help Show this help message
EOF
}
DOCKER_SOCKET="/var/run/docker.sock"
DOCKER_API_VERSION="v1.51"
PG_CONTAINER_NAME=""
BACKUP_DIR="/backups"
BACKUP_PREFIX=""
require_command() {
if ! command -v "$1" >/dev/null 2>&1; then
printf '%s requires %s in PATH\n' "$0" "$1" >&2
exit 1
fi
}
missing_value() {
printf 'Missing value for %s\n' "$1" >&2
print_usage
exit 1
}
docker_exec() {
exec_container_name=$1
exec_cmd=$2
curl -fsSL "https://Git.1-H.CC/Scripts/Linux/raw/branch/main/docker-exec-via-sock.sh" | sh -s -- \
--socket="$DOCKER_SOCKET" \
--api-version="$DOCKER_API_VERSION" \
--container="$exec_container_name" \
--cmd="$exec_cmd"
}
while [ "$#" -gt 0 ]; do
case $1 in
--socket=*)
DOCKER_SOCKET="${1#*=}"
;;
--socket)
if [ "$#" -lt 2 ]; then
missing_value '--socket'
fi
shift
DOCKER_SOCKET="$1"
;;
--api-version=*)
DOCKER_API_VERSION="${1#*=}"
;;
--api-version)
if [ "$#" -lt 2 ]; then
missing_value '--api-version'
fi
shift
DOCKER_API_VERSION="$1"
;;
--container=*)
PG_CONTAINER_NAME="${1#*=}"
;;
--container)
if [ "$#" -lt 2 ]; then
missing_value '--container'
fi
shift
PG_CONTAINER_NAME="$1"
;;
--backup-dir=*)
BACKUP_DIR="${1#*=}"
;;
--backup-dir)
if [ "$#" -lt 2 ]; then
missing_value '--backup-dir'
fi
shift
BACKUP_DIR="$1"
;;
--backup-prefix=*)
BACKUP_PREFIX="${1#*=}"
;;
--backup-prefix)
if [ "$#" -lt 2 ]; then
missing_value '--backup-prefix'
fi
shift
BACKUP_PREFIX="$1"
;;
--help)
print_usage
exit 0
;;
--)
shift
break
;;
*)
printf 'Unknown option: %s\n' "$1" >&2
print_usage
exit 1
;;
esac
shift
done
if [ "$#" -gt 0 ]; then
printf 'Unexpected positional arguments: %s\n' "$*" >&2
print_usage
exit 1
fi
require_command curl
require_command jq
if [ -z "$DOCKER_SOCKET" ] || [ -z "$DOCKER_API_VERSION" ] || [ -z "$PG_CONTAINER_NAME" ] || [ -z "$BACKUP_DIR" ] || [ -z "$BACKUP_PREFIX" ]; then
print_usage
exit 1
fi
if [ ! -S "$DOCKER_SOCKET" ]; then
log "docker socket $DOCKER_SOCKET not found"
exit 1
fi
timestamp=$(date +%Y-%m-%d_%H-%M-%S)
backup_path="$BACKUP_DIR/${BACKUP_PREFIX}${timestamp}.sql.zst"
log "preparing database backup at $backup_path via docker unix socket"
cmd="set -o pipefail && pg_dumpall --username=\"\${POSTGRES_USER:-postgres}\" --clean | zstd > ${backup_path}"
log_border="----------------------------------------------------------------------"
printf '%s\n' "$log_border" >&2
if ! docker_exec "$PG_CONTAINER_NAME" "$cmd"; then
printf '%s\n' "$log_border" >&2
log "backup command failed"
exit 1
fi
printf '%s\n' "$log_border" >&2
printf '\n' >&2 # Add a blank line for visual grouping
log "backup command finished, verifying file size inside container"
verify_cmd="du -h \"${backup_path}\" 2>/dev/null | awk 'NR==1{print \$1}'"
printf '%s\n' "$log_border" >&2
size=$(docker_exec "$PG_CONTAINER_NAME" "$verify_cmd" | tr -d '\r')
printf '%s\n' "$log_border" >&2
printf '\n' >&2 # Add a blank line for visual grouping
if [ -n "$size" ]; then
log "backup completed inside container: $backup_path ($size)"
else
log "backup completed, but could not determine file size inside container."
fi
printf '\n' >&2 # Add a blank line for visual grouping
log "database backup finished"

View File

@@ -1,8 +1,8 @@
#!/bin/sh
set -eu
# Generic database backup triggered through the Docker Engine unix socket.
# Supports PostgreSQL, MySQL/MariaDB, and Kingbase containers.
# 通过 Docker Engine unix socket 触发的通用数据库备份。
# 支持 PostgreSQL, MySQL/MariaDB Kingbase 容器。
log() {
printf '%s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ') $*"
@@ -10,21 +10,21 @@ log() {
print_usage() {
cat <<EOF_USAGE >&2
Usage: $0 [--socket=PATH] [--api-version=VERSION] --container=NAME \\
[--type=postgres|mysql|kingbase] --backup-prefix=PREFIX [--backup-dir=DIR] \\
[--mysql-user=USER] [--mysql-password=PASSWORD] [--exec-user=NAME]
用法: $0 [--socket=路径] [--api-version=版本] --container=名称 \\
[--type=postgres|mysql|kingbase] --backup-prefix=前缀 [--backup-dir=目录] \\
[--mysql-user=用户] [--mysql-password=密码] [--exec-user=名称]
Options:
--socket=PATH Docker Engine unix socket path (default: /var/run/docker.sock)
--api-version=VERSION Docker API version (default: v1.51)
--container=NAME Container name to execute the backup in
--type=TYPE Database type: postgres, mysql, or kingbase (auto-detected from container name if omitted)
--backup-dir=DIR Directory to store backups (default: /backups)
--backup-prefix=PREFIX Backup filename prefix
--mysql-user=USER MySQL user (default: root)
--mysql-password=PASSWORD MySQL password (optional)
--exec-user=NAME Force a specific user when running commands inside the container
--help Show this help message
选项:
--socket=PATH Docker Engine unix socket 路径 (默认: /var/run/docker.sock)
--api-version=VERSION Docker API 版本 (默认: v1.51)
--container=NAME 执行备份的容器名称
--type=TYPE 数据库类型: postgres, mysql, kingbase (如果省略,则从容器名称自动检测)
--backup-dir=DIR 存储备份的目录 (默认: /backups)
--backup-prefix=PREFIX 备份文件名前缀
--mysql-user=USER MySQL 用户 (默认: root)
--mysql-password=PASSWORD MySQL 密码 (可选)
--exec-user=NAME 在容器内运行命令时强制使用特定用户
--help 显示此帮助信息
EOF_USAGE
}
@@ -67,13 +67,13 @@ detect_db_type_from_name() {
require_command() {
if ! command -v "$1" >/dev/null 2>&1; then
printf '%s requires %s in PATH\n' "$0" "$1" >&2
printf '%s 需要 PATH 中包含 %s\n' "$0" "$1" >&2
exit 1
fi
}
missing_value() {
printf 'Missing value for %s\n' "$1" >&2
printf '缺少 %s 的值\n' "$1" >&2
print_usage
exit 1
}
@@ -189,7 +189,7 @@ while [ "$#" -gt 0 ]; do
break
;;
*)
printf 'Unknown option: %s\n' "$1" >&2
printf '未知选项: %s\n' "$1" >&2
print_usage
exit 1
;;
@@ -198,7 +198,7 @@ while [ "$#" -gt 0 ]; do
done
if [ "$#" -gt 0 ]; then
printf 'Unexpected positional arguments: %s\n' "$*" >&2
printf '意外的位置参数: %s\n' "$*" >&2
print_usage
exit 1
fi
@@ -214,17 +214,17 @@ if [ -z "$DOCKER_SOCKET" ] || [ -z "$DOCKER_API_VERSION" ] || [ -z "$CONTAINER_N
fi
if [ ! -S "$DOCKER_SOCKET" ]; then
log "docker socket $DOCKER_SOCKET not found"
log "未找到 docker socket $DOCKER_SOCKET"
exit 1
fi
if [ -z "$DB_TYPE" ]; then
if detected_type=$(detect_db_type_from_name "$CONTAINER_NAME"); then
DB_TYPE=$detected_type
log "auto-detected database type '$DB_TYPE' from container name '$CONTAINER_NAME'"
log "从容器名称 '$CONTAINER_NAME' 自动检测到数据库类型 '$DB_TYPE'"
else
printf 'Unable to detect database type from container name: %s\n' "$CONTAINER_NAME" >&2
printf 'Please specify --type=postgres, --type=mysql, or --type=kingbase\n' >&2
printf '无法从容器名称检测数据库类型: %s\n' "$CONTAINER_NAME" >&2
printf '请指定 --type=postgres, --type=mysql --type=kingbase\n' >&2
exit 1
fi
fi
@@ -257,7 +257,7 @@ case $DB_TYPE in
EXEC_SHELL="sh"
;;
*)
printf 'Unsupported database type: %s\n' "$DB_TYPE" >&2
printf '不支持的数据库类型: %s\n' "$DB_TYPE" >&2
exit 1
;;
esac
@@ -271,7 +271,7 @@ fi
timestamp=$(date +%Y-%m-%d_%H-%M-%S)
backup_path="$BACKUP_DIR/${BACKUP_PREFIX}${timestamp}${BACKUP_EXTENSION}"
log "preparing $DB_TYPE backup at $backup_path via docker unix socket"
log "正在通过 docker unix socket 准备 $DB_TYPE 备份到 $backup_path"
cmd="mkdir -p \"${BACKUP_DIR}\" && set -o pipefail && ${DUMP_CMD} | ${COMPRESS_CMD} > \"${backup_path}\""
@@ -280,13 +280,13 @@ log_border="--------------------------------------------------------------------
printf '%s\n' "$log_border" >&2
if ! docker_exec "$CONTAINER_NAME" "$cmd" "${EXEC_USER:-}"; then
printf '%s\n' "$log_border" >&2
log "backup command failed"
log "备份命令失败"
exit 1
fi
printf '%s\n' "$log_border" >&2
printf '\n' >&2
log "backup command finished, verifying file size inside container"
log "备份命令完成,正在验证容器内的文件大小"
verify_cmd="du -h \"${backup_path}\" 2>/dev/null | awk 'NR==1{print \$1}'"
@@ -296,16 +296,16 @@ printf '%s\n' "$log_border" >&2
printf '\n' >&2
if [ -n "$size" ]; then
log "backup completed inside container: $backup_path ($size)"
log "容器内备份完成: $backup_path ($size)"
else
log "backup completed, but could not determine file size inside container."
log "备份完成,但无法确定容器内的文件大小。"
fi
printf '\n' >&2
log "database backup finished"
log "数据库备份完成"
log "invoking remote cleanup script for prefix '$BACKUP_PREFIX' in $BACKUP_DIR"
log "正在调用远程清理脚本,前缀为 '$BACKUP_PREFIX',目录为 $BACKUP_DIR"
if ! curl -fsSL "https://Git.1-H.CC/Scripts/Linux/raw/branch/main/database-dump-cleanup.sh" | \
sh -s -- --prefix="$BACKUP_PREFIX" --dir="$BACKUP_DIR"; then
log "cleanup script failed"
log "清理脚本失败"
fi