Skip to content

Commit 8b514ce

Browse files
authored
Merge pull request #191 from oceanbase/xiaofeng_branch
在进阶教程中添加《故障应急手册》章节
2 parents 883786e + d237e1b commit 8b514ce

File tree

14 files changed

+283
-0
lines changed

14 files changed

+283
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
title: 故障应急手册概述
3+
weight: 1
4+
---
5+
6+
咱们《OceanBase DBA 进阶教程》的内容已经持续更新了一段时间,终于来到了 “问题排查” 阶段。
7+
8+
前一段儿时间看到了 OceanBase 内部同学整理的一篇社区博客[《OceanBase 应急三板斧》](https://open.oceanbase.com/blog/13250502949),以及文档团队的小伙伴们在官方文档中为大家提供的一些[和应急处理相关的内容](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001573632),内容都非常不错。
9+
10+
不过对于 OceanBase 社区版的用户来说,这些应急场景和应对手段,可能还不是十分完善,同时也不够体系化和图谱化。
11+
12+
同时考虑到用户意见收集中的 @oceanvoice 、@张雨齐 等老师的建议,准备《进阶教程》的这个章节中,为大家提供一份儿相对比较成体系,也更加全面的《故障应急手册》。
13+
14+
在《故障应急手册》中,会把用户在使用 OceanBase 的过程中可能遇到的问题,以及对应的解决方案进行汇总,目录大致会是:
15+
16+
* 1 系统响应时间不符合预期
17+
18+
* 2 SQL 执行报错
19+
20+
* 3 CPU 负载异常
21+
22+
* 4 节点宕机
23+
24+
* 5 生产库故障切容灾库
25+
26+
* 6 硬件 & 基础环境故障应急处理
27+
28+
* 7 负载变化导致的问题
29+
30+
* 8 集群内部其他问题
31+
32+
* 8.1 租户转储阻塞
33+
34+
* 8.2 集群合并阻塞
35+
36+
* 8.3 SYS 租户/ RS 服务问题
37+
38+
* 8.4 磁盘泄漏
39+
40+
* 8.5 内存泄漏
41+
42+
* 8.6 长事务
43+
44+
* 8.7 悬挂事务
45+
46+
* 8.8 coredump
47+
48+
* 8.9 无主
49+
50+
* 未完待续……
51+
52+
53+
手册的更新频率大概是一周一次,因为这个章节的内容较多,所以预计会分成三到四次完成手册内容的更新。希望大家能够持续关注。
54+
55+
56+
## What's more ?
57+
58+
这一小节只有手册的内容介绍,没啥干货,有点儿过意不去。那就在最后附送一个 **<font color="red">针对 OceanBase 严重故障(尤其是业务停服场景),进行快速止血恢复的通用方法</font>** ,简单来说就是:切主 -> 隔离 -> 重启 -> 切备集群。
59+
60+
- 如果集群中只有一个租户有问题,那就切这个租户的主(通过 set tenant primary_zone 修改租户的 primary_zone)。
61+
62+
- 如果集群中只有一个节点有问题,那就 stop or isolate 这个节点。
63+
64+
- 如果整个集群都有问题,那就轮流重启集群中的各个节点。
65+
66+
- 如果轮流重启之后还有问题,那就进行 failover 操作,切换备集群。
67+
68+
- 分析问题永远放在止血和恢复之后。
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
---
2+
title: 系统响应时间不符合预期
3+
weight: 2
4+
---
5+
6+
## 业务及数据库表现
7+
8+
业务表现:业务响应由快变慢,或者直接超时报错。
9+
10+
数据库表现:SQL 执行时间变长,响应曲线陡升,SQL 响应延迟 (RT) 明显变高。
11+
12+
## 排查方向和流程
13+
14+
![image](/img/user_manual/operation_and_maintenance/emergency_handbook/02_slow_response/001.png)
15+
16+
17+
### 排查硬件问题
18+
19+
首先需要排除一下是否由网络、磁盘 IO 等硬件问题导致的 SQL 响应延迟,这里不多啰嗦。
20+
21+
<br></br>
22+
23+
### 排查大查询(slow query)问题
24+
25+
直接通过 OCP 排查是否存在 “可疑 SQL”。
26+
![image](/img/user_manual/operation_and_maintenance/emergency_handbook/02_slow_response/002.png)
27+
28+
如果存在某个大查询(或者叫大请求)占用了过多资源,导致大量短请求无法及时得到响应,可以考虑以下方法:
29+
30+
- 通过 OCP 对占用过多资源的大请求进行限流。
31+
32+
33+
- 通过 [large_query_worker_percentage](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001576444)(默认 30%) 来设置大查询可以使用的系统资源占比。
34+
35+
- 通过 [large_query_threshold](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001576249) (默认 5s)来设置大查询的判定阈值。这个时间阈值修改之后对系统影响可能会比较大,在不了解参数含义时,不建议用户随意修改。
36+
37+
- 通过 OCP 添加主机,并对租户[进行扩容](https://www.oceanbase.com/docs/common-ocp-1000000001405989)(Zone 内增加节点)。
38+
39+
<br></br>
40+
41+
### 排查租户队列积压问题
42+
43+
#### 排查方法
44+
45+
资源问题这里除了某几个大查询占用了过多资源,还有一种租户队列积压的情况。排查方式有以下几种:
46+
47+
- 可以通过 OCP 观察单条 slow query 的平均 queue_time(排队时间)在 elapsed_time(响应时间) 中的占比是否符合预期,如果 queue_time 超长,则可能是租户队列积压。
48+
![image](/img/user_manual/operation_and_maintenance/emergency_handbook/02_slow_response/003.png)
49+
![image](/img/user_manual/operation_and_maintenance/emergency_handbook/02_slow_response/004.png)
50+
51+
- 或者可以通过 GV$OB_SQL_AUDIT 视图查询 slow query 各种维度的信息,详见:《DBA 入门教程》中的 [“分析 SQL 监控视图”](https://www.oceanbase.com/docs/community-tutorials-cn-1000000001390074) 小节。一些重要的事件间隔如下:
52+
![image](/img/user_manual/operation_and_maintenance/emergency_handbook/02_slow_response/005.png)
53+
```
54+
-- 这个例子中查询的是:tenant id 为 1002 的租户,在 2024-11-20 12:00:00 之后
55+
-- query 执行时间超过 100 ms 的其中一条 SQL
56+
57+
select
58+
tenant_id,
59+
request_id,
60+
usec_to_time(request_time),
61+
elapsed_time,
62+
queue_time,
63+
execute_time,
64+
query_sql
65+
from
66+
oceanbase.GV$OB_SQL_AUDIT
67+
where
68+
tenant_id = 1002
69+
and elapsed_time > 100000
70+
and request_time > time_to_usec('2024-11-20 12:00:00')
71+
order by
72+
elapsed_time desc
73+
limit 1 \G
74+
75+
*************************** 1. row ***************************
76+
tenant_id: 1002
77+
request_id: 13329994
78+
usec_to_time(request_time): 2024-11-20 15:14:58.765564
79+
elapsed_time: 153118
80+
queue_time: 34
81+
execute_time: 139873
82+
query_sql: select * from xxxx where xxxx;
83+
1 row in set (0.11 sec)
84+
```
85+
86+
- **<font color="red">如果需要观察特定租户的队列积压情况,可以通过日志中的 'dump tenant info' 来实现,这个是最通用的方法</font>**
87+
```
88+
grep 'dump tenant info' observer.log*
89+
```
90+
![image](/img/user_manual/operation_and_maintenance/emergency_handbook/02_slow_response/006.png)
91+
92+
日志中,有几个关键字可参考:
93+
94+
1. **<font color="red">req_queue</font>**,表示普通请求队列
95+
96+
- total_size=n,n 表示优先级队列中总共的排队请求数。
97+
98+
- queue[x]=y,y 表示每个优先级子队列中的排队请求数(x 越小队列优先级越高)。
99+
100+
2. **<font color="red">multi_level_queue</font>**,表示嵌套请求队列
101+
102+
- total_size=n,n 表示优先级队列中总共的排队请求数。
103+
104+
- queue[x]=y,y 表示每个层级子队列中的排队请求数。
105+
106+
- queue0: 存放无嵌套的请求,由于无嵌套请求有优先级队列来存放,因此常为空。
107+
108+
- queue1: 存放1层嵌套的请求(如 sql 触发的 rpc)
109+
110+
- queue2: 存放2层嵌套的请求(如 sql 触发的 rpc 再次触发的 rpc)
111+
112+
- ……
113+
114+
3. **<font color="red">group_id = x, queue_size = y</font>** 中的 y 表示分组队列排队请求数。
115+
- group 是用来处理特定种类 rpc 请求的,关于每个 group id 对应哪种 rpc 请求。可以参考开源代码 [ob_group_list.h](https://github.com/oceanbase/oceanbase/blob/develop/src/share/resource_manager/ob_group_list.h)。
116+
117+
在日志中搜索 dump tenant info,好处是可以看到历史,可以同时看到队列和线程的大致情况,缺点是日志会周期性打印,实时性不强。
118+
119+
- 或者通过登录 sys 租户,执行以下 SQL 观察租户队列积压情况:
120+
```
121+
obclient [oceanbase]> select * from oceanbase.__all_virtual_dump_tenant_info where tenant_id = 1002\G
122+
*************************** 1. row ***************************
123+
svr_ip: 11.158.31.20
124+
svr_port: 22602
125+
tenant_id: 1002
126+
compat_mode: 0
127+
unit_min_cpu: 2
128+
unit_max_cpu: 2
129+
slice: 0
130+
remain_slice: 0
131+
token_cnt: 10
132+
ass_token_cnt: 10
133+
lq_tokens: 0
134+
used_lq_tokens: 0
135+
stopped: 0
136+
idle_us: 0
137+
recv_hp_rpc_cnt: 99
138+
recv_np_rpc_cnt: 2226
139+
recv_lp_rpc_cnt: 0
140+
recv_mysql_cnt: 5459
141+
recv_task_cnt: 5
142+
recv_large_req_cnt: 0
143+
recv_large_queries: 3661
144+
actives: 10
145+
workers: 10
146+
lq_waiting_workers: 0
147+
req_queue_total_size: 0
148+
queue_0: 0
149+
queue_1: 0
150+
queue_2: 0
151+
queue_3: 0
152+
queue_4: 0
153+
queue_5: 0
154+
large_queued: 0
155+
1 row in set (0.001 sec)
156+
```
157+
这张虚拟表,可以实时地查看队列信息,好处是实时性强,缺点是不记录历史信息。
158+
159+
#### 解决方法
160+
161+
这里先多说几句,OceanBase 的线程模型,是一个典型的生产者消费者模型,当请求的生产速度长期大于消费速度时,租户的工作队列就会被打爆,并返回错误码 -4019。
162+
163+
即使没有打满,也会表现出请求排队耗时长的情况,如租户中存在大量自增列的场景(详见:《DBA 入门教程》中的 “扩展功能” 的 [“序列” 部分](https://www.oceanbase.com/docs/community-tutorials-cn-1000000001390115))。
164+
165+
解决方法如下:
166+
167+
- **<font color="red">如果租户队列已经爆了,只能通过重启恢复(停压力也不行)。</font>** 建议去[社区论坛](https://ask.oceanbase.com/)发帖,联系在论坛中值班的技术支持同学,让他们协助你留下 obstack 或者 pstack 的堆栈信息,否则很难诊断具体原因。
168+
169+
- **<font color="red">一般租户队列爆的问题较少,更常见的是租户队列积压。</font>**
170+
- 如果出现租户队列积压,请优先检查是否有 order 属性的自增列。
171+
172+
- 如果不是有大量自增列集中写入数据,需要联系社区论坛的值班同学通过 obstack 或者 pstack 分析堆栈信息。
173+
174+
- 分析的结论如果不是死锁引起的队列积压,可以通过调大特定租户的规格来缓解特殊场景下的队列积压。这里的 “特殊场景” 指有大量写入导致线程等锁开销,或者操作极耗 cpu(可以通过 top 或者tsar 来验证)。
175+
176+
<br></br>
177+
178+
### 排查计划问题
179+
180+
如果资源问题这个分支的嫌疑被排除了,大概率就是计划问题了。
181+
182+
![image](/img/user_manual/operation_and_maintenance/emergency_handbook/02_slow_response/007.png)
183+
184+
如果 SQL 执行效率是 “由快变慢”,那么可以重点怀疑以下几个常见问题:
185+
186+
- 第一个是计划缓存(plan cahce)的 bad case,也被人称为 “大小账号问题”。问题描述、排查思路、解决方法都详见:《DBA 入门教程》中的 “常见的 SQL 调优方式” 的 [“计划缓存的 bad case” 部分](https://www.oceanbase.com/docs/community-tutorials-cn-1000000001390071),这里不再赘述。简而言之,“大小账号问题” 分两种:
187+
- 一种就是《入门教程》中说的,SQL 中只有常量不同时,会共享 plan cache 中的同一个计划,这种场景可能会有问题;
188+
> 再多说一句,算是偷偷做个预告:OceanBase 后续的版本会在某些合适的场景中支持为 SQL 中的不同常量,缓存不同的计划,以消除现在这个烦人的问题。
189+
- 另一种是 SQL 涉及的表对象的统计信息发生了较大变化,但依然使用的是统计信息发生变化前 plan cache 中缓存的计划。
190+
> 这个问题也会在后续版本的 plan cache 中得到缓解。
191+
192+
193+
- 第二个是 [Buffer 表问题](https://www.oceanbase.com/docs/community-tutorials-cn-1000000001390072)。也详见蓝色链接,不再赘述。
194+
> 这里也只多说一句,《DBA 入门教程》中只给了大家一个解决问题的思路,就是想办法提高特定表的合并频率。除了手动合并,OceanBase 数据库从 V4.2.0 版本开始支持[自适应合并](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001574524),通过修改 table_mode 为 queue 模式,来缓解该问题。
195+
196+
- 第三个是在版本升级后,在低版本中好的计划,在高版本中回退成了差的计划。
197+
- 一般来说,升级之后,绝大多数的计划都会变成更优的计划,这种回退只是极其个别的情况。这种情况在《入门教程》中没有为大家介绍,可以直接通过 OCP 观察对应 SQL 的历史趋势及计划变化来判断。
198+
![image](/img/user_manual/operation_and_maintenance/emergency_handbook/02_slow_response/008.png)
199+
- 解决方法详见[《入门教程》中的 “通过 Hint 生成指定计划” 以及 “通过 Outline 进行计划绑定”](https://www.oceanbase.com/docs/community-tutorials-cn-1000000001390068)。
200+
201+
202+
- 第四个是硬解析问题,也可以直接通过 OCP 观察对应 SQL 计划生产时间的历史趋势来判断。解决方法详见[《入门教程》中的 “硬解析问题”](https://www.oceanbase.com/docs/community-tutorials-cn-1000000001390072)。
203+
![image](/img/user_manual/operation_and_maintenance/emergency_handbook/02_slow_response/009.png)
204+
205+
206+
如果 SQL 执行效率不是由快变慢,而是 “一如既往的慢”,那就去看这本《DBA 进阶教程》中的 [“SQL 性能诊断和调优” 小节](https://oceanbase.github.io/docs/user_manual/operation_and_maintenance/scenario_best_practices/chapter_03_htap/performance_tuning)吧,哈哈~
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
label: 故障应急手册
390 KB
Loading

sidebars.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,14 @@ const sidebars: SidebarsConfig = {
167167
dirName: 'user_manual/operation_and_maintenance/development_specification'
168168
}]
169169
},
170+
{
171+
type: 'category',
172+
label: '故障应急手册',
173+
items: [{
174+
type: 'autogenerated',
175+
dirName: 'user_manual/operation_and_maintenance/emergency_handbook'
176+
}]
177+
},
170178
],
171179
tutorialSidebar: [{ type: 'autogenerated', dirName: 'user_manual/user_best_practices/tutorial' }],
172180
blogsSidebar: [{ type: 'autogenerated', dirName: 'blogs' }],
147 KB
Loading
369 KB
Loading
565 KB
Loading
241 KB
Loading
171 KB
Loading

0 commit comments

Comments
 (0)