首页 > 其他分享 >KingbaseES V8R6运维案例之---普通表toast表故障修复

KingbaseES V8R6运维案例之---普通表toast表故障修复

时间:2023-01-11 15:57:06浏览次数:51  
标签:toast test1 V8R6 运维 pg prod id select

案例说明:
数据库在日常的维护过程中,在执行表查询(select),如下图所示,出现“could not read block 0 in file "base/16385/16408": read only 512 of 8192 bytes”故障,通过对“base/16385/16408”的定位,故障和toast表有关。本案例复现了以上故障,并提供了解决方案。

适用版本:
KingbaseES V8R6

一、案例复现
TOAST存储的表不能单独创建,只有当普通表包含了main,extended或external存储格式的字段时,系统会自动创建一个和普通表关联的TOAST表。当一行记录(tuple)存储的(包括压缩后的大小)大小超过TOAST_TUPLE_THRESHOLD(默认2K)时,会存储到TOAST表。

1、创建测试表及插入数据

# 创建测试表
prod=# create table test1(id int primary key ,v_name varchar);
CREATE TABLE

#查看表结构
prod=# \d+ test1
                                   Table "public.test1"
 Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
 id     | integer |           | not null |         | plain    |              |
 v_name | varchar |           |          |         | extended |              |
Indexes:
    "test1_pkey" PRIMARY KEY, btree (id)
Access method: heap

# 插入大字段数据
prod=# insert into test1 select generate_series(1,100),'a';
INSERT 0 100
prod=# insert into test1 select generate_series(101,200),repeat(md5(random()::text),8000);
INSERT 0 100
prod=# insert into test1 select generate_series(201,300),'b';
INSERT 0 100
---当字段的storage标识为“extended“时,如果字段值默认超过2k,会对字段执行压缩,如果压缩后的size
仍大于2k,则将字段值存入toast表,在源表建立到toast表的指针。

2、查看toast表信息

#获取源表对应的toast表OID
prod=# select oid,reltoastrelid,relname from pg_class where relname='test1';
  oid  | reltoastrelid | relname
-------+---------------+---------
 16405 |         16408 | test1
(1 row)

#获取toast表名称
prod=# select oid,relname from pg_class where oid=16408;
  oid  |    relname
-------+----------------
 16408 | pg_toast_16405
(1 row)

#获取toast表数据文件存储路径
prod=# select pg_relation_filepath('pg_toast.pg_toast_16405');
 pg_relation_filepath
----------------------
 base/16385/16408
(1 row)

prod=# select count(*) from  pg_toast.pg_toast_16405;
 count
-------
   200
(1 row)

prod=# \d+  pg_toast.pg_toast_16405;
TOAST table "pg_toast.pg_toast_16405"
   Column   |  Type   | Storage
------------+---------+---------
 chunk_id   | oid     | plain
 chunk_seq  | integer | plain
 chunk_data | bytea   | plain

二、模拟toast表数据文件故障

#模拟toast表数据文件故障
[kingbase@node102 ~]$ dd if=/dev/zero of=/data/kingbase/v8r6_c6/data/base/16385/16408 bs=512 count=1
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.000188319 s, 2.7 MB/s

[kingbase@node102 ~]$ ls -lh /data/kingbase/v8r6_c6/data/base/16385/16408
-rw------- 1 kingbase kingbase 512 Nov  3 11:21 /data/kingbase/v8r6_c6/data/base/16385/16408

#重启数据库并清理缓存
[kingbase@node102 bin]$ ./sys_ctl stop -D /data/kingbase/v8r6_c6/data
waiting for server to shut down.... done
server stopped

[root@node102 ~]#  echo 3 > /proc/sys/vm/drop_caches

[kingbase@node102 bin]$ ./sys_ctl start -D /data/kingbase/v8r6_c6/data
waiting for server to start....2022-11-03 11:22:12.466 CST [15429] LOG:  sepapower extension initialized
.......
server started


