优化空闲binlog轮转
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
set -euo pipefail
|
||||
umask 077
|
||||
|
||||
# 分钟级 binlog 归档。每次轮转后只归档已关闭文件;每个对象以
|
||||
# server_uuid、原始文件名和原始 sha256 命名,避免实例重建后的编号碰撞。
|
||||
# 分钟级 binlog 归档。每分钟检查活动 binlog 的 Position,仅在有新增已提交事务时
|
||||
# 轮转;每个对象以 server_uuid、原始文件名和原始 sha256 命名,避免实例重建后的编号碰撞。
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=backup-common.sh
|
||||
@@ -31,6 +31,29 @@ closed_binlogs() {
|
||||
2>/dev/null | awk 'NR > 1 { print previous } { previous = $1 } END { }'
|
||||
}
|
||||
|
||||
master_status() {
|
||||
local mysql_cid="$1"
|
||||
docker exec "${mysql_cid}" sh -c \
|
||||
'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mysql -uroot --protocol=socket -N -B -e "SHOW MASTER STATUS;"' \
|
||||
2>/dev/null | awk 'NR == 1 { print $1 "\t" $2 }'
|
||||
}
|
||||
|
||||
state_active_binlog() {
|
||||
local state_dir="$1" key="$2" value
|
||||
[[ -f "${state_dir}/active-binlog.env" ]] || return
|
||||
value="$(awk -F= -v key="${key}" '$1 == key { print substr($0, index($0, "=") + 1); exit }' "${state_dir}/active-binlog.env")"
|
||||
printf '%s' "${value}"
|
||||
}
|
||||
|
||||
write_active_binlog_state() {
|
||||
local state_dir="$1" filename="$2" position="$3"
|
||||
{
|
||||
printf 'filename=%s\n' "${filename}"
|
||||
printf 'position=%s\n' "${position}"
|
||||
printf 'observed_at=%s\n' "$(date -Iseconds)"
|
||||
} > "${state_dir}/active-binlog.env"
|
||||
}
|
||||
|
||||
state_last_index() {
|
||||
local state_dir="$1"
|
||||
local value
|
||||
@@ -103,7 +126,12 @@ archive() {
|
||||
backup_require_cmd ossutil
|
||||
backup_require_cmd openssl
|
||||
require_archive_config
|
||||
local backup_dir oss_uri mysql_cid server_uuid state_dir first_binlog last_index first_index expected_index filename index
|
||||
local force="${1:-}" backup_dir oss_uri mysql_cid server_uuid state_dir first_binlog last_index first_index expected_index filename index
|
||||
local current_status current_file current_pos previous_file previous_pos final_status final_file final_pos
|
||||
if [[ -n "${force}" && "${force}" != '--force' ]]; then
|
||||
printf '用法: %s archive [--force]\n' "$0" >&2
|
||||
exit 1
|
||||
fi
|
||||
backup_dir="$(backup_require_env BACKUP_DIR)"
|
||||
backup_validate_dir "${backup_dir}"
|
||||
oss_uri="$(backup_require_env BACKUP_OSS_URI)"
|
||||
@@ -115,8 +143,19 @@ archive() {
|
||||
work_dir="${backup_dir}/.tmp-binlog-$$"
|
||||
mkdir -p "${state_dir}" "${work_dir}"
|
||||
|
||||
docker exec "${mysql_cid}" sh -c \
|
||||
'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mysql -uroot --protocol=socket -e "FLUSH BINARY LOGS;"' >/dev/null
|
||||
current_status="$(master_status "${mysql_cid}")"
|
||||
IFS=$'\t' read -r current_file current_pos <<< "${current_status}"
|
||||
[[ -n "${current_file}" && "${current_pos}" =~ ^[0-9]+$ ]] || { backup_error '无法读取当前 binlog 位点'; exit 1; }
|
||||
backup_binlog_index "${current_file}" >/dev/null
|
||||
previous_file="$(state_active_binlog "${state_dir}" filename || true)"
|
||||
previous_pos="$(state_active_binlog "${state_dir}" position || true)"
|
||||
|
||||
if [[ "${force}" == '--force' || -z "${previous_file}" || -z "${previous_pos}" || "${current_file}" != "${previous_file}" || "${current_pos}" != "${previous_pos}" ]]; then
|
||||
docker exec "${mysql_cid}" sh -c \
|
||||
'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mysql -uroot --protocol=socket -e "FLUSH BINARY LOGS;"' >/dev/null
|
||||
else
|
||||
backup_log "活动 binlog 无新增已提交事务,跳过轮转"
|
||||
fi
|
||||
first_binlog="$(docker exec "${mysql_cid}" sh -c \
|
||||
'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mysql -uroot --protocol=socket -N -B -e "SHOW BINARY LOGS;"' | head -1 | awk '{print $1}')"
|
||||
[[ -n "${first_binlog}" ]] || { backup_error '无法读取 binlog 列表'; exit 1; }
|
||||
@@ -141,6 +180,10 @@ archive() {
|
||||
archive_one "${mysql_cid}" "${state_dir}" "${server_uuid}" "${oss_uri}" "${filename}"
|
||||
expected_index="${index}"
|
||||
done < <(closed_binlogs "${mysql_cid}")
|
||||
final_status="$(master_status "${mysql_cid}")"
|
||||
IFS=$'\t' read -r final_file final_pos <<< "${final_status}"
|
||||
[[ -n "${final_file}" && "${final_pos}" =~ ^[0-9]+$ ]] || { backup_error '无法读取归档后的 binlog 位点'; exit 1; }
|
||||
write_active_binlog_state "${state_dir}" "${final_file}" "${final_pos}"
|
||||
backup_log "binlog 归档完成,实例 ${server_uuid}"
|
||||
}
|
||||
|
||||
@@ -165,7 +208,7 @@ verify() {
|
||||
}
|
||||
|
||||
case "${1:-archive}" in
|
||||
archive) archive ;;
|
||||
archive) archive "${2:-}" ;;
|
||||
verify) verify ;;
|
||||
*)
|
||||
printf '用法: %s {archive|verify}\n' "$0" >&2
|
||||
|
||||
Reference in New Issue
Block a user