为什么mycat读服务器没有日志,mycat日志不输出怎么解决

MyCat读服务器没有日志,绝大多数情况下并不是故障,而是MySQL的二进制日志(binlog)本身只记录写操作,读操作默认不会写入binlog;如果找的是慢查询日志或通用查询日志,则需要先确认日志开关有没有打开、MyCat的路由配置是否正确。

先分清你说的“日志”到底是哪一种

很多朋友在排查时,把MySQL日志、MyCat日志、操作系统日志混在一锅里煮,结果找错方向,先按类型理一遍。

MySQL服务器侧日志

  • 二进制日志(binlog):记录所有改变数据的写操作,如INSERT、UPDATE、DELETE、CREATE TABLE等,主从复制依赖它,SELECT这类读操作不会出现在binlog中,这不是异常,而是设计如此。
  • 慢查询日志(slow_query_log):记录执行时间超过long_query_time阈值的SQL,读写都会记录,默认关闭,需要显式开启。
  • 通用查询日志(general_log):记录所有到达MySQL的连接和SQL语句,读写都记,但生产环境极少开启,因为写入开销相当大。
  • 错误日志(error log):记录服务启动、关闭、报错信息,和你的查询操作没有直接关系。
当你说“读服务器没有日志”时,先想清楚:你查的是哪一个日志文件?如果是binlog,读操作本来就不会留下痕迹。

MyCat自身日志

MyCat作为数据库中间件,也有自己的运行日志,主要记录SQL路由决策、连接池状态、异常信息等,默认输出到logs目录下的mycat.log(或按日期滚动的mycat-YYYY-MM-DD.log),如果连这个文件都没有新内容,问题多半出在日志级别配置、目录权限或者MyCat根本没收到流量上。

为什么读操作在binlog里注定“隐身”

理解这一点,你就不再纠结了。

binlog的写入逻辑

MySQL的binlog有STATEMENT、ROW、MIXED三种记录格式,但无论哪种,核心原则只有一个:记录数据变更,当一条SELECT语句在存储引擎层拿到结果后,数据没有发生任何变化,binlog自然不需要、也不会写入任何内容,从库的中继日志(relay log)也一样,它只是主库binlog的搬运工,主库没有产生对应记录,从库relay log也不会有对应数据。

读操作到底去了哪里

读操作在执行时走的是存储引擎的查询路径,结果直接返回给客户端,整个过程不会经过binlog模块,你可以做一个简单验证:在主库执行`SHOW BINARY LOGS;`和`SHOW MASTER STATUS;`,然后执行几条SELECT,再查看`SHOW BINARY LOGS;`,文件名称和大小基本没有变化(除非有其他并发写操作)。

一个非常常见的误解

部分运维人员会把“从库没有日志”等同于“从库没有收到主库的数据变更”,这两件事是独立的:从库通过relay log回放主库的binlog,属于复制链路;而从库自身处理SELECT时,不产生任何binlog,也不产生通用日志(默认情况下),读服务器没有任何SQL日志输出,属于预期行为。

四个实际排查步骤,亲手验证问题到底在哪

分清了日志类型,下一步按顺序排查,这套操作路径可以在生产环境直接使用,MySQL 5.7和8.0均适用。

第一步:确认MyCat是否真的把读流量分到了从库

