本文主要介绍 OBServer 日志中出现-4122 报错的原因。
OceanBase 数据库 V4.x 版本中启用 pkt-nio 的情况下,日志中返回 -4122 报错是因为对端的 OBServer 被加入了黑名单,相关的日志包括如下。
WDIAG [RPC] check_blacklist (ob_poc_rpc_proxy.cpp:231) [42876][T1_L0_G0][T1][xxxxx-xxxxx-xxxxx-xxxxx] [lt=1][errcode=-4122] address in blacklist(ret=-4122, addr="xxx.xxx.xxx.xxx:xxx")
WDIAG [RPC] send (ob_poc_rpc_proxy.h:139) [42876][T1_L0_G0][T1][xxxxx-xxxxx-xxxxx-xxxxx] [lt=19][errcode=-4122] check_blacklist failed(ret=-4122)
目的端 server 是否在黑名单中的日志如下所示,每分钟打印一次。
[RPC.OBRPC] do_client_loop (ob_net_keepalive.cpp:648) [60659][KeepAliveClient][T0][Y0-0000000000000000-0-0] [lt=13] dump dest keepalive data states, addr: "xxx.xxx.xxx.xxx:xxx", last_write_ts_=1695284265851697, last_read_ts_=1695284201797557, in_black_=1
server 被加入黑名单和被洗白都会打印日志,如下所示。
INFO [RPC.OBRPC] do_client_loop (ob_net_keepalive.cpp:672) [60659][KeepAliveClient][T0][Y0-0000000000000000-0-0] [lt=16] mark black, addr: "xxx.xxx.xxx.xxx:xxx", last_write_ts_=1695284201832280, last_read_ts_=1695284201797557
INFO [RPC.OBRPC] try_read_response (ob_net_keepalive.cpp:609) [60659][KeepAliveClient][T0][Y0-0000000000000000-0-0] [lt=16] whitewash, addr: "xxx.xxx.xxx.xxx:xxx" last_write_ts_=1695284201832280, last_read_ts_=1695284201797557
问题原因
对端的 OBServer 进程退出或挂起。
目标地址错误,IP:PORT 不是一个 OBServer 监听的 RPC 端口。
高系统负载或内存不足导致系统调用超时。
发送端和接收端的机器系统 Load 高,或者因为系统可用内存不足,触发了直接内存回收导致系统调用超时,这两种情况一般会打印耗时长的日志信息,命令如下。
grep -rn "net_keepalive" observer.log |grep "cost too much time"
ob_net_keepalive 探活机制
ob_net_keepalive 探活机制的原理。
OBServer 启动后,会创建
KeepAliveClient和KeepAliveServer两个线程,KeepAliveClient维护一个 server list,发 RPC 的的时候,会将 RPC 的目的端地址加入 list 中,KeepAliveClient每隔 200ms 向 server list 中的所有的地址发送一个探活请求,然后等待回包。KeepAliveServer线程负责监听client发过来的探活请求,每收到一个请求之后,向client返回ObNetKeepAliveData作为回包。struct ObNetKeepAliveData { public: ObNetKeepAliveData() : rs_server_status_(0) {} int encode(char *buf, const int64_t buf_len, int64_t &pos) const; int decode(const char *buf, const int64_t data_len, int64_t &pos); int32_t get_encoded_size() const; int32_t rs_server_status_; int64_t start_service_time_; };ob_net_keepalive 探活机制实现黑名单的逻辑。
如果
KeepAliveClient发送的探活包在一定时间(2.8s 到 3.2s之间)没有收到回包,就会将对应的目的端地址加入黑名单,在这之后客户端会断连接,然后继续尝试建连接、发送探活包、等待回包的操作,如果收到了server 的回包,就会将目的端地址洗白。
适用版本
OceanBase 数据库 V4.x 版本。