zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

逐步分析MySQL从库com_insert无变化的原因

mysql 分析 原因 变化 INSERT com 从库 逐步
2023-06-13 09:15:26 时间

大家都知道com_insert等com_xxx参数可以用来监控数据库实例的访问量,也就是我们常说的QPS。并且基于MySQL的复制原理,所有主库执行的操作都会在从库重放一遍保证数据一致,那么主库的com_insert和从库的com_insert理论上应该是相等的。
如下面显示,第二列代表主库,第三列代表从库:

复制代码代码如下:


com_select             22                1138
com_update             36                  37
com_insert            133                 135
com_delete              0                   0
qcache_hits             0                   0
Com_replace             0                   0
Connections            13                  24

但是我们看另外一个业务:

复制代码代码如下:


com_select              0                  95
com_update              0                   0
com_insert             92                   0
com_delete             20                   0
qcache_hits             0                   6
Com_replace             0                   0
Connections             0                   6

我们可以很明显的看出来,主库有92个写,但是从库0个写,这是为什么呢?

这2个业务唯一的区别就是binlog_format的设置不一样。

复制代码代码如下:
第一个业务
showglobalvariableslike"%binlog_format%";
+---------------+-----------+
|Variable_name|Value    |
+---------------+-----------+
|binlog_format|STATEMENT|
+---------------+-----------+

第二个业务
showglobalvariableslike"%binlog_format%";
+---------------+-------+
|Variable_name|Value|
+---------------+-------+
|binlog_format|ROW  |
+---------------+-------+

我们来看下com_xxx的官方文档定义:

TheCom_xxxstatementcountervariablesindicatethenumberoftimeseachxxxstatementhasbeenexecuted.Thereisonestatusvariableforeachtypeofstatement.Forexample,Com_deleteandCom_updatecountDELETEandUPDATEstatements,respectively.Com_delete_multiandCom_update_multiaresimilarbutapplytoDELETEandUPDATEstatementsthatusemultiple-tablesyntax.

从上述文档,我们只能看到com_xxx是如何运作的,但是并不能解释为什么使用RBR之后com_insert就不变化了。

接下来我们结合下面这段文档来一起看看。

Youcannotexaminethelogstoseewhatstatementswereexecuted,norcanyouseeontheslavewhatstatementswerereceivedfromthemasterandexecuted.
However,youcanseewhatdatawaschangedusingmysqlbinlogwiththeoptions--base64-output=DECODE-ROWSand--verbose.

这2段话结合来看,原因应该是这样的:

1、主库上接收的是statement的语句,所以com_insert符合触发条件,会随着业务增加。

2、而从库是拿到主库的binlog后重放更新数据,但是主库的日志格式是rowformat,这就导致了binlog中记录的不是statement语句,而是data的变化记录。

3、这样从库虽然依然能进行更新记录,但是无法解析出来这些data变化是一条statement语句导致的还是多条statment语句导致,所以就不在更新com_insert这个statmentcounter了。

基本上推论符合现实情况,但是没有code证明,比较遗憾。

另外,如果我们无法通过com_insert来监控从库的写入情况,那么我们应该监控那个status呢?

个人建议对于row格式的实例,通过监控innodb_rows_inserted来监控写入情况。

复制代码代码如下:
showglobalstatuslike"innodb_rows_inserted";
+----------------------+------------+
|Variable_name       |Value     |
+----------------------+------------+
|Innodb_rows_inserted|2666049650|
+----------------------+------------+

附:(两个文档的官方文档链接)

http://dev.mysql.com/doc/refman/5.6/en/server-status-variables.html#statvar_Com_xxx

http://dev.mysql.com/doc/refman/5.5/en/replication-sbr-rbr.html