关于数据库:高性能数据访问中间件-OBProxy三问题排查和服务运维

22次阅读

共计 9748 个字符,预计需要花费 25 分钟才能阅读完成。

1 引言

上篇文章咱们解说了 OBProxy 的装置部署,在实际时,大家还可能因为机器环境、操作程序不对等问题导致装置部署失败,这时候能够到 OceanBase 的开源社区 问答 板块发问,会有业余的工程师答复你的问题。(也能够退出钉群:33254054 和技术同学面对面交换)实现了 OBProxy 的装置部署后,就能够应用 OBProxy 拜访 OceanBase 数据库了。

刚开始应用 OBProxy,排查问题和运维 OBProxy 是大家将要遇到的拦路虎。因而,本章咱们将具体解说 问题排查伎俩和服务运维办法 ,让大家更轻松的应用 OBProxy,并成为 OBProxy 的专家。

OBProxy 是数据库拜访链路上重要的一环,联合本文内容,大家能够触类旁通,多多思考分布式系统的链路追踪、问题排查等内容,这对了解分布式系统有很大的帮忙。好了,当初咱们开始吧!

2 问题排查

大部分状况下,排查问题是须要团队协同实现的,上面我会介绍一些标准和思路,不便大家交换和解决问题。

2.1 形容问题

遇到问题时,咱们首先须要形容分明问题,最好是可能复现问题,这样能力让研发同学无效的解决问题。比方在 OceanBase 开源社区的问答版里发问时,倡议形容问题能够用如下的模版:

<!-- 为了防止屡次沟通确认,晋升效率,请提供以下信息 -->【应用环境】生产环境 or 测试环境【OB or 其余组件】【应用版本】【问题形容】清晰明确形容问题【复现门路】问题呈现前后相干操作【问题景象及影响】【附件】

这里举荐大家依照要求填写,填写内容的同时,也利于大家将问题梳理的更分明。问题形容倡议至多要包含以下两点:

问题工夫:对于不好复现的问题,工夫信息有利于进行问题梳理,不便对齐问题。
客户端报错:客户端报错蕴含丰盛的信息(SQL、堆栈、执行工夫等),具体的信息对排查问题十分有帮忙;当有论断时,能够前后对照后果,进一步验证论断。

2.2 剖析问题

形容完问题后,对于问题排查人员,就须要剖析问题。在剖析问题前,首先要全局理解数据库拜访链路,次要蕴含以下模块:

从全局再去看部分,思路会更清晰。OBProxy 和各个模块都有交互,大家有空能够多理解和学习下利用、LB 和 ObServer 的常识。当剖析问题时,依照从前往后(从利用端开始)的程序一个个剖析,先确定哪个模块的问题,再确定模块的具体问题。

上面介绍一些低效的问题排查办法,大家尽量避免:

客户说利用应用数据库报错,间接去 OBProxy 的日志目录搜寻 WARNERROR 级别日志,如果日志打印不标准或者 WARN/ERROR 日志太多,这种办法就非常的低效,甚至和客户问题没任何关系。
客户说有数据库连贯断了,我跳过了中间环节,间接从 OceanBase 数据库开始排查,后果未发现问题。

2.3 归类问题

本大节对 OBProxy 常见问题进行归类,不便大家在剖析 OBProxy 模块时有更好的思路。从业务视角去看,OBProxy 的问题次要蕴含以下几类,下图中 ODP 是 OBProxy 的简称。

  • 登录失败:绝大部分都是某个中央配置呈现问题,比拟容易复现和排查。
  • SQL 执行:呈现问题品种很多,有些疑难问题很难排查。
  • 返回谬误:后端服务返回明确的错误码,依据错误码去 OBServer 和 OBProxy 断排查。
  • 慢 SQL:须要确定每个模块的耗时,找到瓶颈点去优化,除了 2.2 中的模块,网络也是一个重要因素。
  • 断连贯:和慢 SQL 相似,须要先排查哪个模块被动断开连接(被动发送 FIN 报文),而后排查具体模块。

2.4 总结

