WalMiner插件主要有两个功能,在此记录一下第二个功能数据页挽回(坏块修复),学习一下关于这块的使用方法,方便日后回顾。
1 环境搭建
- 创建WalMiner的extension
create extension walminer;
语句解析: 该句SQL功能是安装一个扩展,详细用法如下:
CREATE EXTENSION [ IF NOT EXISTS ] extension_name
[ WITH ] [ SCHEMA schema_name ]
[ VERSION version ]
[ FROM old_version ]
描述
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
- 添加要解析的wal日志文件
我的wal log 路径:
“/usr/local/pgsql/data/pg_wal/000000010000000000000002”
-- 添加wal文件:
select walminer_wal_add('/usr/local/pgsql/data/pg_wal');
-- 注:参数可以为目录或者文件
- list wal日志文件
-- 列出wal文件:
![select walminer_wal_list();]
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';
3 执行数据挽回
SQL用法:
select page_collect(relfilenode, reloid, pages)
描述
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");