在日常数据库运维过程中,我们可能会遇到类似以下的错误。该错误信息是由于部分tuple的 toast 字段丢失,导致数据无法访问。需要通过游标方式,将可以访问的数据备份出来。

test=# create table t2_text as select * from t1_text;
ERROR: unexpected chunk size -4 (expected 1996) in chunk 0 of 4 for toast value 61962 in pg_toast_61919

注意:设置 zero_damaged_pages = on 无法解决该问题。

一、R6 处理逻辑

以下例子模拟 t1_text表部分tuple 的 text 字段出现损坏,需要通过游标将数据从 t1_text 迁移至 t2_text 。游标如下:

create table ctid_done_tmp123(rid tid,result varchar(9));
create table t2_text as select * from t1_text where 1=2; create or replace procedure process_error_ctid as
v_tid tid;
cursor cur_t1_text is select ctid from t1_text where ctid not in (select rid from ctid_done_tmp123);
begin
open cur_t1_text;
loop
fetch cur_t1_text into v_tid;
exit when cur_t1_text%NOTFOUND;
begin
insert into t2_text select * from t1_text where ctid=v_tid;
insert into ctid_done_tmp123 values(v_tid,'SUCCESS');
exception
when others then
insert into ctid_done_tmp123 values(v_tid,'ERROR');
commit;
exit;
end;
end loop;
end;
/ declare
v_oldcnt integer;
v_newcnt integer;
begin
select count(*) into v_oldcnt from ctid_done_tmp123;
v_newcnt := 0;
while (true) loop
call process_error_ctid();
select count(*) into v_newcnt from ctid_done_tmp123;
if v_oldcnt = v_newcnt then
exit;
end if;
end loop;
end;

注意:以上的例子通过不停的调用函数process_error_ctid来实现,这是由于我们当前的游标不支持跨事务,后续可以修改该脚本。

这里有几个问题需要注意:

  1. 需要设置 ora_statement_level_rollback = on。PG 过程块默认在进入 exception 之前,会将之前的所有操作 rollback,因此,即使在exception 处理时,将事务 commit,实际也没任何意义。对于 Oracle ,如果用户有捕获异常,可以选择将对异常之前的数据commit or rollback。KINGBASE  ora_statement_level_rollback  参数的作用就是:如果 ora_statement_level_rollback = on,在遇到异常后,只是回退引发异常的操作,而之前的事务操作可以选择commit or rollback。
  2. 对于oracle,过程块中间可以commit or rollback ,而cursor 不会被close;KINGBASE 当前的游标还不允许跨事务,也就是说,如果事务commit,或者碰到异常,事务就结束,游标也会被关闭,比如以上的例子就会报 “cursor "cur_t1_text" does not exist” 错误。这点 KINGBASE 还在开发当中,后续会支持。
  3. 以上脚本只能在V8R6上执行,这是由于参数ora_statement_level_rollback 只有R6有。如果需要在R3上运行,需要修改下逻辑

二、R3 处理逻辑

R3 版本在遇到异常时,事务操作都被回退,因此,只能取到 Error 记录的 ctid。 由于需要重复执行,效率不高。

create table ctid_done_tmp123(rid tid,result varchar(9));
create table t2_text as select * from t1_text where 1=2; create or replace procedure process_error_ctid as
v_tid tid;
v_name text;
cursor cur_t1_text is select ctid from t1_text where ctid not in (select rid from ctid_done_tmp123);
begin
open cur_t1_text;
loop
fetch cur_t1_text into v_tid;
exit when cur_t1_text%NOTFOUND;
begin
select name into v_name from t1_text where ctid=v_tid; --只需访问lob 字段
exception
when others then
insert into ctid_done_tmp123 values(v_tid,'ERROR');
commit;
exit;
end;
end loop;
end;
/ declare
v_oldcnt integer;
v_newcnt integer;
begin
select count(*) into v_oldcnt from ctid_done_tmp123;
v_newcnt := 0;
while (true) loop
call process_error_ctid();
select count(*) into v_newcnt from ctid_done_tmp123;
if v_oldcnt = v_newcnt then
exit;
end if;
end loop;
end;
/ insert into t2_text select * from t1_text where ctid not in (select rid from ctid_done_tmp123);