#查询源表数据出现块故障
prod=# select * from test1;
ERROR:  could not read block 0 in file "base/16385/16408": read only 512 of 8192 bytes

# toast表数据为空
prod=# select * from  pg_toast.pg_toast_16405 limit 2;
 chunk_id | chunk_seq | chunk_data
----------+-----------+------------
(0 rows)

# 可以对源表做行统计查询
prod=# select count(*) from test1;
 count
-------
   300
(1 row)

三、解决toast表故障步骤

1、尝试重建索引并对表分析

# 尝试重建索引
prod=# reindex table test1;
REINDEX
prod=# reindex table pg_toast.pg_toast_16405;
REINDEX

# 执行表分析
prod=# vacuum analyze test1;
VACUUM

# 源表查询依然出现故障
prod=# select * from test1;
ERROR:  missing chunk number 0 for toast value 16413 in pg_toast_16405

2、定位源表发生故障的记录

# 尝试通过手工方式定位
prod=#  select * from test1 order by id limit 1 offset 1;
 id | v_name
----+--------
  2 | a
(1 row)

prod=#  select * from test1 order by id limit 1 offset 100;
ERROR:  missing chunk number 0 for toast value 16413 in pg_toast_16405

prod=#  select * from test1 order by id limit 100 offset 0;
 id  | v_name
-----+--------
   1 | a
   2 | a
   3 | a
   4 | a
   5 | a
   6 | a
   7 | a
   8 | a
   9 | a
........

prod=#  select * from test1 order by id limit 100 offset 1;
ERROR:  missing chunk number 0 for toast value 16413 in pg_toast_16405

#通过脚本定位故障记录

[kingbase@node102 ~]$ cat chk_toast.sh
#!/bin/bash
CNT=300         #300是表的总行数
CMD_DIR='/opt/Kingbase/ES/V8R6_C6/Server/bin'
PORT=54325

for ((i=1; i<=CNT;i++))
do
  $CMD_DIR/ksql -U system  prod -p $PORT  -c "SELECT * FROM test1 order by id  LIMIT 1 offset $i" >/dev/null || echo $i
done

# 执行脚本
[kingbase@node102 ~]$ sh chk_toast.sh
ERROR:  missing chunk number 0 for toast value 16413 in pg_toast_16405
100
ERROR:  missing chunk number 0 for toast value 16414 in pg_toast_16405
101
ERROR:  missing chunk number 0 for toast value 16415 in pg_toast_16405
102
........
ERROR:  missing chunk number 0 for toast value 16511 in pg_toast_16405
198
ERROR:  missing chunk number 0 for toast value 16512 in pg_toast_16405
199

---如上所示,从第100行开始到199行,字段v_name的字段值存储在toast表,因toast表故障,因此无法从源表访问。

3、清理源表中故障记录

# 确定源表需清理的记录
prod=#  select * from test1 order by id limit 1 offset 99;
 id  | v_name
-----+--------
 100 | a
(1 row)

prod=#  select * from test1 order by id limit 1 offset 199;
ERROR:  missing chunk number 0 for toast value 16512 in pg_toast_16405

prod=#  select * from test1 order by id limit 1 offset 200;
 id  | v_name
-----+--------
 201 | b
(1 row)

#删除源表中故障记录
prod=# delete from test1 where id >100 and id <201;
DELETE 100

#清理故障记录后源表可以正常查询
prod=# select * from test1;
 id  | v_name
-----+--------
   1 | a
   2 | a
   3 | a
   4 | a
   5 | a
   6 | a
   7 | a
   8 | a
   9 | a
  10 | a
  11 | a
  12 | a
  13 | a
  14 | a
.......

prod=# select count(*) from test1;
 count
-------
   200
(1 row)


prod=# select * from pg_toast.pg_toast_16405;
 chunk_id | chunk_seq | chunk_data