通过后面内容介绍,大家就有了问题排查的方法论,但这只是万里长征第一步,因为文章篇幅无限,没有在持续深刻介绍上来,前面有一些简略例子,不便大家进一步理解。大家还须要一直的实战总结,能力面对问题做到熟能生巧。

3 OBProxy 日志

解决 OBProxy 的问题时,有三大法宝:OBProxy 日志、Linux 命令(网络命令、系统命令和文本命令)和 OceanBase 云平台(OceanBase Cloud Platform,简称 OCP)。其中 Linux 命令和监控平台的知识点非常通用,网络上材料很多,大家能够自学,把握后对大家排查问题帮忙很大。

本节咱们次要介绍和 OBProxy 关系比拟严密的日志局部,OBProxy 的日志有多种类别,咱们将介绍每种日志的作用,帮忙大家排查问题。

3.1 谬误日志

谬误日志的文件名叫做 obproxy_error.log,谬误日志会记录执行谬误的申请,包含 OBProxy 本身谬误和 OBServer 返回谬误。咱们以 select obproxy_error from dual 做测试,其中 obproxy_error 字段没有加引号,会被当作列解决,导致执行失败。客户端报错如下:

MySQL [test]> select obproxy_error from dual;
ERROR 1054 (42S22): Unknown column 'obproxy_error' in 'field list'

关上 obproxy_error.log,内容如下:

2022-07-11 10:26:09.358231,undefined,,,,ob9988.zhixin.lm.xx.xx.xx.xx:sys:test,OB_MYSQL,,,COM_QUERY,SELECT,failed,1054,select obproxy_error from dual,42423us,454us,0us,41222us,Y0-7F4B1EF653A0,,,,0,xx.xx.xx.xx:33041,Unknown column 'obproxy_error' in 'field list'

# 日志通过逗号分隔,如果 SQL 中有逗号,会通过 %2C 代替,通过 tr ',' '\n' 替换后果如下

1,2022-07-11 10:26:09.358231    #日志打印工夫
2,undefined           # sharding 模式下逻辑租户名
3,                    # 无需关注,外部应用
4,                    # 无需关注,外部应用
5,                    # sharding 模式下逻辑库名
6,ob9988.zhixin.lm.xx.xx.xx.xx:sys:test  # 物理库信息(cluster:tenant:database)7,OB_MYSQL         # 数据库类型
8,                 # 逻辑表名
9,                 # 物理表名
10,COM_QUERY       # SQL 命令(COM_QUERY、COM_STMT_PREPARE 等)11,SELECT          # SQL 类型
12,failed          # 执行后果(success/failed)13,1054            # 错误码(succ 时为空)14,select obproxy_error from dual  # SQL 语句
15,42423us         # 执行总耗时(ms,包含外部 SQL 执行耗时
16,454us           # 预执行工夫
17,0us             # 建设连接时间
18,41222us         # 数据库执行工夫
19,Y0-7F4B1EF653A0 # OBProxy 外部日志 trace_id
20,           # 无需关注,外部应用
21,           # 无需关注,外部应用
22,           # 无需关注,外部应用
23,0          # 无需关注,外部应用
24,xx.xx.xx.xx:33041  # 路由到的 ObServer 的地址信息
25,Unknown column 'obproxy_error' in 'field list' # 报错信息 

3.2 审计日志

审计日志的文件名叫做 obproxy_digest.log,审计日志记录执行工夫大于参数 query_digest_time_threshold 阈值(默认 100ms)的申请和谬误响应申请。对于 3.1 中的例子,咱们从 obproxy_digest.log 中也能够看到日志。

2022-07-11 10:26:09.358221,undefined,,,,ob9988.zhixin.lm.xx.xx.xx.xx:sys:test,OB_MYSQL,,,COM_QUERY,SELECT,failed,1054,select obproxy_error from dual,42423us,454us,0us,41222us,Y0-7F4B1EF653A0,,,,0,xx.xx.xx.xx:33041

除了执行谬误 SQL,咱们应用 select sleep(3) from dual 模拟慢 SQL,执行后,查看 obproxy_digest.log,能够看到 OBProxy 执行破费了 409us,ObServer 执行花了 3039883us。内容如下:

