1、系统初始化:关闭防火墙、时间同步、初始化等

[root@vastbase ~]# systemctl stop firewalld.service 
[root@vastbase ~]# systemctl disable firewalld.service 
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.




## 这里使用 setenforce 0 临时生效
[root@vastbase ~]# /usr/sbin/setenforce 0
[root@vastbase ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config



####依赖包
[root@vastbase ~]# yum install -y zlib-devel libaio libuuid readline-devel krb5-libs libicu libxslt tcl perl openldap pam openssl-devel libxml2 bzip2

2.参数配置  

 echo "RemoveIPC=no" >> /etc/systemd/logind.conf 
 echo "RemoveIPC=no" >> /usr/lib/systemd/system/systemd-logind.service 


[root@vastbase ~]# systemctl daemon-reload
[root@vastbase ~]# systemctl restart systemd-logind




###内核参数
[root@vastbase ~]# cat<<-EOF>>/etc/sysctl.conf
fs.aio-max-nr=1048576
fs.file-max= 76724600
kernel.sem = 4096 2097152000 4096 512000
kernel.shmall = 3964411
kernel.shmmax = 16238231542
kernel.shmmni = 819200
net.core.netdev_max_backlog = 10000
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 4194304
net.core.somaxconn = 4096
net.ipv4.tcp_fin_timeout = 5
vm.dirty_background_bytes = 409600000 
vm.dirty_expire_centisecs = 3000
vm.dirty_ratio = 80
vm.dirty_writeback_centisecs = 50
vm.overcommit_memory = 0
vm.swappiness = 0
net.ipv4.ip_local_port_range = 40000 65535
fs.nr_open = 20480000
EOF

## 生效配置
[root@vastbase ~]# sysctl -p




####系统参数
cat<<-EOF>>/etc/security/limits.conf
vastbase soft nproc unlimited
vastbase hard nproc unlimited
vastbase soft stack unlimited
vastbase hard stack unlimited
vastbase soft core unlimited
vastbase hard core unlimited
vastbase soft memlock unlimited
vastbase hard memlock unlimited
vastbase soft nofile 1024000
vastbase hard nofile 1024000
EOF


3、安装

####用户
useradd -m vastbase
passwd vastbase


####创建数据库coredump目录
mkdir -p /home/vastbase/data/vdb_coredump
chmod 770 /home/vastbase/data
chown vastbase:vastbase /home/vastbase/data


#####创建数据库数据目录(可自定义)
mkdir -p /home/vastbase/data/vastbase
chmod 700 /home/vastbase/data/vastbase
chown -R vastbase:vastbase /home/vastbase/data/vastbase


#####创建数据库软件目录(可自定义)
mkdir -p /home/vastbase/local/vastbase
chown -R vastbase:vastbase /home/vastbase



###上传包,包是3个月试用期,刚找官方要的,有想要的留言
mkdir -p /home/vastbase/soft

cp 数据库安装包 /home/vastbase/soft

chown -R vastbase:vastbase /home/vastbase/soft


###切换用户安装
su  vastbase
cd soft
tar -zxvf 数据库安装包

cd /home/vastbase/soft/vastbase-installer

./vastbase_installer


根据提示一步一步安装就行了

4、数据库启动

source ~/.bashrc
##启动数据库 一般会报错
vb_ctl start

##分析报错是因为内存参数设置过大,需要修改配置文件/home/vastbase/data/vastbase/postgresql.conf 中以下几个参数值,具体的值根据内存来,尽量设置小:

wal_buffers = 32MB
shared_buffers=512MB
max_connections=100
max_process_memory=6144MB
cstore_buffers = 32MB



####查看状态
vb_ctl status


###登录
vsql -r -d vastbase

5、创建用户和连接

#连接数据库
vsql -d vastbase -p 5432
 
#创建用户
CREATE USER vastbase_test PASSWORD 'Test@123';
 
#创建数据库
CREATE DATABASE vastbase_test OWNER vastbase_test ENCODING 'UTF-8' template = template0;
 
#授予权限
GRANT ALL PRIVILEGES TO vastbase_test;



####使用远程连接工具连接时,会有报错需要开启一个参数
password_force_alter=off

6.shell脚本备份恢复

#!/usr/bin/env bash
# pg_vastbase_backup.sh
# 备份/恢复脚本(仅使用 Vastbase --pipeline 模式;每库单独 .dump)
# 用法:
#   ./pg_vastbase_backup.sh backup [DBNAME]
#   ./pg_vastbase_backup.sh restore <dump-file|backup-dir|latest> [db1 db2 ...]
#   ./pg_vastbase_backup.sh list
#   ./pg_vastbase_backup.sh help

set -euo pipefail

#########################
# 配置区(请按需修改)
#########################
BACKUP_ROOT="/var/backups/psql"
RETENTION_DAYS=7

PG_HOST="1.1.1.1"
PG_PORT=5432
PG_USER="vastbase"
PG_PASSWORD="123"       # 明文风险:建议改为运行时输入或密钥管理
VAST_USER="vastbase"

VB_DUMP_BIN="/home/vastbase/local/vastbase/bin/vb_dump"
VB_RESTORE_BIN="/home/vastbase/local/vastbase/bin/vb_restore"
PSQL_BIN="/home/vastbase/local/vastbase/bin/psql"

LOGFILE="${BACKUP_ROOT}/backup_restore.log"
#########################

log() { echo "[$(date '+%F %T')] $*" | tee -a "${LOGFILE}"; }

usage() {
  cat <<EOF
Usage:
  $0 backup [DBNAME]
  $0 restore <dump-file|backup-dir|latest> [db1 db2 ...]
  $0 list
  $0 help

说明:
  - 默认尝试用 vb_restore --clean --no-data-for-failed-tables(不删库的情况下先清理冲突对象)。
  - 若需强制先 DROP/CREATE 目标库(完整覆盖),导入前设置环境变量:
      export FORCE_RECREATE_DB=1
    然后运行 restore,会先终止连接并重建数据库。
EOF
}

# 在 VAST_USER 下执行命令
run_as_vastbase() {
  local cmd="$*"
  if command -v runuser >/dev/null 2>&1; then
    runuser -u "${VAST_USER}" -- /bin/bash -lc "${cmd}"
  elif command -v sudo >/dev/null 2>&1; then
    sudo -u "${VAST_USER}" -H /bin/bash -lc "${cmd}"
  else
    su - "${VAST_USER}" -c "${cmd}"
  fi
}

# 检查 --pipeline 支持
check_pipeline_bin() {
  local bin="$1"
  if [ ! -x "${bin}" ]; then
    return 1
  fi
  if "${bin}" --help 2>&1 | grep -q -- '--pipeline'; then
    return 0
  fi
  return 2
}

ensure_dirs() {
  mkdir -p "${BACKUP_ROOT}"
  touch "${LOGFILE}" || true
  chown "${VAST_USER}":"${VAST_USER}" "${BACKUP_ROOT}" 2>/dev/null || true
  chmod 750 "${BACKUP_ROOT}" 2>/dev/null || true
}

timestamp() { date '+%F_%H%M%S'; }

get_db_list() {
  run_as_vastbase "printf '%s\n' '${PG_PASSWORD}' | ${PSQL_BIN} --pipeline -h '${PG_HOST}' -p ${PG_PORT} -U '${PG_USER}' -X -A -t -c \"SELECT datname FROM pg_database WHERE datallowconn = true AND datname NOT IN ('template0','template1','postgres')\""
}

backup_one_db() {
  local db="$1"
  local outdir="$2"
  local outfile="${outdir}/${db}_$(date '+%F_%H%M%S').dump"

  log "开始备份数据库 ${db} -> ${outfile}"
  run_as_vastbase "printf '%s\n' '${PG_PASSWORD}' | ${VB_DUMP_BIN} --pipeline -h '${PG_HOST}' -p ${PG_PORT} -U '${PG_USER}' -F c -f '${outfile}' '${db}'"
  local rc=$?
  if [ $rc -ne 0 ]; then
    log "错误:备份 ${db} 失败(rc=${rc}),删除残留文件"
    run_as_vastbase "rm -f '${outfile}'" || true
    return $rc
  fi
  if run_as_vastbase "test -s '${outfile}'"; then
    log "完成备份: ${outfile}"
    return 0
  else
    log "错误:备份文件不存在或为空: ${outfile}"
    run_as_vastbase "rm -f '${outfile}'" || true
    return 2
  fi
}

# ====== 关键:增强的恢复单文件函数 ======
# 行为:
#  - 若传入 target_db 且 FORCE_RECREATE_DB=1:terminate backends -> DROP DATABASE IF EXISTS -> CREATE DATABASE -> restore 到 target_db
#  - 若传入 target_db 且 FORCE_RECREATE_DB!=1:使用 vb_restore --pipeline --clean --no-data-for-failed-tables -d target_db 恢复(先清理冲突对象)
#  - 若未传 target_db:使用 vb_restore --pipeline -C -d postgres dumpfile(尽量按 dump 原名创建),如果你需要强制重建请改为传 target_db 或使用 FORCE_RECREATE_DB 并传目标名
do_restore_single_file() {
  local dumpfile="$1"
  local target_db="${2:-}"

  if [ ! -f "${dumpfile}" ]; then
    log "错误:未找到文件 ${dumpfile}"
    return 2
  fi

  # 若指定目标库
  if [ -n "${target_db}" ]; then
    if [ "${FORCE_RECREATE_DB:-0}" = "1" ]; then
      log "强制重建目标库:终止连接、DROP/CREATE ${target_db}"
      # 终止目标库的活动连接(在 postgres 上执行)
      run_as_vastbase "printf '%s\n' '${PG_PASSWORD}' | ${PSQL_BIN} --pipeline -h '${PG_HOST}' -p ${PG_PORT} -U '${PG_USER}' -c \"SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname='${target_db}' AND pid<>pg_backend_pid();\" || true"
      # DROP & CREATE
      run_as_vastbase "printf '%s\n' '${PG_PASSWORD}' | ${PSQL_BIN} --pipeline -h '${PG_HOST}' -p ${PG_PORT} -U '${PG_USER}' -c \"DROP DATABASE IF EXISTS \\\"${target_db}\\\"; CREATE DATABASE \\\"${target_db}\\\";\""
      # 恢复到目标库
      log "开始恢复到空的目标库 ${target_db}"
      run_as_vastbase "printf '%s\n' '${PG_PASSWORD}' | ${VB_RESTORE_BIN} --pipeline -h '${PG_HOST}' -p ${PG_PORT} -U '${PG_USER}' -d '${target_db}' '${dumpfile}'"
      return $?
    else
      log "使用 vb_restore --clean 恢复到目标库 ${target_db}(会先清理冲突对象)"
      # --clean 会尝试 DROP 冲突对象,--no-data-for-failed-tables 遇到无法创建的表时跳过数据导入,避免大量错误中断
      run_as_vastbase "printf '%s\n' '${PG_PASSWORD}' | ${VB_RESTORE_BIN} --pipeline --clean --no-data-for-failed-tables -h '${PG_HOST}' -p ${PG_PORT} -U '${PG_USER}' -d '${target_db}' '${dumpfile}'"
      return $?
    fi
  fi

  # 未指定目标库:尝试用 -C(创建原名数据库)恢复
  log "未指定目标库,使用 vb_restore -C 在 postgres 上创建原名数据库并恢复(若数据库已存在可能失败)"
  # 如果用户强制重建但没给目标名,无法安全得知 dump 内 DB 名;仍用 -C 恢复(若报错请使用 target_db+FORCE_RECREATE_DB=1)
  run_as_vastbase "printf '%s\n' '${PG_PASSWORD}' | ${VB_RESTORE_BIN} --pipeline --clean --no-data-for-failed-tables -h '${PG_HOST}' -p ${PG_PORT} -U '${PG_USER}' -C -d postgres '${dumpfile}'"
  return $?
}
# ====== 恢复函数结束 ======

cleanup_old() {
  if [ "${RETENTION_DAYS:-0}" -gt 0 ]; then
    log "清理超过 ${RETENTION_DAYS} 天的备份目录"
    find "${BACKUP_ROOT}" -maxdepth 1 -mindepth 1 -type d -mtime +"${RETENTION_DAYS}" -print -exec rm -rf {} \; || true
  fi
}

do_list() {
  ls -lh "${BACKUP_ROOT}" || true
}

do_backup() {
  local target_db="${1:-}"
  ensure_dirs

  if ! check_pipeline_bin "${VB_DUMP_BIN}"; then
    log "错误:${VB_DUMP_BIN} 不存在或不支持 --pipeline,退出。"
    exit 2
  fi

  local ts dir dbs db
  ts="$(timestamp)"
  dir="${BACKUP_ROOT}/${ts}"
  mkdir -p "${dir}"
  chown "${VAST_USER}":"${VAST_USER}" "${dir}" 2>/dev/null || true
  chmod 750 "${dir}" 2>/dev/null || true

  if [ -n "${target_db}" ]; then
    if [ "${target_db}" = "template0" ] || [ "${target_db}" = "template1" ] || [ "${target_db}" = "postgres" ]; then
      log "指定数据库 ${target_db} 在排除名单中,跳过。"
      exit 1
    fi
    backup_one_db "${target_db}" "${dir}" || { log "备份 ${target_db} 失败"; exit 2; }
  else
    mapfile -t dbs < <(get_db_list)
    if [ ${#dbs[@]} -eq 0 ]; then
      log "未检索到要备份的数据库(已排除 template/db),退出"
      exit 1
    fi
    for db in "${dbs[@]}"; do
      db="$(echo "${db}" | tr -d '\r\n')"
      if [ -z "${db}" ]; then continue; fi
      backup_one_db "${db}" "${dir}" || log "警告:数据库 ${db} 备份失败,继续下一个"
    done
  fi

  echo "# restore instructions: sudo ./pg_vastbase_backup.sh restore ${dir}" > "${dir}/README.txt"
  cat > "${dir}/restore_all.sh" <<'EOF'
#!/usr/bin/env bash
# 占位:请使用主脚本执行恢复,例如:
# sudo ./pg_vastbase_backup.sh restore <backup-dir> [db1 db2 ...]
EOF
  chmod 700 "${dir}/restore_all.sh"
  chown "${VAST_USER}":"${VAST_USER}" "${dir}/restore_all.sh" 2>/dev/null || true

  cleanup_old
  log "备份完成,目录: ${dir}"
  log "要恢复该目录下所有 dump: sudo ./pg_vastbase_backup.sh restore ${dir}"
}

do_restore() {
  if [ "${#}" -lt 1 ]; then
    echo "Usage: $0 restore <dump-file|backup-dir|latest> [db1 db2 ...]"
    exit 1
  fi
  ensure_dirs
  local path="$1"; shift || true
  local filter_dbs=("$@")

  if [ "${path}" = "latest" ]; then
    path="$(ls -1dt "${BACKUP_ROOT}"/*/ 2>/dev/null | head -n1 || true)"
    if [ -z "${path}" ]; then
      log "错误:未找到任何备份目录"
      exit 1
    fi
  fi

  if [ -d "${path}" ]; then
    log "恢复目录 ${path}"
    mapfile -t allfiles < <(ls -1 "${path}"/*.dump 2>/dev/null || true)
    if [ ${#allfiles[@]} -eq 0 ]; then
      log "目录 ${path} 下未找到 .dump 文件,退出"
      exit 1
    fi

    if [ ${#filter_dbs[@]} -gt 0 ]; then
      for db in "${filter_dbs[@]}"; do
        df="$(ls -1 "${path}/${db}"_*.dump 2>/dev/null | sort -V | tail -n1 || true)"
        if [ -z "${df}" ]; then
          log "未找到 ${db} 对应的 dump,跳过"
          continue
        fi
        if ! do_restore_single_file "${df}" "${db}"; then
          log "警告:恢复 ${db} 失败,继续"
        fi
      done
    else
      for df in "${allfiles[@]}"; do
        fname="$(basename "${df}")"
        dbname="${fname%%_*}"
        if [ -z "${dbname}" ]; then
          log "无法从文件名推断库名: ${fname},跳过"
          continue
        fi
        if ! do_restore_single_file "${df}" ""; then
          log "警告:恢复 ${dbname} 失败,继续"
        fi
      done
    fi
    return 0
  fi

  if [ -f "${path}" ]; then
    if [ ${#filter_dbs[@]} -gt 0 ]; then
      local target="${filter_dbs[0]}"
      do_restore_single_file "${path}" "${target}"
    else
      do_restore_single_file "${path}" ""
    fi
    return $?
  fi

  log "错误:参数 ${path} 既不是目录也不是文件"
  exit 2
}

# main
if [ "${#}" -lt 1 ]; then usage; exit 1; fi

case "$1" in
  backup)
    do_backup "${2:-}"
    ;;
  restore)
    shift
    if [ "${#}" -lt 1 ]; then
      echo "Usage: $0 restore <dump-file|backup-dir|latest> [db1 db2 ...]"
      exit 1
    fi
    do_restore "$@"
    ;;
  list)
    do_list
    ;;
  help|--help|-h)
    usage
    ;;
  *)
    echo "未知命令: $1"
    usage
    exit 2
    ;;
esac

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