案例说明:

数据库在日常的维护过程中,在执行表查询(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表的恢复。

KingbaseES V8R6运维案例之---普通表toast表故障修复的更多相关文章

  1. KingbaseES V8R6备份恢复案例之---自定义表空间指定恢复目录数据恢复

    案例说明: KingbaseES V8R6在通过sys_rman执行物理备份恢复时,可以通过参数'--kb1-path',指定恢复的数据(data)目录,但如果原备份中包含自定义表空间时,需要建立表空 ...

  2. KingbaseES V8R3集群运维案例之---用户自定义表空间管理

    ​案例说明: KingbaseES 数据库支持用户自定义表空间的创建,并建议表空间的文件存储路径配置到数据库的data目录之外.本案例复现了,当用户自定义表空间存储路径配置到data下时,出现的故障问 ...

  3. KingbaseES V8R6集群管理运维案例之---repmgr standby switchover故障

    案例说明: 在KingbaseES V8R6集群备库执行"repmgr standby switchover"时,切换失败,并且在执行过程中,伴随着"repmr stan ...

  4. KingbaseES V8R6集群运维案例之---repmgr standby promote应用案例

    案例说明: 在容灾环境中,跨区域部署的异地备节点不会自主提升为主节点,在主节点发生故障或者人为需要切换时需要手动执行切换操作.若主节点已经失效,希望将异地备机提升为主节点. $bin/repmgr s ...

  5. 运维案例 | Exchange2010数据库损坏的紧急修复思路

    ​​关注嘉为科技,获取运维新知 Exchange后端数据库故障,一般都会是比较严重的紧急故障,因为这会直接影响到大面积用户的正常使用,而且涉及到用户数据.一旦遇到这种级别的故障,管理员往往都是在非常紧 ...

  6. KingbaseES V8R6备份恢复案例之---同一数据库创建不同stanza备份

    案例说明: 在生产环境,有的应用需要调用数据库的sys_rman做备份,为了区分数据库自身的sys_rman备份和应用的备份,可以使用不同的stanza name创建备份.本案例介绍了,如何在King ...

  7. KingbaseES V8R6备份恢复案例之--删除test数据库后sys_backup.sh备份

    案例说明: KingbaseES V8R6通过sys_backup.sh执行物理备份,默认sys_backup.sh执行备份初始化时,需要连接test数据库进行身份的认证:在一些生产环境为了安全需求, ...

  8. KingbaseES V8R6备份恢复案例之---手工清理冗余历史备份

    案例说明: 对于KingbaseES V8R6的通过sys_rman执行的物理历史备份,可以在执行备份时,备份的保留(retention)策略自动清理.不能通过手工删除备份,可以通过expire参数手 ...

  9. python运维开发(十九)----Django后台表单验证、session、cookie、model操作

    内容目录: Django后台表单验证 CSRF加密传输 session.cookie model数据库操作 Django后台Form表单验证 Django中Form一般有2种功能: 1.用于做用户提交 ...

  10. KingbaseES V8R3集群运维案例之---主库系统down failover切换过程分析

    ​ 案例说明: KingbaseES V8R3集群failover时两个cluster都会触发,但只有一个cluster会调用脚本去执行真正的切换流程,另一个有对应的打印,但不会调用脚本,只是走相关的 ...

随机推荐

  1. Linux驱动开发笔记(三):基于ubuntu的helloworld驱动源码编写、makefile编写以及驱动编译加载流程测试

    前言   前面学习了驱动的基础框架,上一篇编译了gcc7.3.0,那么为了方便很好的熟悉流程,本篇,将使用ubuntu18.04,直接编译ubuntu18.04的驱动,然后做好本篇文章的相关实战测试. ...

  2. 硬件开发笔记(七): 硬件开发基本流程,制作一个USB转RS232的模块(六):创建0603封装并关联原理图元器件

    前言   有了原理图,可以设计硬件PCB,在设计PCB之间还有一个协同优先动作,就是映射封装,原理图库的元器件我们是自己设计的.为了更好的表述封装设计过程,本文描述了贴片电阻电容0603芯片封装,创建 ...

  3. 【Azure Redis 缓存】Azure Redis读写比较慢/卡的问题排查

    问题描述 在使用Azure Redis的过程中发现读写比较慢,非常卡,执行扩容6-->13GB后,过一段时间也满了.在通过门户Console连接到Reids,通过info Memory名称查看到 ...

  4. STM32标准库内部Flash读写

    STM32标准库FLASH读写 1. STM32内部FLASH介绍 STM32系列一般集成有内部flash,这部分内存可以直接通过指针的形式进行读取.但是由于内部flash一般存储为重要数据或程序运行 ...

  5. BUUCTF—Crypto(完结版本—_—)

    BUUCTF-Crypto 1.一眼就解密 考点:base64 我的解答: 字符串后面的等号,看来是base大家族,由字母和数字范围来看是base64,不管了,先扔CyberCher,仙女魔法棒变出f ...

  6. 使用OpenFeign远程调用时请求头处理报错问题

    1. 错误信息 basic.result.exception.OtherException: feign error:系统异常:Content type 'multipart/form-data;bo ...

  7. 冲击900亿美元估值!邀约路演、秘密交表的Shein上市有望

    双十一的狂欢刚刚结束,Shein即将赴美上市的消息又在电商圈里投下一枚重磅炸弹. 继被媒体曝光其寻求900亿美金估值后,最新的消息称其已邀请投资人参与路演,且已秘密完成交表.这个神秘的中国独角兽,离敲 ...

  8. 来也科技收购Mindsay背后:新旧势力交锋智能自动化备受关注

    来也科技收购Mindsay背后:新旧势力交锋智能自动化备受关注 来也科技收购Mindsay背后:历程一波三折,意义非同寻常 来也科技收购Mindsay,国产RPA正式进军国际市场 收购Mindsay来 ...

  9. jQuery 框架

    jQuery 框架 目录 jQuery 框架 一. 概述 二. jQuery 安装引用 2.1 安装 2.2 本地导入使用 2.3 jQuery CDN引入 三. jQuery基本语法 四. 查找标签 ...

  10. 封装svg通用组件

    安装vite-plugin-svg-icons插件 pnpm i vite-plugin-svg-icons -D 在main.ts中引入vite-plugin-svg-icons import 'v ...