COM_QUIT and Questions

In the pursuit of intricate details, we always want 2 + 2 to equal 4. In the case of the status value Questions, 2 + 2 seems to equal much less than 4. On a production server this discrepancy can often be a magnitude in the millions. Thanks to a poster named bwakem on dbforums.com, the primary discrepancy was found to be the status value Connections, which usually accounts for the missing Questions.

In an effort to understand why, beyond simply knowing that this is, I dove into the MySQL source code (version 5.0.10 beta) to see what was going on and where. This document is part detailed explanation of why Connections allows Questions to add up evenly, and part journey through the MySQL source code. Numbers in brackets like [1507] scattered throughout the document are source code line references.

Adding Up Questions

If you've read this article before, you'll remember I formerly thought the formula for the status value Questions was:

Questions = Com_* + Qcache_hits + ((Connections - 2) - (Aborted_clients / 2))

However, since mysqlreport v2.2 and its new --dtq (Distribution of Total Questions) option, I've found that this is not always 100% accurate. Meaning, there are yet other things which increment Questions, but cannot be directly counted with the values from SHOW STATUS. Consequently, when mysqlreport notices such "hidden" values, it lists a line in the DTQ report for these called "Unknown." (Ironically, the last sentence of this article, as preserved, mentions "the satisfaction of knowing MySQL isn't hiding something from us"—apparently I was wrong.) On some servers, as one example report shows, the value of Unknown Questions as a percentage of Total Questions can be quite large. However, it is possible to have no Unknown Questions. For this reason, I leave this article as-is until I can do the laborious task of tracking down all the hidden values. For now, here follows the original article; just be aware there's more to be discovered...

What increments Connections is not actually what increments Questions in turn. The MySQL protocol command COM_QUIT is actually what increments Questions; Connections is the closest status available to us to quantify how many COM_QUIT commands MySQL has handled. Naturally this works because every connection is eventually going to quit (forgetting, for the sake of simplicity, persistent connections). Two is subtracted from Connections first for the current connection (the one in which SHOW STATUS is being executed, which obviously hasn't quit yet), and again because MySQL starts Connections at 1 instead of 0 so the very first connection shows Connections is 2 (I don't why; an issue for another document perhaps). Half of Aborted_clients is subtracted from Connections because an aborted client causes Connections to increment but doesn't send a COM_QUIT command (hence why it's considered aborted). Aborted_clients is divided by 2 because MySQL apparently increments it in twos for even a single aborted client (another issue for another document). What would increment Com_select increments Qcache_hits instead if MySQL is able to get the query from the query cache. The sum of all Com_* status values is the primary contribution to Questions. (Although I haven't tested more particular Com_ values like Com_slave_start, looking at the source code I believe it's reasonable to say all Com_ values increment Questions.)

COM_QUIT and Questions In Action

An important part of understanding the MySQL source code is the global and per-thread variables query_id (sql/mysql_priv.h [47-49] and sql/sql_class.h [1233-1241]). For clarity, and because it appears this way in the code, query_id refers to the global query_id and thd->query_id refers to the per-thread query_id (where thd is an instantiation of class THD, sql/sql_class.h [1028-1490]). query_id starts at 1. Every question MySQL handles is given a number which comes from query_id. Therefore, if you start MySQL, login with the mysql cli, and quit (/q), when the cli sends the COM_QUIT command, this being the first question is given the number 1. Naturally, after each question is given its number, query_id is incremented by 1. This process happens in sql/sql_parse.cc, function dispatch_command() [1507-1509]. First thd->query_id is assigned the current value of query_id [1507]. If the question (i.e., command, query, etc.) is not COM_STATISTICS or COM_PING [1508], then query_id is incremented by 1 [1509].

Knowing this, it's easy to understand why Questions is simply thd->query_id (sql/sql_show.cc [1338]). Although each thread (thd) will have a different value for its query_id, when you tell MySQL "SHOW STATUS;", at that instant that question (which results in a COM_QUERY command) gets the next global query_id number. Since all threads have been taking their numbers from query_id, this is an accurate count of all questions for all threads.

Since COM_QUIT is sent by every civilized MySQL interface when the script or program using that interface is done, this explains why COM_QUIT, seen by us as Connections, counts toward Questions. In a sense you could say the formula for COM_QUIT is:

COM_QUIT = (Connections - 2) - (Aborted_clients / 2)

Perhaps MySQL AB will add a Com_quit status value. Then the formula for Questions would be really simple and intuitive:

Questions = Com_* + Qcache_hits

Until then, we at least have the satisfaction of knowing MySQL isn't hiding something from us; it's just a little obfuscated.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Action 4: increasing the number of books of a given user. When the user of the software specifies action 4, your program must ask the user to type the name of a user, and a number of books, and the program then uses that number to increase the number of books lent or borrowed by the user. Then the program goes back to the main menu. For example: Type an action (total:1 add:2 get:3 more:4 less:5 quit:6): 3 Enter the name of the user: Anna Anna borrows -5 book(s). Type an action (total:1 add:2 get:3 more:4 less:5 quit:6): 4 Enter the name of the user: Anna Enter the number of books: 2 Type an action (total:1 add:2 get:3 more:4 less:5 quit:6): 3 Enter the name of the user: Anna Anna borrows -7 book(s). Type an action (total:1 add:2 get:3 more:4 less:5 quit:6): 3 Enter the name of the user: Bob Bob borrows 10 book(s). Type an action (total:1 add:2 get:3 more:4 less:5 quit:6): 4 Enter the name of the user: Bob Enter the number of books: 2 Type an action (total:1 add:2 get:3 more:4 less:5 quit:6): 3 Enter the name of the user: Bob Bob borrows 12 book(s). Type an action (total:1 add:2 get:3 more:4 less:5 quit:6): If the name of the user is wrong, then an UnknownUserException exception will be thrown by the Library object. The code of the main method of your CLI class must catch this exception, print the error message from the exception object, and then it just goes back to printing the menu of actions (by just going back to the beginning of the while loop). For example (where 4, aaaa, and 2 are inputs from the user): Type an action (total:1 add:2 get:3 more:4 less:5 quit:6): 4 Enter the name of the user: aaaa Enter the number of books: 2 User aaaa unknown. Type an action (total:1 add:2 get:3 more:4 less:5 quit:6): Note that, even if a consumer is a borrower, the readPosInt method prevents the typed number of books from being negative. This means a borrower will never throw a NotALenderException. Nevertheless the code of the main method of your CLI class must handle this exception by printing the error message "BUG! This must never happen!" and immediately terminating the program using System.exit(1). For example (where 3, Bob, 4, Bob, and -15 are inputs from the user): Type an action (total:1 add:2 get:3 more:4 less:5 quit:6): 3 Enter the name of the user: Bob Bob borrows 12 book(s). Type an action (total:1 add:2 get:3 more:4 less:5 quit:6): 4 Enter the name of the user: Bob Enter the number of books: -15 Positive integers only! Enter the number of books:
05-24

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值