我们知道Oracle数据库中有自动block修复功能,在主备环境中,如果主库或者备库出现数据坏块,那么Oracle ADG能够进行自动修复。这实际上是Oracle 11.2.0.3版本所引入的一个特性auto block media recover,简称bmr. 这个功能有相关的数据库参数来进行控制,决定是否启用。
NAME VALUE DESCRIB
------------------------------------ ------------ ------------------------------------------------
_auto_bmr enabled
enable/
disable Auto BMR
_auto_bmr_req_timeout 60 Auto BMR Requester Timeout
_auto_bmr_sess_threshold 30 Auto BMR Request Session Threshold
_auto_bmr_pub_timeout 10 Auto BMR Publish Timeout
_auto_bmr_fc_time 60 Auto BMR Flood Control Time
_auto_bmr_bg_time 3600 Auto BMR Process Run Time
_auto_bmr_sys_threshold 100 Auto BMR Request System Threshold
_auto_bmr_max_rowno 1024 x
$krbabrstat Max number of rows
Oracle的这个功能很强大,也非常人性化。当然这个功能的基本原理跟blockrecover类似,copy block+ apply redo。
那么如果你使用国产数据库,比如MogDB,遇到文件损坏或者坏块怎么办呢?
我们知道MogDB使用的文件系统,而openGauss系数据库的表本质上就是一个独立的文件。当文件损坏的时候,那么实际上MogDB也提供了相关的函数来应对这个场景。
这里我给大家简单演示一下。
[omm1@mogdb1 ~]$ gsql -r
gsql ((MogDB 5.0.8 build 41aa0432) compiled at 2024-07-26 12:43:48 commit 0 last mr 1804 )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type
"help"
for
help.
MogDB=
# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges | Compatibility
-----------+-------+----------+---------+-------+-------------------+---------------
aa | aa | UTF8 | C | C | | A
bb | bb | UTF8 | C | C | | B
postgres | omm1 | UTF8 | C | C | | A
template0 | omm1 | UTF8 | C | C | =c/omm1 +| A
| | | | | omm1=CTc/omm1 |
template1 | omm1 | UTF8 | C | C | =c/omm1 +| A
| | | | | omm1=CTc/omm1 |
(5 rows)
MogDB=
# \c aa
Non-SSL connection (SSL connection is recommended when requiring high-security)
You are now connected to database
"aa" as user
"omm1".
aa=
# create table test_corrupt(id int,name varchar(100));
CREATE TABLE
aa=
# insert into test_corrupt select generate_series,generate_series||'MogDB or MogDB Cube' from generate_series(1,100000);
INSERT 0 100000
aa=
# SELECT pg_relation_filepath('test_corrupt');
pg_relation_filepath
----------------------
base/16779/31665
(1 row)
aa=
# checkpoint;
CHECKPOINT
aa=
#
aa=
# \q
万事具备只欠东风!这里模拟删除这个表文件。
注意!注意!如果是生产库,千万别模拟!
[omm1@mogdb1 ~]$
cd
$PGDATA
[omm1@mogdb1 data]$ rm -rf base/16779/31665
[omm1@mogdb1 data]$
[omm1@mogdb1 data]$ gsql -r -d aa
gsql ((MogDB 5.0.8 build 41aa0432) compiled at 2024-07-26 12:43:48 commit 0 last mr 1804 )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type
"help"
for
help.
aa=
# select count(1) from test_corrupt;
ERROR: could not open file
"base/16779/31665": No such file or directory
aa=
#
人为删除这个表文件之后,我们登陆数据库查询发现已经找不到文件了。
aa=
# select * from gs_verify_data_file();
node_name | rel_oid | rel_name | miss_file_path
-------------------+---------+--------------+------------------
dn_6001_6002_6003 | 31665 | test_corrupt | base/16779/31665
(1 row)
aa=
#
aa=
# \timing on
Timing is on.
aa=
# select * from gs_repair_file(31665,'base/16779/31665',600);
gs_repair_file
----------------
t
(1 row)
Time: 530.816 ms
aa=
# select count(1) from test_corrupt;
count
--------
100000
(1 row)
Time: 33.093 ms
aa=
#
大家可以看到,通过gs_verify_data_file 函数可以表文件进行check检查,有点类似Oracle dbv工具。
最后一步是通过gs_repair_file函数来进行文件自动修复。可以看到,非常顺利的修复了这个表文件。
那么这个修复具体是什么逻辑呢?实际上我们看看log 就看发现一些线索。
2024-08-20 15:55:09.762 omm1 aa [
local] 47016331712256 0[0:0
#0] 2251799813808012 [REMOTE] LOG: remote read page size, file base/16779/31665 from 172.20.22.128@17135
2024-08-20 15:55:09.884 omm1 aa [
local] 47016331712256 0[0:0
#0] 2251799813808012 [REMOTE] LOG: remote read page, file base/16779/31665 block start is 0 from 172.20.22.126@54520
2024-08-20 15:55:10.290 omm1 aa [
local] 47016331712256 0[0:0
#0] 2251799813808012 [REDO] LOG: file rename from base/16779/31665.repair to base/16779/31665 finish
大家可以看到,本质上修复的这个文件是从备库去拉取的,同时再应用本地redo。
关于提到的几个函数的功能和一些详细描述,大家可以参考MogDB 官方文档。
https://docs.mogdb.io/zh/mogdb/v5.0/data-damage-detection-and-repair-functions