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,如果是计算层,则是分片编号。