diff --git a/docs/user_manual/operation_and_maintenance/zh-CN/about_this_manual/01_overview.md b/docs/user_manual/operation_and_maintenance/zh-CN/about_this_manual/01_overview.md index 2ec28398c..eba643f3d 100644 --- a/docs/user_manual/operation_and_maintenance/zh-CN/about_this_manual/01_overview.md +++ b/docs/user_manual/operation_and_maintenance/zh-CN/about_this_manual/01_overview.md @@ -15,8 +15,6 @@ weight: 1 ## 整体内容概览 手册的内容大纲详见下图: -(实际编写和整理的过程中,会持续根据用户建议和实际情况进行调整,非最终版本) - ![image.png](/img/user_manual/operation_and_maintenance/zh-CN/about_this_manual/001.png) 《OceanBase 4.x DBA 进阶教程》 diff --git a/docs/user_manual/operation_and_maintenance/zh-CN/development_specification/02_charset_specification.md b/docs/user_manual/operation_and_maintenance/zh-CN/development_specification/02_charset_specification.md index fb20f5782..4cc869208 100644 --- a/docs/user_manual/operation_and_maintenance/zh-CN/development_specification/02_charset_specification.md +++ b/docs/user_manual/operation_and_maintenance/zh-CN/development_specification/02_charset_specification.md @@ -167,7 +167,9 @@ Client 将 SQL 字符串的发给 Server 执行,Server 将执行结果返回 * 使用 jdbc 连接 OceanBase 数据库,GBK 链路一般在 url 里修改参数设置,添加 `characterEncoding=gbk`。 ```shell - String url = "jdbc:oceanbase://xxx.xxx.xxx.xxx:xxxx?useSSL=false&useUnicode=true&characterEncoding=gbk&connectTimeout=30000&rewriteBatchedStatements=true"; + String url = "jdbc:oceanbase://host:port?useSSL=false" + + "&useUnicode=true&characterEncoding=gbk" + + "&connectTimeout=30000&rewriteBatchedStatements=true"; ``` * 使用 OBClient 客户端连接数据库,GBK 链路 bash 环境变量推荐使用 `zh_CN.GBK` 的超集 `zh_CN.GB18030`。 diff --git a/docs/user_manual/operation_and_maintenance/zh-CN/operations_and_maintenance/optimizer_statistics/01_operations_and_maintenance.md b/docs/user_manual/operation_and_maintenance/zh-CN/operations_and_maintenance/optimizer_statistics/01_operations_and_maintenance.md index 3d721dea3..68c7ac74e 100644 --- a/docs/user_manual/operation_and_maintenance/zh-CN/operations_and_maintenance/optimizer_statistics/01_operations_and_maintenance.md +++ b/docs/user_manual/operation_and_maintenance/zh-CN/operations_and_maintenance/optimizer_statistics/01_operations_and_maintenance.md @@ -14,7 +14,7 @@ weight: 1 -## 自动统计信息收集问题排查 {#自动统计信息收集问题排查} +## 自动统计信息收集问题排查 ### 自动统计信息收集工作原理 目前自动统计信息收集任务是基于 DBMS_SCHEDULER 系统包实现,以周为单位,定义了如下 7 个窗口的定时执行任务: @@ -31,10 +31,10 @@ weight: 1 自动收集收集的是统计信息缺失或者统计信息过期的表,按照增量收集的方式进行收集。也就是只收集数据变化的分区,而不用重新收集整个表的统计信息。过期标准是看针对每个分区来说增量的 DML info 变化是否满足过期的阈值(默认:10%,即单个分区距离上一次收集期间增删改的总量不超过当前表数据量的 10%)。 -### 自动统计信息收集是否正常排查 {#自动统计信息收集是否正常排查} +### 自动统计信息收集是否正常排查 请按照如下步骤进行排查: -+ **步骤一:按照租户类别使用如下 SQL 查询进行检查,主要检查最近一天内的所有租户自动收集是否有正常调度。如果调度正常,跳转步骤二,否则请先参考本文中的 “[自动统计收集任务调度问题排查](#自动统计收集任务调度问题排查)” 部分。** ++ **步骤一:按照租户类别使用如下 SQL 查询进行检查,主要检查最近一天内的所有租户自动收集是否有正常调度。如果调度正常,跳转步骤二,否则请先参考本文中的 “自动统计收集任务调度问题排查” 部分。** ```sql @@ -125,13 +125,13 @@ FROM (SELECT task_id, + **步骤三,针对上述收集失败的表,按照如下场景选择应对方式:** -1. **(最常见场景) ** 收集失败的表是一个数据量大表(行数超过上亿),长时间没收集成功,出现收集超时报错 ret=-4012,请按照如下方式进行解决:[“自动收集卡在超大表运维手段”](#自动收集卡在超大表运维手段)。 +1. **(最常见场景) ** 收集失败的表是一个数据量大表(行数超过上亿),长时间没收集成功,出现收集超时报错 ret=-4012,请按照本文中的 “自动收集卡在超大表运维手段” 部分进行处理。 2. 租户中的表太多,大部分表都需要重新收集统计信息,但是收集窗口时间有限,导致未收集完成。该场景下需要考虑重新对该租户在 **业务低峰期** 的时候手动收集一次,收集策略可参考:[《手动统计信息收集命令使用手册》](https://oceanbase.github.io/docs/user_manual/operation_and_maintenance/zh-CN/operations_and_maintenance/optimizer_statistics/command)。 3. 非超时报错,其他错误码,请先在 **业务低峰期 ** 对该表重新手动收集一次统计信息(详见:《手动统计信息收集命令使用手册》)。后续继续观察,同时将该报错问题反馈给 OceanBase 社区论坛的官方值班同学。 -## 自动统计收集任务调度问题排查 {#自动统计收集任务调度问题排查} +## 自动统计收集任务调度问题排查 可以根据当前的租户情况,使用如下查询检查自动收集任务是否调度正常: + **sys 租户(需要指定目标租户的 tenant_id)**: @@ -188,8 +188,8 @@ ORDER BY time; 如果上述查询结果调度异常,可以将该报错问题反馈给 OceanBase 社区论坛的官方值班同学。 -## 自动收集卡在超大表运维手段 {#自动收集卡在超大表运维手段} -当前业务场景中有比较多的租户,因为有一个大表收集缓慢,导致自动收集任务失败,是否是这个原因导致可通过 [“自动统计信息收集问题排查”](#自动统计信息收集问题排查) 来确认,当确认是某个大表所导致的问题,可以使用如下策略进行运维: +## 自动收集卡在超大表运维手段 +当前业务场景中有比较多的租户,因为有一个大表收集缓慢,导致自动收集任务失败,是否是这个原因导致可参考本文中的 “自动统计信息收集问题排查” 部分来进行确认,当确认是某个大表所导致的问题,可以使用如下策略进行运维: + **步骤一:使用如下 SQL 检查当前大表过去一段时间的收集情况,观察是否都是一个收集耗时长的过程,如果查询 sys 租户的 ret_code 字段非 0 表示收集失败,查询业务租户视图的 status 字段非 'SUCCESS' 或者 NULL 表示收集失败** @@ -209,7 +209,7 @@ WHERE table_name = '{table_name}' ORDER BY start_time; ``` -+ **步骤二:可以考虑大表的收集策略,参考这个标准:**[“大表统计信息收集策略调整“](#大表统计信息收集策略调整) ++ **步骤二:可以考虑大表的收集策略,参考本文中的 “大表统计信息收集策略调整“ 部分作为标准** + **步骤三:调整完收集策略之后,需要明确是否有必要重新手动收集一次该表的统计信息。如果该表统计信息过期很严重,相关查询的计划生成都有问题,则可以考虑看系统资源是否充足,加大并行收集统计信息;其他情况如果想确认下步骤二设置的策略能否有效,推算自动统计信息收集能发成功,则可以使用如下查询** @@ -219,7 +219,7 @@ ORDER BY start_time; call dbms_stats.gather_table_stats('database_name','table_name', no_invalidate=>true); ``` -+ **步骤四:如果当前租户已经长时间出现大表收集卡住的问题,可以通过 [“快速获取当前租户中统计信息过期或者统计信息缺失的表”](#快速获取当前租户中统计信息过期或者统计信息缺失的表) 中的方式查询当前租户中是否已经存在大量表统计信息缺失或者过期的问题,如果存在则需要在业务低峰期手动重新收集相关表的统计信息(参考《手动统计信息收集命令使用手册》 )。** ++ **步骤四:如果当前租户已经长时间出现大表收集卡住的问题,可以通过本文中的 “快速获取当前租户中统计信息过期或者统计信息缺失的表” 部分的方式查询当前租户中是否已经存在大量表统计信息缺失或者过期的问题,如果存在则需要在业务低峰期手动重新收集相关表的统计信息(参考《手动统计信息收集命令使用手册》 )。** + **步骤五:以上步骤完成之后,最后一步可以考虑调整自动统计信息收集发起任务的时间,尽量错开业务的高峰期,放到每日合并之后进行。** @@ -250,7 +250,7 @@ call dbms_scheduler.enable('SATURDAY_WINDOW'); call dbms_scheduler.enable('SUNDAY_WINDOW'); ``` -### 快速获取当前租户中统计信息过期或者统计信息缺失的表 {#快速获取当前租户中统计信息过期或者统计信息缺失的表} +### 快速获取当前租户中统计信息过期或者统计信息缺失的表 通过如下查询,可以在业务租户中查询统计信息缺失或者过期的表,并且按照数据量排序: ```sql @@ -271,7 +271,7 @@ GROUP BY v2.database_name, ORDER BY row_cnt; ``` -### 大表统计信息收集策略调整 {#大表统计信息收集策略调整} +### 大表统计信息收集策略调整 针对大表的统计信息收集,其收集耗时主要在三个地方: 1. **表数据量大,收集需要全表扫,耗时高;** @@ -282,7 +282,7 @@ ORDER BY row_cnt; 因此根据上述耗时点,可以根据表的实际情况及相关查询情况进行优化,给出如下建议: -+ 设置合适的默认收集并行度,需要注意的是设置并行度之后,需要调整相关的自动收集任务在业务低峰期进行([“调整自动统计信息收集的调度时间”](#调整自动统计信息收集的调度时间)),避免影响业务,**建议并行度控制 8 个以内。** 可使用如下方式设置: ++ 设置合适的默认收集并行度,需要注意的是设置并行度之后,需要调整相关的自动收集任务在业务低峰期进行(参考本文的 “调整自动统计信息收集的调度时间” 部分),避免影响业务,**建议并行度控制 8 个以内。** 可使用如下方式设置: ```sql -- MySQL 租户: @@ -342,9 +342,9 @@ call dbms_stats.delete_table_prefs('database_name', 'table_name', 'granularity') select dbms_stats.get_prefs('degree', 'database_name','table_name') from dual; ``` -除了上述方式以外,也可以考虑能否手动收集完大表统计信息之后,锁定相关的统计信息,具体场景及使用方式参考:[如何锁定统计信息,避免统计信息更新](#如何锁定统计信息,避免统计信息更新) +除了上述方式以外,也可以考虑能否手动收集完大表统计信息之后,锁定相关的统计信息,具体场景及使用方式参考本文中的 “如何锁定统计信息,避免统计信息更新” 部分。 -### 如何锁定统计信息,避免统计信息更新 {#如何锁定统计信息,避免统计信息更新} +### 如何锁定统计信息,避免统计信息更新 针对一些整体数据分布变化不太大,想要维持相关表的查询计划稳定,可以使用如下的方式考虑锁定 / 解锁表的统计信息: ```sql diff --git a/docs/user_manual/operation_and_maintenance/zh-CN/tool_emergency_handbook/01_oms_troubleshooting_guide.md b/docs/user_manual/operation_and_maintenance/zh-CN/tool_emergency_handbook/01_oms_troubleshooting_guide.md index dfac906dc..f52967d2e 100644 --- a/docs/user_manual/operation_and_maintenance/zh-CN/tool_emergency_handbook/01_oms_troubleshooting_guide.md +++ b/docs/user_manual/operation_and_maintenance/zh-CN/tool_emergency_handbook/01_oms_troubleshooting_guide.md @@ -411,7 +411,7 @@ OceanBase 社区版作为源端时,对于无中间件表,OMS 社区版迁移 #### 查询 SQL -```SQL +``` SET TIME_ZONE='%s'; SET sql_mode=''; @@ -494,14 +494,13 @@ SELECT REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, TABLE_SCHEMA, TABLE_NAME | oceanbase.__all_virtual_partition_item | 二级分区信息 | | oceanbase.__all_virtual_partition_sstable_macro_info | 宏块信息表 | -
-

