ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

如何安全的删除 xlog 文件

2021-10-19 15:35:51  阅读:241  来源: 互联网

标签:文件 00 删除 xlog echo 日志 page


判定脚本

xlog_recycle_check.sh 点击查看代码
#!/bin/bash

usage()
{
    echo "Usage: "
    echo "  $0 [OPTION] ... [XLOGFILES]"
    echo
    echo "Options:"
    echo "  -x xlog_segsize,    xlog 文件段大小,单位 MB,默认 64 MB"
    echo "  -v,                 打印调试信息"
    echo

    exit 0
}

debug_echo()
{
    if [[ $verbose -eq 1 ]]; then
        echo "$@"
    fi
}

# 解析参数
while getopts "x:v" opt
do
    case $opt in
        x ) # 单位 MB ,默认 64 MB
            xlog_segsize="$OPTARG"
            ;;
        v )
            verbose=1
            ;;
        \? )
            usage
            ;;
    esac
done

shift $(($OPTIND-1))

# xlog 文件段
xlog_files=("$@")
[[ ${#xlog_files[@]} -eq 0 ]] && usage

# 设置默认值
verbose=${verbose:=0}
xlog_segsize="${xlog_segsize:=64}"

# 计算 xlog 分组进制 (4GB/xlog_segsize)
xlog_radix=$((0x100000000/($xlog_segsize*1024*1024)))
debug_echo "xlog radix: $xlog_radix"

# 遍历 xlog 文件段
for xlog_file in ${xlog_files[@]}
do
    xlog_base="$(basename $xlog_file)"
    if [[ ! $xlog_base =~ ^[0-9A-Z]{24}$ ]]; then
        debug_echo "$xlog_file is NOT xlog file"
        continue
    fi
    echo "xlog base: $xlog_base"
    echo "xlog file: $xlog_file"

    # 根据文件名计算当前文件的第一个 page 的LSN
    xlog_timeline="0x${xlog_base:0:8}"
    debug_echo "xlog timeline: $xlog_timeline"
    xlog_group="0x${xlog_base:8:8}"
    debug_echo "xlog group: $xlog_group"
    xlog_index="0x${xlog_base:16:8}"
    debug_echo "xlog index: $xlog_index"
    debug_echo "xlog calc expr: ($xlog_group*$xlog_radix+$xlog_index)*$xlog_segsize*1024*1024"
    xlog_first_page_lsn_calc=$((($xlog_group*$xlog_radix+$xlog_index)*$xlog_segsize*1024*1024))
    echo "LSN calc: $xlog_first_page_lsn_calc"
    printf "LSN calc hex: 0x%016x\n" $xlog_first_page_lsn_calc

    # 根据文件第 8~16 字节计算当前文件段第一个 page 的十六进制 LSN
    xlog_first_page_lsn_line=($(hexdump -s 8 -n 8 $xlog_file -C | head -n 1))
    debug_echo "LSN line: ${xlog_first_page_lsn_line[@]}"
    xlog_first_page_lsn_bytes=(${xlog_first_page_lsn_line[@]:1:8})
    debug_echo "LSN bytes: ${xlog_first_page_lsn_bytes[@]}"
    xlog_first_page_lsn_hex="0x"
    for((i=7;i>=0;i--))
    do
        xlog_first_page_lsn_hex+="${xlog_first_page_lsn_bytes[$i]}"
    done
    echo "LSN read hex: $xlog_first_page_lsn_hex"

    diff=$(($xlog_first_page_lsn_calc-$xlog_first_page_lsn_hex))
    if [[ $diff -ne 0 ]]; then
        echo "[RESULT] $xlog_base    recycled"
    else
        echo "[RESULT] $xlog_base    matched"
    fi
done

使用效果

  1. 查看一批 xlog 文件段
    sh ~/xlog_recycle_check.sh pg_xlog/* | grep RESULT
    image

  2. 查看指定 xlog 文件段
    sh ~/xlog_recycle_check.sh pg_xlog/00000001000000010000001B
    image

  3. 打印调试信息
    sh -v ~/xlog_recycle_check.sh pg_xlog/000000010000000100000032
    image

判定原理

WAL文件的命名包括三部分,每部分都是用8个16进制(4个字节)的字符串表示。

以 WAL 日志文件段64MB为例
● 第一部分,表示时间线,即WAL日志所在的时间线。
● 每4GB大小的日志文件段为一组,则每组有4GB/64MB=64个文件段,即每组的日志文件段至多64个,16进制的范围表示 00~3F,即第三部分的取值范围为 00~3F。
● 当日志的大小(LSN)每超过4GB,则向第二部分进一。

以 00000001000000110000001E 文件段为例:

● 第一部分:00000001 表示日志段所在的时间线为 0x00000001 = 1。
● 第二部分:00000011 表示日志段所在的组号(或者说第N个4GB日志文件,从0开始计数)为 0x00000011 = 17,即第18个4GB文件范围内。
● 第三部分:0000001E 表示日志段所在组的段号(即第N组的第M个文件段,从0开始计数)为 0000001E = 30

总结,00000001000000110000001E 为 第“0x00000011 * 64 + 0x0000001E = 17*64+30 = 1118”个64MB的文件段。

注:这里为什么要乘以64?

那么,该日志文件段,所表示的LSN的起始位置为:

1118 * 64 * 1024 * 1024 = 75027709952 = 0x1178000000

根据XLogPageHeaderData 结构体的定义,每一个XLOG的Page都会有这个页的一些头部信息。
● 前2字节,表示魔数,0xD07E
● 接着的2字节,表示一些flag
● 接着的4字节,表示时间线
● 接着的8字节,表示这个Page的起始LSN
image

再看下,00000001000000110000001E 文件的第8~16个字节,表示的是这个日志文件的第一个页的位置。(看样子是小端模式)。

hexdump -C -n 16 00000001000000110000001E
00000000 7e d0 06 00 01 00 00 00 00 00 00 78 11 00 00 00 |~..........x....|
00000010
根据日志文件的首页信息,可以看出,00000001000000110000001E 文件名与其内容是匹配的。

也可以用python3获取

python3 -c "
f=open('00000001000000110000001E', 'rb')
f.seek(8)
print(hex(int.from_bytes(f.read(8), byteorder='little')))
f.close()
"

那么,当日志文件被checkpoint进程recycle之后,会将旧的日志文件,重命名成新的日志文件,以减少文件的生成次数。

重命名的文件,其文件名与其内容是不匹配的。如 000000010000001100000026

hexdump -C -n 16 000000010000001100000026
00000000 7e d0 06 00 01 00 00 00 00 00 00 74 11 00 00 00 |~..........t....|
00000010

按照上述的说法:
000000010000001100000026的第一个首页的起始位置应该是:

(0x00000011 * 64 + 0x00000026) * (64 * 1024 * 1024) = 75564580864 = 0x1198000000

也就是说,000000010000001100000026 文件的第8~16个字节应该是:00 00 00 98 11 00 00 00,而不是现在的 00 00 00 74 11 00 00 00。

现在的 00 00 00 74 11 00 00 00,其表示的是 0x1174000000 这个首页的LSN地址。

反推,

0x1174000000/(6410241024) = 1117,即是第1117个64MB的文件。

按照每64个64MB文件为一组,其
● 组号为:1117 / 64 = 17 = 0x11
● 组内的段号为:1117 % 64 = 29 = 0x1D

即,这个文件的首页内容所在的WAL日志文件段名应该是:00000001000000110000001D

即,000000010000001100000026 是由 00000001000000110000001D 重命名的来。

标签:文件,00,删除,xlog,echo,日志,page
来源: https://www.cnblogs.com/zaclu/p/15424855.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有