----------+-----------+------------
(0 rows)

#源表插入数据
prod=# insert into test1 select generate_series(101,200),repeat(md5(random()::text),8000);
INSERT 0 100

#toast表生成新的记录
prod=# select count(*) from pg_toast.pg_toast_16405;
 count
-------
   200
(1 row)

prod=# insert into test1 select generate_series(301,400),repeat(md5(random()::text),8000);
INSERT 0 100
prod=# select count(*) from pg_toast.pg_toast_16405;
 count
-------
   400
(1 row)


prod=# select count(distinct chunk_id) from pg_toast.pg_toast_16405 ;
 count
-------
   200
(1 row)

---从以上所示,toast表故障问题已经解决。

四、总结
因toast表坏块问题,将导致源表不可访问,如果有有效的备份,可以通过备份来进行故障的恢复;如果没有有效的备份,可以通过对源表故障记录的清理,完成toast表的恢复。

标签:toast,test1,V8R6,运维,pg,prod,id,select
From: https://www.cnblogs.com/kingbase/p/16854984.html

相关文章

  • 生产数据新增子表(用于保存历史数据)解决方案 ,含数据运维
    先说需求,可以简化为学生提交作业的一个需求,之前是学生提交作业->老师评价作业,每个学生每个作业只会有一条数据,学生再次提交是去更新他的作业现在需要改成 学生提交作业->......
  • 运维基础
    阿里云镜像:https://developer.aliyun.com/mirror/centos上有很多第三方的软件,yum需要安装epel源,才能进行下载#查看进程ps-ef#查看端口netstat-tunlp#CURLlinux......
  • jenkins 运维管理及备份恢复
    一、运维管理二、备份恢复系统管理->系统配置  cpconfig.xml/usr/local/jenkinsbf/cp-rjobs/usr/local/jenkinsbf/cp-rusers/usr/local/jenkinsbf......
  • KingbaseES V8R6 索引膨胀
    索引膨胀对于索引,随着业务不断的增删改,会造成膨胀,尤其Btree索引,也会涉及索引分裂、合并等,导致索引访问效率降低、维护成本增加。另外,索引页的复用与HEAPPAGE不一样,因为索......
  • KingbaseES V8R6 中unlogged表
    前言KingbaseESV8R6有一种表称为unlogged,在该表新建的索引也属于unlogged。和普通表的区别是,对该表进行DML操作时候不将该表的变更记录变更写入到wal文件中。在数据库异常......
  • 网络运维实用小工具
    常用工具一:tcping.exe我们需要测试tcp端口,ping命令虽然好用,但​不能测试端口,因为ping基于ICMP协议,属于IP层协议,所以无法测试传输层的TCP/UDP端口。1、WIN+R按键,输入CMD打开......
  • 无监控,不运维!深入浅出介绍ChengYing监控设计和使用
    监控系统俗称「第三只眼」,几乎是我们每天都会打交道的系统,它也一直是IT系统中的核心组成部分,负责问题的发现以及辅助性的定位。ChengYing作为一站式全自动化全生命周期大......
  • Linux运维笔记[9]-磁盘管理
    RAID简介[https://zhuanlan.zhihu.com/p/356299159][https://www.cnblogs.com/qi-yuan/p/11735525.html]磁盘阵列(RedundantArraysofIndependentDisks,RAID),有“独立磁......
  • sysAK(青囊)系统运维工具集:如何实现高效自动化运维?
    系统运维SIG已在龙蜥社区建立SIG组。目前sysAK工具集已经在龙蜥社区开源,并且在系统运维SIG、跟踪诊断SIG一起共建,希望大家后期加入SIG一起讨论共建。本文将从技......
  • Linux运维
    Linux1.查看内存、CPU1.内存消耗最多的前10个进程:psauxw|head-1;psauxw|sort-rn-k4|head-102.CPU占用最多的前10个进程:psauxw|head-1;psauxw|sort-r......