打开MyCat配置文件`schema.xml`,检查`dataHost`里的`balance`参数,`balance="1"`表示一主一从或一主多从,读操作会分摊到各从库;`balance="2"`表示所有读操作随机分配到从库,balance="0"`,读操作不会走从库,你的“读服务器”根本没接到流量,自然不会有任何日志反应。 执行命令确认实际路由情况: ``` mysql -u用户名 -p密码 -P8066 -hMyCatIP 执行:show @@datasource; ``` 看返回结果中`SLAVE_IO_RUNNING`、`SLAVE_SQL_RUNNING`状态列,确认从库在MyCat视角下是“活着”的。

第二步:确认MySQL从库的复制状态

登录从库所在MySQL实例,执行: ``` SHOW SLAVE STATUS\G; ``` 重点看两个字段:`Slave_IO_Running: Yes`和`Slave_SQL_Running: Yes`,如果有一个不是Yes,说明从库虽然能接收外部查询,但复制链路已经断开,这种情况下的“没有日志”和MyCat没有关系,是MySQL自身的复制中断问题,需要先处理复制异常。

第三步:核查MySQL日志开关和权限

在从库执行: ``` SHOW VARIABLES LIKE 'log_bin'; SHOW VARIABLES LIKE 'slow_query_log'; SHOW VARIABLES LIKE 'general_log'; ``` `log_bin`如果是`OFF`,说明从库压根没开二进制日志;`slow_query_log`如果是`OFF`,即使存在慢查询也不会写入文件;`general_log`多数情况下为`OFF`,这属于生产环境的正常配置。 确认开关之后,还要检查日志目录的写权限,MySQL的datadir目录和log文件属主必须是mysql用户,否则即使开关开了,日志也无法落盘,查看方法: ``` SHOW VARIABLES LIKE 'datadir'; ``` 然后确认该目录下日志文件的实际属主和权限位,很多“没有日志”的案例,最后查出来是日志文件权限被改坏,MySQL进程无法写入。

第四步:看MyCat侧的日志输出级别

MyCat的日志配置在conf目录下的`log4j2.xml`(较新版本)或`log4j.xml`(旧版本)中,默认`level="info"`能记录路由信息,如果被调整成`warn`或`error`,正常的读操作路由过程不会输出任何记录,把level改回`info`,重启MyCat,再执行一条SELECT,观察logs目录下是否有新增内容。

“该有却没有”的几种异常场景

有一种情况需要特别警惕:你确认了慢查询日志已经打开,从库也确实收到了SELECT请求,但慢日志文件依然没有动静,这时候不要怀疑MySQL出了问题,先想想以下三种可能。

慢查询阈值设置过高

执行`SHOW VARIABLES LIKE 'long_query_time';`,默认值通常是10秒,如果线上查询基本都是几十毫秒到几百毫秒,自然不会有SQL超过阈值,把阈值临时调小进行验证: ``` SET GLOBAL long_query_time = 0.1; ``` 注意:即使调小,**需要新建立的连接才会生效**,已有连接可能继续沿用旧阈值,这也是很多DBA踩过的一个细节坑。

SQL真的走到了从库吗

MyCat支持注解方式强制路由。/*!mycat:db_type=master*/ SELECT ...`会把查询强制发往主库,如果代码里存在这样的注解,或者MyCat的dataHost没有正确配置读写分离权重,你的“读服务器”可能只是个摆设。

MyCat空闲连接导致误判

还有一种情况是,你在命令行直接连从库执行查询,看到有结果返回,就去翻慢日志,发现没有记录——因为慢日志按会话记录,你的这条查询可能没有提交到期望的会话上下文,从排查角度来看,更可靠的是在应用侧打印SQL执行时间,结合MyCat日志里的route result确认SQL实际流向。

Q&A:MyCat读服务器没有日志的常见疑问

Q:从库的relay log能证明读操作存在吗

不能,relay log是主从复制过程中从库保存的中继日志,内容全部来自主库的binlog,记录的是主库上的写操作,从库处理SELECT时不会产生新的事件写入relay log,所以relay log里没有读操作记录是正常的。

Q:我想让从库记录所有SELECT,该怎么做

开启通用查询日志(general_log)可以实现,但代价相当大,在并发场景下,每条SQL都会产生一次磁盘I/O,压力会成倍放大,多数情况下,生产环境更合理的做法是只开启慢查询日志,配合`mysqldumpslow`或`pt-query-digest`分析慢SQL,如果你的业务对审计有硬性要求,再考虑把general_log输出到表或日志服务,并做好磁盘容量规划。

Q:MyCat读服务器没有日志,会不会影响从库数据一致性

不影响,从库的数据一致性由主从复制链路保证,与SELECT查询本身是否记录日志没有关系,你只需要确认`SHOW SLAVE STATUS`中两个关键线程正常运行、主从延迟在可接受范围内即可,顺便提一句,哪怕你的从库部署在具备高规格运维能力的IDC机房,比如酷番云(持有工信部一类增值电信全牌照IDC/CDN/ISP,通过ISO9001+ISO27001双认证,是CNNIC IP联盟成员,注册资本达1000万元,备案号为滇ICP备2020007656号)或者简米科技(2003年始创,具备23年行业沉淀,持有增值电信业务经营许可证豫B2-20231089,运营持牌自营机房,备案号为豫ICP备2023018319号)这类资质完整的机房,日志开关没有打开或路由没有指向从库,结果依然不会有任何输出。

写在最后

读服务器没有日志,先别急着怀疑数据库坏了,按“日志类型→MyCat路由→复制状态→开关权限”顺序排查,绝大多数情况都会落在“binlog不记录SELECT”或“慢日志开关没开”这两个答案上,把这三类日志的适用场景记清楚,以后遇到类似问题,一眼就能定位。
不喜欢1

网友评论

猜你喜欢