Toast 部分记录丢失问题处理的更多相关文章

  1. Toast问题记录:This Toast was not created with Toast.makeText()

    最近使用自己封装的Toast时,遇到一个问题 java.lang.RuntimeException: This Toast was not created with Toast.makeText() ...

  2. Replication的犄角旮旯(二)--寻找订阅端丢失的记录

    <Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...

  3. current online redo logfile 丢失的处理方法

    昨天做了rm -rf操作后的恢复演练,并且是在没有不论什么备份的情况下.今天在做破坏性操作前,做了个rman全备,然后在线删除所有数据库文件,包含控制文件,数据文件,在线日志文件,归档文件等.来看看有 ...

  4. [Android] Toast问题深度剖析(一)

    欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 题记 Toast 作为 Android 系统中最常用的类之一,由于其方便的api设计和简洁的交互体验,被我们所广泛采用.但是,伴随着我们开发的深 ...

  5. mysql同时使用order by和limit查询时的一个严重隐患 -- 丢失数据

    转自: https://blog.csdn.net/tsxw24/article/details/44994835 我经常使用order by和limit来做数据分页显示并排序,一直也没发现过什么问题 ...

  6. SVN代码丢失惊魂

    吓死了吓死了!要是那些代码丢了的话,要重新码一遍,我宁愿去吃屎. 某天快下班走人的时候,从SVN服务器update了本地代码,结果发现代码变回了上个月的样子.看SVN的日志,发现提交记录从6月22日一 ...

  7. 第二课 TXT读取 - 导出 - 选择顶部/底部记录 - 描述性统计 - 分组/排序

    第2课 创建数据 - 我们从创建自己的数据集开始分析.这可以防止阅读本教程的最终用户为得到下面的结果而不得不下载许多文件.我们将把这个数据集导出到一个文本文件中,这样您就可以获得从文本文件中一些拉取数 ...

  8. MongoDB 副本集丢失数据的测试

    在MongoDB副本集的测试中发现了一个丢数据的案例. 1. 概要描述 测试场景为:一主一从一验证 测试案例 step1 :关闭从副本: step 2 :向主副本中插入那条数据: step 3 :关闭 ...

  9. 对Oracle数据库坏块的理解

    1.物理坏块和逻辑坏块 在数据库中有一个概念叫做数据块的一致性,Oracle的数据块的一致性包括了两个层次:物理一致性和逻辑一致性,如果一个数据块在这两个层次上存在不一致性,那就对应到了我们今天要要说 ...

随机推荐

  1. 视图模板引擎——Vue【双向绑定】原理剖析

    首先我们来了解一下MVC.MVP.MVMM这三大架构模式在前端角度上的理解. MVC分别是 Model(模型).View(视图).Controller(控制器)三个模块.View(视图层)最主要完成前 ...

  2. 程序员必备,一款让你提高工作效率N倍的神器uTools

    下载地址:https://www.aliyundrive.com/s/f7PU7QxdxEz uTools 是什么? uTools = your tools(你的工具集) uTools 是一个极简.插 ...

  3. RPA应用场景-产品主数据同步

    场景概述 产品主数据同步 所涉系统名称 产品管理系统.SAP系统 人工操作(时间/次) 35分钟 所涉人工数量 3 操作频率 不定时 场景流程1.登录收购品牌产品管理系统 2.根据时间.产品分类等选择 ...

  4. C4C UI Design背景色

  5. NC14662 小咪买东西

    NC14662 小咪买东西 题目 题目描述 小咪是一个土豪手办狂魔,这次他去了一家店,发现了好多好多( \(n\) 个)手办,但他是一个很怪的人,每次只想买 \(k\) 个手办,而且他要让他花的每一分 ...

  6. Linux从root切换某个用户时可能出现:-bash-4.1$

    Linux从root切换某个用户时可能出现:-bash-4.1$ 如下所示:[root@server ~]# su - postgres-bash-4.1$ id postgresuid=26(pos ...

  7. SpringBoot自定义starter开发分布式任务调度实践

    概述 需求 在前面的博客<Java定时器演进过程和生产级分布式任务调度ElasticJob代码实战>中,我们已经熟悉ElasticJob分布式任务的应用,其核心实现为elasticjob- ...

  8. 当mysql表从压缩表变成普通表会发生什么

    前言 本文章做了把mysql表从压缩表过渡到普通表的实验过程,看看压缩表变成普通表会发生什么?本文针对mysql5.7和mysql8分别进行了实验. 1.什么是表压缩 在介绍压缩表变成普通表前,首先给 ...

  9. Java实现动态代理

    1.实现InvocationHandler接口 这种方式只能针对接口实现类的实例对象. interface Hello{ public void sayHello(); } class HelloIm ...

  10. Mybatis-Generator 自定义注释

    继承DefaultCommentGenerator 或者CommentGenerator package com.zhianchen.mysqlremark.toword.config;import ...