记录一次金仓V8R3数据库坏块处理过程PostgreSQL数据库适用

Posted yuzhijian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记录一次金仓V8R3数据库坏块处理过程PostgreSQL数据库适用相关的知识,希望对你有一定的参考价值。

因数广政务云华为业务存储固件升级,导致数据库产生坏块,业务SQL查询报错如下:

ERROR:  missing chunk number 0 for toast value 38166585 in SYS_TOAST_30170
CONTEXT:  PL/SQL function inline_code_block line 12 at FOR over EXECUTE statement

解决办法:

1、先查询出 SYS_TOAST_30170 属于哪张表的大字段。

select 
  n.nspname AS schema_name,
  c.relname AS table_name,
  a.attname AS column_name,
  bb.relname as TOAST_name
 from 
  sys_class c 
  inner join (select substring(sc.RELNAME from \'[0-9]+\') gg, sc.relname from sys_class sc) bb on c.relfilenode = bb.gg
  inner join sys_attribute a on a.attrelid = c.oid
  inner join sys_namespace n ON n.oid = c.relnamespace
  WHERE 
    a.attnum > 0 
  AND NOT a.attisdropped
  AND a.atttypid = (SELECT oid FROM sys_type WHERE typname = \'text\')  
  and bb.relname = \'SYS_TOAST_30170\';

PostgreSQL使用以下脚本:

select 
  n.nspname AS schema_name,
  c.relname AS table_name,
  a.attname AS column_name,
  bb.relname as TOAST_name
 from 
    pg_class c 
    inner join (select substring(sc.RELNAME from \'[0-9]+\') gg, sc.relname from pg_class sc) bb on c.relfilenode = bb.gg
    inner join pg_attribute a on a.attrelid = c.oid
    inner join pg_namespace n ON n.oid = c.relnamespace
    WHERE 
    a.attnum > 0 
    AND NOT a.attisdropped
    AND a.atttypid = (SELECT oid FROM pg_type WHERE typname = \'text\')  
    and bb.relname = \'SYS_TOAST_30170\';

2、创建一张记录含有坏块行的表、row_error_table

CREATE TABLE row_error_table (
    err_ctid tid,
    err_tablename varchar2(1000),
    err_cloum varchar2(500),
    err_CONTEXT text
);

3、使用下面脚本找到坏块在哪些行进行处理。

DO $$
DECLARE
    rec RECORD;        
    
    v_tablename text := \'g_inbox\';     
        
    v_columnname text := \'PROCESS_CONTENT\';                
BEGIN
    FOR rec IN EXECUTE format(\'SELECT ctid, %I FROM %I ORDER BY ctid \', v_columnname, v_tablename) LOOP
        BEGIN
            RAISE NOTICE \'CTID Parameter is: %\', rec.ctid;
            RAISE NOTICE \'ROW Parameter is: %\', rec.PROCESS_CONTENT;
        EXCEPTION WHEN others THEN 
      
            INSERT INTO row_error_table (err_ctid, err_tablename,err_cloum,err_CONTEXT) VALUES (rec.ctid, v_tablename,v_columnname,SQLERRM);
        END;
    END LOOP;
END;
$$ 
LANGUAGE plsql;

这个脚本会对需要检测坏块的表进行全表扫描,逐行验证是否有坏块。

  v_tablename text := \'g_inbox\';                             /* 需要检测坏块的表、手动输入 */

  v_columnname text := \'PROCESS_CONTENT\';                /* 需要检测坏块的列、手动输入 */   

检测坏块的时间取决于表的数据量。

 

脚本跑完以后会显示DO。

4、上面脚本跑完以后检查哪些行是有坏块。

SELECT * FROM row_error_table;

保存坏块的表名和列名都有显示,保存着CTID。

5、校验行是否有坏块。

查询整行记录报错,确定是有坏块

6、找到坏块的主键id。

找到主键ID以后,可以通过备份集找到原来的备份在异机进行恢复,然后通过主键ID找到着5行数据导出,然后在生产库导入即可。

 

 

 

 

 

 

oracle坏块处理记录

 

1. 执行sql:select count(distinct id) from bw_fpzxx ,报错如下:

ORA-01578: ORACLE 数据块损坏 (文件号 16, 块号 195428)
ORA-01110: 数据文件 16: ‘/disk01/hwxx09.dbf‘
01578. 00000 -  "ORACLE data block corrupted (file # %s, block # %s)"

2.确认block_no 为195428的数据。

select id,rownum,rowid,dbms_rowid.rowid_relative_fno(rowid) rel_fno,dbms_rowid.rowid_block_number(rowid)
blockno from bw_fpzxx where dbms_rowid.rowid_relative_fno(rowid)=16 and
dbms_rowid.rowid_block_number(rowid)
=195428--rownum <8;

/*
1  1100623697598  1  AAASNhAAQAAAvtkAAL  16  195428
2  1100623690430  2  AAASNhAAQAAAvtkAAE  16  195428
3  1100623693502  3  AAASNhAAQAAAvtkAAH  16  195428
4  1100623687358  4  AAASNhAAQAAAvtkAAB  16  195428
5  1100623695550  5  AAASNhAAQAAAvtkAAJ  16  195428
6  1100623691454  6  AAASNhAAQAAAvtkAAF  16  195428
7  1100623698622  7  AAASNhAAQAAAvtkAAM  16  195428
8  1100623688382  8  AAASNhAAQAAAvtkAAC  16  195428
9  1100623694526    9    AAASNhAAQAAAvtkAAI    16    195428
10    1100623696574    10    AAASNhAAQAAAvtkAAK    16    195428
11    1100623692478    11    AAASNhAAQAAAvtkAAG    16    195428
12    1100623686334    12    AAASNhAAQAAAvtkAAA    16    195428
13    1100623689406    13    AAASNhAAQAAAvtkAAD    16    195428
*/

13条数据,把出错的数据块屏蔽了。

3.

alter system set event=‘10231 trace name context forever,level 10‘ scope=spfile;

4.再次执行sql

select count(distinct id) from bw_fpzxx;

147467803


























以上是关于记录一次金仓V8R3数据库坏块处理过程PostgreSQL数据库适用的主要内容,如果未能解决你的问题,请参考以下文章

炫“库”行动-人大金仓有奖征文-KingbaseES V8R3 读写分离集群在线扩容案例

炫“库”行动-人大金仓有奖征文-KingbaseES V8R3 读写分离集群在线扩容案例

炫“库”行动-人大金仓有奖征文-KingbaseES V8R3 读写分离集群在线扩容案例

记一次存储故障导致数据库坏块处理过程

oracle坏块处理记录

一次意外情况出现逻辑坏块的处理