在日常数据库运维过程中,我们可能会遇到类似以下的错误。该错误信息是由于部分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. easyui combobox重复渲染问题

    当一个页面有两个easyui combobox存在时,并且同时给两个combobox赋相同值,某些easyui的版本会导致其中一个无法切换选项. 解决办法,分两步赋值,可解决问题

  2. 数据库系列:MySQL索引优化总结(综合版)

    1 背景 作为一个常年在一线带组的Owner以及老面试官,我们面试的目标基本都是一线的开发人员.从服务端这个技术栈出发,问题的范围主要还是围绕开发语言(Java.Go)等核心知识点.数据库技术.缓存技 ...

  3. 合宙Air32F103CBT6开发板上手报告

    2022年6月初合宙新上市了 Air32F103 系列 MCU, 市面上 STM32F103 的克隆军队又增加了新的一员. 这次不知道是哪家的贴牌, 分 Air32F103CBT6 和 Air32F1 ...

  4. 不同network中的两个docker容器

    1. 创建docker网络 docker network create --subnet 172.18.0.1/16 test docker network ls 2. 创建两个容器指定docker ...

  5. bat-配置环境变量2-给PATH追加环境变量

    使用setx /M path "%path%;%%winrar%%"这种方式修改环境变量存在的问题 对于 path 这种 既有用户级变量和系统级变量的变量 直接使用setx /M ...

  6. 用python这样做,offer还不是拿到手软?

    大家好鸭,我是小熊猫 本篇代码提供者: 自游老师 老师简介:青灯教育金牌讲师3年Python爬虫开发经验七年在线教育经验擅长Python.c等语言曾任职多家互联网公司爬虫工程师.Python讲师 [环 ...

  7. Oracle Database 19c (19.3)

    https://www.oracle.com/database/technologies/oracle19c-windows-downloads.htmlOracle Database 19c (19 ...

  8. java包机制

  9. APISpace 号码实时查询API接口 免费好用

    最近公司项目有一个号码实时查询的小功能,想着如果用现成的API就可以大大提高开发效率,所以在网上的API商店搜索了一番,发现了 APISpace,它里面的号码实时查询API非常符合我的开发需求.   ...

  10. 输入一个url全过程详解

    1. 用户在浏览器中输入url,浏览器接收到url. 2.浏览器接收到这个url之后,会根据这个url会先查看缓存,如果有缓存且没有过期的话直接提供给客户端,完成页面渲染. 3.否则浏览器就会通过DN ...