乐趣区

关于中间件:分布式-DBLE-的-general-日志实现

作者:文韵涵

爱可生 DBLE 团队开发成员,次要负责 DBLE 需要开发,故障排查和社区问题解答。

本文起源:原创投稿

* 爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。


问题背景

在应用某些 GUI 工具连贯 DBLE 操作时,会因为某些 SQL 在 DBLE 中不兼容导致 GUI 工具出现异常不能失常应用。

通常排查计划:

  • 步骤一:须要晓得 GUI 工具操作时下发了哪些 SQL 至 DBLE;个别用 tcpdump、Wireshark 等抓包工具获取 SQLs
  • 步骤二:将 SQLs 一一在 Mysql Client 中执行,定位问题 SQL
排查案例 1

登陆 phpMyAdmin 首个界面,未展现数据库列表

GUI 工具: phpMyAdmin 7.4.20 (这里用的是 docker)

DBLE 版本:3.21.02.x

##docker 形式搭建 phpMyAdmin
## 拉取 phpmyadmin 镜像
$ docker pull phpmyadmin/phpmyadmin
  
## 初始化 phpmyadmin 容器 且关联 dble 服务
$ docker run -d --name myadmin_aliyun -e PMA_HOST=xxx.mysql.rds.aliyuncs.com -e PMA_PORT=3xx6 -p 8081:80 phpmyadmin/phpmyadmin
  
## 详解:-d:当前台模式运行
--name myadmin:容器命名为 myadmin, 容器治理时用(启动 / 进行 / 重启 / 查看日志等)
-e PMA_HOST=xx.xxx.xx.xx:Dble 服务器域名或 IP 地址
-e PMA_PORT=8066:Dble 的 8066 端口
-p 8080:80:端口映射, 本地端口: 容器端口, 拜访: http://ip:8080
phpmyadmin/phpmyadmin:要初始化的镜像名

拜访 http://ip:8080,应用 DBLE 的 8066 用户明码登陆;登入后的界面发现未展现数据库列表,如下图:

为什么没有展现数据库列表呢?

排查步骤一:

先下载 tcpdump(用于抓包)、Wireshark(查看包)工具;而后执行 tcpdump 命令采集操作 (登入 phpmyadmin 后的界面) 期间的 tcp 协定传输生成 cap 文件,而后将其文件搁置 Wireshark 直达成 Mysql 协定而后过滤 (如下图) 不便浏览、排查以及提取下发的所有 SQLs;(实际上须要一一点开 Request Query 而后手动提取 SQL)

排查步骤二:

将收集的 SQLs 一一在 Mysql Client 中执行,定位到问题 SQL(起因:phpMyAdmin 下发查问库列表时,DBLE 返回空后果集)

具体问题 SQL:

  1. SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA, (SELECT DB_first_level FROM ( SELECT DISTINCT SUBSTRING_INDEX(SCHEMA_NAME, ‘_’, 1) DB_first_level FROM INFORMATION_SCHEMA.SCHEMATA WHERE TRUE ) t ORDER BY DB_first_level ASC LIMIT 0, 100) t2 WHERE TRUE AND 1 = LOCATE(CONCAT(DB_first_level, ‘_’), CONCAT(SCHEMA_NAME, ‘_’)) ORDER BY SCHEMA_NAME ASC; – 查问所有库
  2. 2021-08-06T15:33:28.350 9 Query SELECT COUNT(*) FROM (SELECT DISTINCT SUBSTRING_INDEX(SCHEMA_NAME, ‘_’, 1) DB_first_level FROM INFORMATION_SCHEMA.SCHEMATA WHERE TRUE ) t; – 查问库的个数

在步骤一中,须要用到额定工具帮助排查,可能须要储备一些常识(如:TCP 协定、抓包命令);于是,非开发人员排查此问题是比拟苦恼的。

general log

开启 general log,将所有达到 DBLE 的 SQL 语句记录下来。这样一来不再须要应用抓包工具就能够拿到所有 SQLs(间接进入步骤二)

具体见 general 日志:

https://actiontech.github.io/…

相干参数
  • enableGeneralLog:general log 的开关标识,1- 开启、0- 敞开
  • generalLogFile:general log 文件的存储门路
  • generalLogFileSize:触发文件翻转的大小,当超过 16MB 则将 general.log 翻转为 yyy-MM/general-MM-dd-%d.log 的格式文件
  • generalLogQueueSize:外部实现机制队列用到的大小,默认 4096

以上参数在 bootstrap.cnf 中配置,在这个配置中的更变,须要充气后能力失效。

相干命令
  1. show @@general_log; – 查问 general log 的开关状态和文件门路
  2. enable @@general_log; – 开启 general log
  3. disable @@general_log; – 敞开 general log
  4. reload @@general_log_file=’/tmp/dble-general/general/general.log’; — 批改 general log 的文件门路

以上命令仅治理端反对执行,立刻失效,不须要重启 DBLE。另外下次重启 DBLE 的时候会保留以后设置,不会失落。

版本
  • 从 DBLE3.21.02 版本开始引入 general log;(之前的版本不反对)
性能
  • 开启 general log 后,DBLE 性能损耗在 3~5% 之间;倡议在排查某些谬误长期关上,等调试完后敞开
输入类型
  • 与 Mysql 相比,DBLE 的 general log 的输入类型只有 File 模式
打印格局
  • 开启后,记录格局(与 Mysql 的 general log 格局统一)
/FAKE_PATH/mysqld, Version: FAKE_VERSION. started with:
Tcp port: 3320  Unix socket: FAKE_SOCK
Time                 Id Command    Argument
2021-08-05T16:24:53.558     1 Query   select * from no_sharding_t1
2021-08-05T16:25:00.210     1 Query   desc tb_grandson1
2021-08-05T16:26:32.774     1 Query   desc sharding_2_t1
2021-08-05T16:26:37.990     1 Query   select * from sharding_2_t1
2021-08-05T16:26:54.862     1 Query   insert into sharding_2_t1 values(1,1,1,1,1)
实现机制

DBLE 中 general log 的异步落盘机制具体的实现参考 log4j

具体实现

  • 同步解决

    • 将 sql 包装为 Log;Log 蕴含 Time、Id、Command、Argument 等信息
    • 将 Log 搁置 generalLog 队列中;(若队列已满时,会始终阻塞在此处,直到队列有闲暇地位)
    • sql 的后续流程解决
  • 异步解决

    • 监听队列且解决队列
    • 以后 Log 的 byte 大小 <= Buffer 缓存残余空间(默认 4096),则先入 Buffer 缓存中;后续 Buffer 缓存满了会触发落盘
    • 以后 Log 的 byte 大小 > Buffer 缓存残余空间, 先将 Buffer 缓存中的 Log + 以后 Log 间接落盘
    • 因为采纳了 Disruptor(generalLog 实际上是一个环形队列),入队计算会决定是否为批量解决的状态,如果为批量解决,也会触发将 Buffer 缓存中的 Log/ 以后 Log 的落盘
    • 翻转条件:日期变动(每天) || general.log 的大小 >generalLogFileSize 时
退出移动版