南大通用GBase 8a手工设置表某个分片为故障状态的方法

GBase 8a 集群,当某个分片出现故障时,会自动检测并设置故障标志,但某些特殊情况出现的逻辑错误,比如行数不一样,则数据库自身无法判断以哪个为准,此时需要人工干预来进行故障恢复。

原因

目前我这里已知的主副本行数出现不一致的情况如下:

1、对数据计算节点的分片做了直接操作。

比如向分片里手工插入或删除了数据。

2、文件系统故障,导致event无法被正确记录

出现过磁盘空间满,导致event文件的新版本无法正确写入而导致event丢失。

3、手工清理event时范围被意外放大

比如清理某个表的event, 结果操作成了某个节点IP的event, 结果有效的未处理的event被清掉了。

解决方案

1、手工同步

请参考 GBase 8a集群通过gc_sync_client手工同步分片数据

就当成2个都有问题处理,重点是选择其中一个可用的为主,覆盖另外一个。

2、手工设置故障标记

如果设置命令出错

gcluster command error : The nodeid given don't exist or suffix and nodeid is not matched.

是因为指定的表并在这个nodeid上存在分片。比如表只有n1和n2, 指定的是n15,那就就报这个错误。常见于扩容后的场景。

v8命令

set self gcluster_node_status_list="库名.表名:分片号:主机nodeid:状态:SCN号";

注意其中的分隔符,除了库名和表名是小数点,其它的都是冒号

  • 库名.表名 设置的目的表
  • 分片号,比如n1, n2。复制表为空即可。
  • 主机nodeid, 可以从show nodes里看到。详情看后面介绍
  • 状态:写2 就行了,其中2=dml, 16=ddl,32=dmlstorage。内部会根据情况自动做判断和升级。部分状态可以看这里 GBase 8a查看某张表当前主副本可用状态、是否存在event
  • SCN号:随意写,同步后会以主为准。 一般都写2

v95命令

在V95版本里,多了虚拟集群(VC), 所以命令格式稍有变化,多了VCID, 注意不是vcname, 是ID,可以通过show vcs查看每个vcname对应的vcid, 默认是vc00001。其它与V8完全相同

set self gcluster_node_status_list="vcid.库名.表名:分片号:主机nodeid:状态:SCN号";

虚拟集群vcid

gbase> show vcs;
+---------+--------------+---------+
| id      | name         | default |
+---------+--------------+---------+
| vc00001 | vcname000001 | Y       |
+---------+--------------+---------+
1 row in set (Elapsed: 00:00:00.00)

主机nodeid

根据IP,找到最前面的Id列,就是对应的nodeid。 比如 10.0.2.202 对应的是3389128714

gbase> show nodes;
+------------+------------+-------+--------------+----------------+--------+-----------+
| Id         | ip         | name  | primary part | duplicate part | status | datastate |
+------------+------------+-------+--------------+----------------+--------+-----------+
| 3389128714 | 10.0.2.202 | node2 | n1           | n2             | online |         0 |
| 3372351498 | 10.0.2.201 | node1 | n2           | n1             | online |         0 |
+------------+------------+-------+--------------+----------------+--------+-----------+

V8样例

设置n1
gbase> set self gcluster_node_status_list="testdb.t4:n1:3389128714:2:2";
Query OK, 0 rows affected (Elapsed: 00:00:00.02)

设置n2
gbase> set self gcluster_node_status_list="testdb.t4:n2:3389128714:2:2";
Query OK, 0 rows affected (Elapsed: 00:00:00.03)

4、查看event
[gbase@rh6-1 gcluster]$ gcadmin showdmlevent
Event count:1
Event ID:    18
ObjectName: testdb.t4

Fail Data Copy:
------------------------------------------------------
SegName: n1     SCN: 2  NodeIP: 10.0.2.202      FAILURE
SegName: n2     SCN: 2  NodeIP: 10.0.2.202      FAILURE

V95版本样例


gbase> set self gcluster_node_status_list='vc00001.testdb.t1:n1:1694629898:2:2';
Query OK, 0 rows affected (Elapsed: 00:00:00.03)

设置集群调度层(coordinator gcluster)dmlstoragefevent的方法

如上的set 只能设置计算节点gnode的event. 如下用python方案,设置调度层gcluster的event

import gcware
fevent = {}
fevent['eventid'] =1
fevent['vcid']='vc00001'
fevent['distributionid'] = 1
# select table_id from information_schema.tables where table_schema='testdb' and table_name='t1'
fevent['tableid'] = 2052
fevent['tablename'] = "testdb.t1"
fevent['comment'] = 'Hello World'
#下面的true代表是集群层, false标识节点层
fevent['content'] = 'testdb.t1,,true'
fevent['tabletype'] = 'DISTRIBUTION'
datacopyid = {}
#如果是集群层,则填写集群层的nodeid, 如果是节点层,则写分片号,比如1,2,3
datacopyid['segid'] = 3372351498
datacopyid['nodeipaddr'] = "10.0.2.201"
fevent['datacopyid'] = datacopyid
eventid = gcware.setdmlstoragefevent(fevent)

如上代码中的content, 用来区分是管理层还是计算层。如果是管理层,则segid为节点的nodeid,如果是计算层,则是分片编号。