2022-07-11 14:32:51.758265,undefined,,,,ob9988.zhixin.lm.xx.xx.xx.xx:sys:test,OB_MYSQL,,,COM_QUERY,SELECT,success,,select sleep(3),3041116us,409us,0us,3039883us,Y0-7F4B1CEA13A0,,,,0,xx.xx.xx.xx:33041

日志剖析

1,2022-07-11 14:32:51.758265    #日志打印工夫
2,undefined          # sharding 模式下逻辑租户名
3,                   # 无需关注,外部应用
4,                   # 无需关注,外部应用
5,                   # sharding 模式下逻辑库名
6,ob9988.zhixin.lm.100.88.147.179:sys:test  # 物理库信息(cluster:tenant:database)7,OB_MYSQL         # 数据库类型
8,                 # 逻辑表名
9,                 # 物理表名
10,COM_QUERY       # SQL 命令(COM_QUERY、COM_STMT_PREPARE 等)11,SELECT          # SQL 类型
12,success         # 执行后果(success/failed)13,                # 错误码(succ 时为空)14,select sleep(3) # SQL 语句
15,3041116us       # 执行总耗时(ms,包含外部 SQL 执行耗时
16,409us           # 预执行工夫
17,0us             # 建设连接时间
18,3039883us       # 数据库执行工夫
19,Y0-7F4B1CEA13A0 # OBProxy 外部日志 trace_id
20,                # 无需关注,外部应用
21,                # 无需关注,外部应用
22,                # 无需关注,外部应用
23,0               # 无需关注,外部应用
24,xx.xx.xx.xx:33041  # 路由到的 ObServer 的地址信息 

3.3 慢日志

慢日志的文件名叫做 obproxy_slow.log,慢日志记录执行工夫大于 slow_query_time_threshold 阈值(默认 500ms)的申请。如上节 SQL select sleep(3) from dual 在 obproxy_slow.log 中也有记录,内容如下:

2022-07-11 14:32:51.758270,undefined,,,,ob9988.zhixin.lm.xx.xx.xx.xx:sys:test,OB_MYSQL,,,COM_QUERY,SELECT,success,,select sleep(3),3041116us,409us,0us,3039883us,Y0-7F4B1CEA13A0,,,,0,xx.xx.xx.xx:33041

慢日志的日志格局和审计日志的格局雷同,此处不在介绍。

对于慢 SQL,在 obproxy.log 也会有记录,关键字是 Slow Query,obproxy.log 中记录的信息更加具体,如下面的 SQL,搜寻 obproxy.log 失去:

[2022-07-11 14:32:51.758195] WARN  [PROXY.SM] update_cmd_stats (ob_mysql_sm.cpp:8425) [74744][Y0-7F4B1CEA13A0] [lt=7] [dc=0] Slow Query: ((client_ip={127.0.0.1:50422},   // 发送 SQL 的客户端地址
server_ip={xx.xx.xx.xx:33041}, // SQL 被路由到的指标 BOServer
obproxy_client_port={xx.xx.xx.xx:52052},  // 和 OBServer 连贯的本地地址
server_trace_id=Y81100B7C0535-0005E3460FBBE3CD-0-0, // 指标 OBServer 中执行过程中的 trace id
route_type=ROUTE_TYPE_NONPARTITION_UNMERGE_LOCAL, // SQL 应用的路由策略
user_name=root,         // 用户名
tenant_name=sys,        // 租户名
cluster_name=ob9988.zhixin.lm.100.88.147.179,  // 集群名
logic_database_name=,  // 逻辑库名
logic_tenant_name=,    // 逻辑租户名
ob_proxy_protocol=0,   // 协定类型
cs_id=14,         // client login 时看到的 connection id, proxy 调配
proxy_sessid=7230691598940700681, // client 拜访 ob 时外部记录 connection id
ss_id=21, 
server_sessid=3221588238,  // SQL 在指标 observer 中的 connection id, observer 调配
sm_id=14, 
cmd_size_stats={
    client_request_bytes:20,  // client 发给 proxy 的申请包大小
    server_request_bytes:38,  // OBProxy 发给指标 observer 的申请包大小
    server_response_bytes:0,  // 指标 observer 发给 proxy 的响应包大小
    client_response_bytes:71}, // OBProxy 发给 client 的响应包大小
cmd_time_stats={
    client_transaction_idle_time_us=0, // 在事务中该条 SQL 与上一条 SQL 执行完结之间的间隔时间, 即 client 事务间隔时间
    client_request_read_time_us=97, // OBProxy 从 client socket 读取申请包的耗时
    client_request_analyze_time_us=95, // OBProxy 剖析 client 的 SQL 耗时
    cluster_resource_create_time_us=0, // OBProxy 创立集群资源耗时 (仅首次拜访集群时须要创立)
    pl_lookup_time_us=0, // 依据 SQL 获取波及路由表的耗时
    pl_process_time_us=0,  // 对波及路由表的进行筛选排序的耗时
    congestion_control_time_us=21,  // 依据 SQL 获取波及黑名单信息的耗时
    congestion_process_time_us=3,  // 对波及黑名单的进行查看过滤的耗时
    do_observer_open_time_us=55,  // 对指标 observer 获取可用连贯的耗时, 蕴含 connect_time
        server_connect_time_us=0,  // 对指标 observer 创立连贯的耗时
    server_sync_session_variable_time_us=0,  // 对抉择的指标连贯进行初始化的耗时, 包含 saved_login, 同步 db, 同步零碎变量, 同步 last_insert_id, 同步 start_trans
        server_send_saved_login_time_us=0,  // 对抉择的指标连贯进行 saved login 耗时
        server_send_use_database_time_us=0,  // 对抉择的指标连贯同步 db 耗时
        server_send_session_variable_time_us=0,  // 对抉择的指标连贯同步已批改的零碎变量耗时
        server_send_all_session_variable_time_us=0,  // 对抉择的指标连贯同步所有零碎耗时
        server_send_last_insert_id_time_us=0, // 对抉择的指标连贯同步 last_insert_id 耗时
        server_send_start_trans_time_us=0,   // 对抉择的指标连贯同步 start_trans/begin 耗时
    build_server_request_time_us=23,  // 构建对指标 server 的申请包的耗时
    plugin_compress_request_time_us=0,   // 对申请包进行压缩耗时
    prepare_send_request_to_server_time_us=409,  // OBProxy 承受到客户端申请,到转发到 observer 执行前总计工夫,失常应该是后面所有工夫之和
    server_request_write_time_us=32,  // OBProxy 向指标 server socket 发送申请包的耗时
    server_process_request_time_us=3039883,   // 指标 server 该执行 SQL 的耗时
    server_response_read_time_us=67,   // OBProxy 从指标 server socket 读取响应包的耗时
    plugin_decompress_response_time_us=59, // 对响应包进行解压缩耗时
    server_response_analyze_time_us=70,  // 对响应包进行剖析的耗时
    ok_packet_trim_time_us=0, // 对响应包 trim 掉最初一个 ok 包的耗时
    client_response_write_time_us=185,  // OBProxy 向 client socket 发送响应包的耗时
    request_total_time_us=3041116},  // OBProxy 解决该申请总工夫, 等于后面所有耗时之和
sql=select sleep(3)   //client 的申请 SQL
)

下面内容十分的具体,不便定位慢 SQL 问题。对于每个局部的含意,大家能够参考第一篇《OceanBase 改写系列一:OceanBase 查问改写实际概述》中讲的 SQL 执行流程(确认下文章和链接是否正确)去对应。

3.4 统计日志

统计日志的文件名叫做 obproxy_stat.log。统计日志默认每分钟(monitor_stat_dump_interval 参数管制)输入一次。通过该日志能够查看 OBProxy 一分钟内 SQL 的执行状况,举个例子,查看 OBProxy 是否有申请流量,看该日志记录即可。参考例子如下:

2022-07-11 10:26:59.499204,undefined,,ob9988.zhixin.lm.xx.xx.xx.xx:sys:test,OB_MYSQL,SELECT,success,,1,1,0,0,41480us,332us,40369us

日志剖析

1,2022-07-11 10:26:59.499204   #日志打印工夫
2,undefined      # sharding 模式下逻辑租户名
3,               # sharding 模式下逻辑库名
4,ob9988.zhixin.lm.xx.xx.xx.xx:sys:test  # 物理库信息(cluster:tenant:database)5,OB_MYSQL  # 数据库类型
6,SELECT    # SQL 类型
7,success   # 执行后果(success/failed)8,          # 错误码(succ 时为空)9,1         # 总申请数量
1           # 30 ms ~ 100 ms 申请数量
0           # 100 ms ~ 500 ms 申请数量
0           # 大于 500 ms 申请数量
41480us     # 执行总耗时(ms,包含外部 SQL 执行耗时)332us       # 预执行工夫
40369u      # 数据库执行工夫 

3.5 主日志

主日志的文件名叫做 obproxy.log,有 DEBUG、TRACE、INFO、ERROR 四种级别,通过 syslog_level 参数管制,当须要进一步排查问题起因时,通过 trace_id 字段能够过滤失去一个 session 上的所有日志,查看 obproxy.log 要求对 OBProxy 的代码实现十分相熟,有肯定技术难度。感兴趣同学能够查看 OBProxy 源代码。

3.6 总结

OBProxy 的日志在排查问题时十分的有用,把握下面内容能够应答大部分的 OBProxy 问题。本节对日志格局做了介绍,并联合例子进一步阐明,置信大家能够疾速把握。

4 服务运维

OBProxy 有一个管理员账号 root@proxysys,为了平安,咱们对该账号的登录地址做了限度,要求大家本机登录进行运维操作。上面咱们将从配置管理和外部命令两方面做具体介绍。

4.1 配置管理

OBProxy 的配置参数参考文档参数阐明。应用 root@proxysys 登录,就能够查看和批改配置项:

# 查看日志级别

MySQL [(none)]> show proxyconfig like '%syslog_level%';
+--------------+-------+-----------------------------------------------------------------------------------+-------------+---------------+
| name         | value | info                                                                              | need_reboot | visible_level |
+--------------+-------+-----------------------------------------------------------------------------------+-------------+---------------+
| syslog_level | DEBUG | specifies the current level of logging: DEBUG, TRACE, INFO, WARN, USER_ERR, ERROR | false       | USER          |
+--------------+-------+-----------------------------------------------------------------------------------+-------------+---------------+

# 批改日志级别为 INFO

MySQL [(none)]> alter proxyconfig set syslog_level = INFO;
Query OK, 0 rows affected (0.01 sec)

对于 show proxyconfig 的输出,各字段含意如下:

  • name:配置名,所有配置项名字能够从参数阐明文档获取。
  • value:配置内容,次要是整型和字符串格局。当内容不非法时会报错。
  • info:形容配置参数的具体信息。
  • need_reboot:示意参数是否重启失效。这里须要留神有些参数尽管不须要重启,但有时只对新的连贯失效。

4.2 外部命令

外部命令只在 OBProxy 上执行,不会转发给 OBServer,次要用于获取 OBProxy 的外部状态或者批改外部行为。这部分内容和原理关系严密,本节只做简要介绍,后续大家对 OBProxy 有更深刻理解后能够再学习。

5 总结

本章内容是对 OBProxy 的问题排查总结,这些办法凝聚了 OBProxy 技术专家多年的心血,通过了大量的实战测验。不仅能够用来学习,也能够作为手册,当遇到 OBProxy 问题时翻阅查看相干内容阐明,心愿能帮忙到大家!

6 课后互动

6.1 上期互动

obproxyd.sh 脚本对 OBProxy 过程做了探活,请问探活办法是什么?除了脚本中的办法,还有哪些探活办法?这些办法有什么优缺点,请举例说明。

obproxyd.sh 通过查看 /proc/$pid 文件是否存进行探活。还能够通过检测端口是否在监听确认是否存活。这两种办法做到过程级别探测,但某些场景下,如果过程异样不能执行业务逻辑就无奈探测到,更进一步能够发送利用心跳报文进行检测。

6.2 本期互动

小明想查看所有通过 OBProxy 的 SQL,请问有什么方法?

正文完
 0