说明

-

宏块信息需要使用系统租户查询

-
+> 说明: +> +> 宏块信息需要使用系统租户查询 #### 查询SQL -```SQL +``` -- 查询所有 Schema SELECT CATALOG_NAME, SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME, SQL_PATH FROM `information_schema`.`SCHEMATA` diff --git a/docs/user_manual/operation_and_maintenance/zh-CN/tool_emergency_handbook/odp_troubleshooting_guide/03_connection_diagnosis.md b/docs/user_manual/operation_and_maintenance/zh-CN/tool_emergency_handbook/odp_troubleshooting_guide/03_connection_diagnosis.md index 3ac832ac8..025ea5fdb 100644 --- a/docs/user_manual/operation_and_maintenance/zh-CN/tool_emergency_handbook/odp_troubleshooting_guide/03_connection_diagnosis.md +++ b/docs/user_manual/operation_and_maintenance/zh-CN/tool_emergency_handbook/odp_troubleshooting_guide/03_connection_diagnosis.md @@ -52,11 +52,25 @@ cluster does not exist, this connection will disconnect [xiaofeng.lby@sqaobnoxdn011161204091.sa128 /home/xiaofeng.lby/obproxy/log] $grep Y0-00007F630AAA2A70 * -obproxy_diagnosis.log:[2024-12-17 14:34:14.024938] [125907][Y0-00007F630AAA2A70] [LOGIN](trace_type="LOGIN_TRACE", connection_diagnosis={cs_id:278640, ss_id:0, proxy_session_id:0, server_session_id:0, client_addr:"127.0.0.1:9988", server_addr:"*Not IP address [0]*:0", cluster_name:"xiaofeng_91_435", tenant_name:"sys", user_name:"root", error_code:-4669, error_msg:"cluster does not exist", request_cmd:"OB_MYSQL_COM_LOGIN", sql_cmd:"OB_MYSQL_COM_LOGIN", req_total_time(us):196}{internal_sql:"", login_result:"failed"}) - -obproxy_error.log:2024-12-17 14:34:14.024960,xiaofeng_cluster_430_proxy,,,,xiaofeng_91_435:sys:,OB_MYSQL,,,OB_MYSQL_COM_LOGIN,,failed,-4669,,194us,0us,0us,0us,Y0-00007F630AAA2A70,,127.0.0.1:9988,,0,,cluster not exist, - -obproxy.log:[2024-12-17 14:34:13.584801] INFO [PROXY.NET] accept (ob_mysql_session_accept.cpp:36) [125907][Y0-00007F630AAA2A70] [lt=0] [dc=0] [ObMysqlSessionAccept:main_event] accepted connection(netvc=0x7f630aa7d2e0, client_ip={127.0.0.1:9980}) +obproxy_diagnosis.log:[2024-12-17 14:34:14.024938] [125907][Y0-00007F630AAA2A70] [LOGIN] +(trace_type="LOGIN_TRACE", + connection_diagnosis={ + cs_id:278640, ss_id:0, proxy_session_id:0, server_session_id:0, + client_addr:"127.0.0.1:9988", server_addr:"*Not IP address [0]*:0", + cluster_name:"xiaofeng_91_435", tenant_name:"sys", user_name:"root", + error_code:-4669, error_msg:"cluster does not exist", + request_cmd:"OB_MYSQL_COM_LOGIN", sql_cmd:"OB_MYSQL_COM_LOGIN", + req_total_time(us):196} + {internal_sql:"", login_result:"failed"}) + +obproxy_error.log:2024-12-17 +14:34:14.024960,xiaofeng_cluster_430_proxy,,,,xiaofeng_91_435:sys:,OB_MYSQL,,, +OB_MYSQL_COM_LOGIN,,failed,-4669,,194us,0us,0us,0us, +Y0-00007F630AAA2A70,,127.0.0.1:9988,,0,,cluster not exist, + +obproxy.log:[2024-12-17 14:34:13.584801] INFO [PROXY.NET] accept (ob_mysql_session_accept.cpp:36) +[125907][Y0-00007F630AAA2A70] [lt=0] [dc=0] [ObMysqlSessionAccept:main_event] +accepted connection(netvc=0x7f630aa7d2e0, client_ip={127.0.0.1:9980}) ... ``` @@ -72,7 +86,8 @@ connection_diagnosis={ client_addr:"10.10.10.1:58218", server_addr:"*Not IP address [0]*:0", cluster_name:"undefined", tenant_name:"test", user_name:"root", error_code:-4043, - error_msg:"dummy entry is empty, please check if the tenant exists", request_cmd:"COM_SLEEP", sql_cmd:"COM_LOGIN"}{internal_sql:""}) + error_msg:"dummy entry is empty, please check if the tenant exists", + request_cmd:"COM_SLEEP", sql_cmd:"COM_LOGIN"}{internal_sql:""}) ``` 看到最后 error_msg 中的 ``please check if the tenant exists``,基本也就能猜出断连接的原因了。 @@ -144,7 +159,15 @@ obproxy_diagnosis 日志通用内容如下: 登录断连接对应的 trace_type 为 LOGIN_TRACE,租户名错误导致断连接的诊断日志示例如下: ```shell -[2023-09-08 10:37:21.028960] [90663][Y0-00007F8EB76544E0] [CONNECTION](trace_type="LOGIN_TRACE", connection_diagnosis={cs_id:1031798785, ss_id:0, proxy_session_id:0, server_session_id:0, client_addr:"10.10.10.1:44018", server_addr:"*Not IP address [0]*:0", cluster_name:"undefined", tenant_name:"sys", user_name:"root", error_code:-10018, error_msg:"fail to check observer version, empty result", request_cmd:"COM_SLEEP", sql_cmd:"COM_LOGIN"}{internal_sql:"SELECT ob_version() AS cluster_version"}) +[2023-09-08 10:37:21.028960] [90663][Y0-00007F8EB76544E0] [CONNECTION]( + trace_type="LOGIN_TRACE", + connection_diagnosis={ + cs_id:1031798785, ss_id:0, proxy_session_id:0, server_session_id:0, + client_addr:"10.10.10.1:44018", server_addr:"*Not IP address [0]*:0", + cluster_name:"undefined", tenant_name:"sys", user_name:"root", error_code:-10018, + error_msg:"fail to check observer version, empty result", request_cmd:"COM_SLEEP", + sql_cmd:"COM_LOGIN"} + {internal_sql:"SELECT ob_version() AS cluster_version"}) ``` 额外诊断信息为 `internal_sql`,表示 ODP 当前执行的内部请求。 @@ -226,10 +249,9 @@ OceanBase 数据库主动断连接有如下几种场景。 | ODP 传输请求给 OceanBase 数据库时连接断开 | 10016 | An EOS event eceived while proxy transferring request | 需与 OceanBase 数据库配合诊断。 | | ODP 传输 OceanBase 数据库回包时连接断开 | 10014 | An EOS event received while proxy reading response | 需与 OceanBase 数据库配合诊断。 | -
-

