• WalMiner插件之xlog解析恢复使用教程


    WalMiner插件主要有两个功能,在此记录一下第二个功能数据页挽回(坏块修复),学习一下关于这块的使用方法,方便日后回顾。

    1 环境搭建

    1. 创建WalMiner的extension
    create extension walminer;
    
    • 1

    在这里插入图片描述

    语句解析: 该句SQL功能是安装一个扩展,详细用法如下:

    CREATE EXTENSION [ IF NOT EXISTS ] extension_name
        [ WITH ] [ SCHEMA schema_name ]
                 [ VERSION version ]
                 [ FROM old_version ]
    
    • 1
    • 2
    • 3
    • 4
    描述

    create extension命令安装一个新的扩展到一个数据库中,必须保证没有同名的扩展已经被安装。

    安装一个扩展意味着执行一个扩展的脚本文件,这个脚本会创建一个新的SQL实体,如函数,数据类型,操作符,和索引支持的方法。

    参数

    [ IF NOT EXISTS ] 表示如果系统已经存在一个同名的扩展,不会报错。
    extension_name:将被安装扩展的名词。PostgresSQL从SHAREDIR/extension/extension_name.control这个文件安装扩展.
    schema_name:扩展的实例被安装在该模式下,扩展的内容可以被重新安装.指定的模式必须已经存在.如果没有指定,扩展的控制文件也不指定一个模式,这样将使用默认模式.

    【知识扩展】

    PostgreSQL设计为易于扩展,因此,加载到数据库中的扩展功能可以像内置的特性一样运行。扩展是独立开发的,要想使用扩展功能,将其源码放进数据库/contrib目录下,编译安装即可使用。

    contrib模块

    此模块又称为扩展(extensions)。此方法适用于所有使用扩展规范构建的contrib模块,包括如下:

    • 扩展SQL文件( extension_name.sql )
    • 扩展控制文件 ( extension_name.control )
    • 扩展库文件(extension_name.so)

    检查是否安装了contrib模块的好方法是查看pgbench程序是否可用。
    切换成postgres用户,在unix系统下检查pgbench:

    [postgres@Centos7 ~]$ pgbench -V
    
    • 1

    在这里插入图片描述

    1. 添加要解析的wal日志文件
      我的wal log 路径:
      “/usr/local/pgsql/data/pg_wal/000000010000000000000002”
    -- 添加wal文件:
    select walminer_wal_add('/usr/local/pgsql/data/pg_wal');
    -- 注:参数可以为目录或者文件
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    1. list wal日志文件
    -- 列出wal文件:
    ![select walminer_wal_list();]
    
    • 1
    • 2

    在这里插入图片描述

    2 SQL执行

    执行以下SQL,再执行truncate ,就可以实现数据挽回功能。

    DROP EXTENSION IF EXISTS walminer;
    CREATE EXTENSION IF NOT EXISTS walminer;
    
    DROP TABLE t1;
    DROP TABLE t2;
    SELECT walminer_stop();
    CREATE TABLE t1(i int, j int, k varchar);
    CREATE TABLE t2(i int, j int, k varchar);
    
    INSERT INTO t1(i,j,k) SELECT generate_series(1,157),1,'PostgreSQL';
    INSERT INTO t1(i,j,k) SELECT generate_series(1,157),2,'PostgreSQL';
    INSERT INTO t1(i,j,k) SELECT generate_series(1,157),3,'PostgreSQL';
    DELETE FROM t1 WHERE j = 1 AND NOT( ctid >= '(0,1)' AND ctid <= '(0,157)');
    DELETE FROM t1 WHERE j = 2 AND NOT( ctid >= '(1,1)' AND ctid <= '(1,157)');
    DELETE FROM t1 WHERE j = 3 AND NOT( ctid >= '(2,1)' AND ctid <= '(2,157)');
    
    SELECT count(*) AS count1_1 FROM t1 WHERE j = 1 \gset
    SELECT count(*) AS count2_1 FROM t1 WHERE j = 2 \gset
    SELECT count(*) AS count3_1 FROM t1 WHERE j = 3 \gset
    
    SELECT relfilenode AS node_in_datadict FROM pg_class WHERE relname = 't1' \gset
    SELECT oid AS oid_in_curdb FROM pg_class WHERE relname = 't2' \gset
    SELECT setting  AS pgdata  FROM pg_settings WHERE name = 'data_directory' \gset
    SELECT :'pgdata' || '/pg_walminer/wm_datadict/dictionary.d' AS path \gset
    SELECT pg_walfile_name(pg_current_wal_lsn()) AS walfile_name \gset
    SELECT :'pgdata' || '/pg_wal/' || :'walfile_name' AS walfile_path \gset
    
    SELECT walminer_build_dictionary(:'path');
    SELECT walminer_load_dictionary(:'path');
    
    SELECT walminer_wal_add(:'walfile_path');
    SELECT walminer_regression_mode();
    -- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    TRUNCATE t2;
    SELECT page_collect(:'node_in_datadict', :'oid_in_curdb', '0');
    SELECT count(*) AS count1_2 FROM t2 WHERE ctid >= '(0,1)' AND ctid <= '(0,157)' \gset
    SELECT count(*) AS count2_2 FROM t2 WHERE ctid >= '(1,1)' AND ctid <= '(1,157)' \gset
    SELECT count(*) AS count3_2 FROM t2 WHERE ctid >= '(2,1)' AND ctid <= '(2,157)' \gset
    
    SELECT :'count1_1' = :'count1_2';
    SELECT 0 = :'count2_2';
    SELECT 0 = :'count3_2';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    3 执行数据挽回

    SQL用法:

    select page_collect(relfilenode, reloid, pages)
    
    • 1
    描述

    relfilenode:需要解析的wal日志中的relfilenode

    reloid:解析库中存在的表的OID,此命令将会将从wal中找到的page覆盖到reloid制定的表中

    pages:是字符串类型,制定想要挽回的目标page。格式为’0,1,2,7’或者’all’。

    SELECT page_collect("node_in_datadict", "oid_in_curdb", "0");
    
    • 1

    在这里插入图片描述

  • 相关阅读:
    【mq】从零开始实现 mq-11-消费者消息回执添加分组信息 pull message ack groupName
    Qt 利用UDP进行通信
    window安装ELK
    软件设计模式白话文系列(六)代理模式
    JS——手风琴|鼠标悬停图片滚动展示栏 [技术栈:html、css、JavaScript]
    white-space几种属性的用法(处理空格)
    1923. 最长公共子路径
    【路径规划】基于遗传算法求解立体仓库出入库路径优化问题含Matlab代码
    P2P应用
    第十二章 哈希表与字符串哈希
  • 原文地址:https://blog.csdn.net/qq_43893755/article/details/130861861