说明

-

OceanBase 数据库主动断连接的场景下,ODP 无法收集更为详细的信息,如果 ODP 配置的 OBServer 节点状态正常,则需要配合 OceanBase 数据库的日志进行诊断。

-
+> 说明 +> +> OceanBase 数据库主动断连接的场景下,ODP 无法收集更为详细的信息,如果 ODP 配置的 OBServer 节点状态正常,则需要配合 OceanBase 数据库的日志进行诊断。 ### 客户端主动断连接 @@ -255,10 +277,9 @@ OceanBase 数据库主动断连接有如下几种场景。 | ODP 处理请求时客户端断连接 | 10011 | An EOS event received from client while obproxy handling response | 需客户端配合诊断。 | | ODP 回包时客户端发送断连接 | 10012 | An EOS event received from client while obproxy transferring response | 需客户端配合诊断。 | -
-

说明

-

客户端断连接的场景下,ODP 无法收集更为详细的信息,只能指出客户端方面主动断开连接的操作。比较常见的断连接问题有驱动超时主动断开连接、Druid/Hikaricp/Nginx 等中间件主动断连接、网络抖动等问题,具体情况可与客户端配合诊断。

-
+> 说明 +> +> 客户端断连接的场景下,ODP 无法收集更为详细的信息,只能指出客户端方面主动断开连接的操作。比较常见的断连接问题有驱动超时主动断开连接、Druid / Hikaricp / Nginx 等中间件主动断连接、网络抖动等问题,具体情况可与客户端配合诊断。 ### ODP 或 OceanBase 数据库内部错误 @@ -346,7 +367,8 @@ JDBC 默认的 socketTimeout 配置为 0,即不会产生 socketTimeout 超时 2. 根据 ODP 连接诊断日志信息确定是客户端主动断开了连接,从客户端入手排查,查看 JDBC 堆栈。 ```shell - The last packet successfully received from the server was 5,016 milliseconds ago. The last packet sent successfully to the server was 5,011 milliseconds ago. + The last packet successfully received from the server was 5,016 milliseconds ago. + The last packet sent successfully to the server was 5,011 milliseconds ago. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)