SQLクエリタイムアウトの設定方法(timeoutの処理について)

7030 ワード

OceanBaseのquery timeout設定方式を最適化するため、MySQLのtimeoutに関する処理を調査し、以下に記録する.
 
  
mysql> show variables like '%time%';
+----------------------------+-------------------+
| Variable_name | Value |
+----------------------------+-------------------+
| connect_timeout | 10 |
| datetime_format | %Y-%m-%d %H:%i:%s |
| delayed_insert_timeout | 300 |
| flush_time | 1800 |
| innodb_lock_wait_timeout | 50 |
| innodb_old_blocks_time | 0 |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| lc_time_names | en_US |
| lock_wait_timeout | 31536000 |
| long_query_time | 10.000000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| slow_launch_time | 2 |
| system_time_zone | |
| time_format | %H:%i:%s |
| time_zone | SYSTEM |
| timed_mutexes | OFF |
| timestamp | 1366027807 |
| wait_timeout | 28800 |
+----------------------------+-------------------+
21 rows in set, 1 warning (0.00 sec)

いくつかのパラメータを重点的に説明します.
connect_timeout:
The number of seconds that the mysqld server waits for a connect packet before respondingwith Bad handshake. The default value is 10 seconds as of MySQL 5.1.23 and 5 seconds before that. Increasing the connect_timeout value might help if clients frequently encounter errors of the form Lost connection to MySQL server at ‘XXX', system error: errno.
解释:リンクを取得するとき、握手を待つタイムアウト时间は、ログイン时にのみ有効であり、ログイン成功というパラメータは问题ありません.主に、ネットワークが不良な場合に再接続を適用して接続数が速くなるのを防ぐため、一般的にはデフォルトでよい.
interactive_timeout:
The number of seconds the server waits for activity on an interactive connection before closing it. An interactive client is defined as a client that uses the CLIENT_INTERACTIVE option to mysql_real_connect(). See alsowait_timeout.
説明:SLEEP状態が続くスレッドがどのくらい閉じられますか.スレッドは使用されるたびにacrivity状態として起動し,Queryの実行が完了するとinteractive状態となり,計時を再開する.wait_timeoutの違いは,TCP/IPとSocketリンクのみに作用するスレッドであり,意味は同じである.
MySQLは接続のタイムアウト時間を構成することができます.この時間が長すぎると、10 minになると、3000個のリンクがいっぱいになり、sleepがどこにあるのか、新しいリンクが入らず、正常にサービスできない可能性があります.したがって、この構成は、論理に合致する値、60 sまたは120 sなどをできるだけ構成する.
人の話をする:
コマンドラインの下でコマンドをノックした後、次のコマンドが来るまでの間隔がinteractive_time、この間隔がinteractiveを超えたらtimeoutでは、接続が自動的に切断され、次のコマンドが失敗します.しかし、一般的なmysqlクライアントには自動再接続メカニズムがあり、次のコマンドは再接続後に実行されます.
 
  
mysql> set interactive_timeout = 1;
Query OK, 0 rows affected (0.00 sec)
mysql> show session variables like '%timeout%';
+----------------------------+----------+
| Variable_name | Value |
+----------------------------+----------+
| connect_timeout | 10 |
| interactive_timeout | 1 |
| wait_timeout | 28800 |
+----------------------------+----------+
10 rows in set (0.00 sec)
 
  
mysql> set wait_timeout = 1;
Query OK, 0 rows affected (0.00 sec)
【 , 】
mysql> show session variables like '%timeout%';
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 7
Current database: *** NONE ***
+----------------------------+----------+
| Variable_name | Value |
+----------------------------+----------+
| connect_timeout | 10 |
| interactive_timeout | 28800 |
| wait_timeout | 28800 |
+----------------------------+----------+
10 rows in set (0.01 sec)

wait_timeout:
The number of seconds the server waits for activity on a noninteractive connection(接続にアクティブコマンドがないので、クライアントがコーヒーを飲んだのかもしれません.)before closing it. Before MySQL 5.1.41, this timeout applies only to TCP/IP connections, not to connections made through Unix socket files, named pipes, or shared memory.
On thread startup, the session wait_timeout value is initialized from the global wait_timeout value or from the global interactive_timeout value, depending on the type of client
ここではnon-interactive connectionとは
> Non-Interactive Commands
Just do a quick look up on a table without logging into the client, running the query then logging back out again.
You can instead just type one line using the ' -e ' flag.
 
  
c:\mysql\bin\mysql -u admin -p myDatabase -e 'SELECT * FROM employee'

net_read_timeout/net_write_timeout
The number of seconds to wait for more data from a connection before aborting the read. Before MySQL 5.1.41, this timeout applies only to TCP/IP connections, not to connections made through Unix socket files, named pipes, or shared memory. When the server is reading from the client, net_read_timeout is the timeout value controlling when to abort. When the server is writing to the client, net_write_timeout is the timeout value controlling when to abort. See also slave_net_timeout.
On Linux, the NO_ALARM build flag affects timeout behavior as indicated in the description of the net_retry_count system variable.
説明:このパラメータはTCP/IPリンクに対してのみ有効であり、それぞれデータベースが受信クライアントがネットワークパケットを送信するのを待つタイムアウト時間と、ネットワークパケットをクライアントに送信するのを待つタイムアウト時間であり、これはActivity状態のスレッドで有効なパラメータである
JDBC setQueryTimeout関数:
クエリのデッドサイクルや時間が長すぎるなどの現象を回避するためにスレッドがブロックする、Statementのインスタンスを取得した後、stmt.setQueryTimeout(10); クエリによるスレッドのブロックを回避します.
しかし、昨日、プログラムに「ORA-01013:ユーザーが現在の操作をキャンセルするように要求した」という異常が発生したことがわかりました.エラーSQL文を手動で実行すると、この文は20秒以上かかります.setQueryTimeout(10)のため、クエリ文の実行が完了しないうちに例外が放出される.setQueryTimeout(10)を使用する場合は、60秒以上のように時間を長く設定する必要があります.スレッドが長期にわたってブロックされない限り、可能です.短すぎて投げ出しやすい「ORA-01013:ユーザから現在の操作のキャンセルを要求された」という異常
JDBCがsetQueryTimeoutを実現する原理:
 
  
class IfxCancelQueryImpl extends TimerTask
implements IfmxCancelQuery
{
IfxStatement stmt;
Timer t = null;
public void startCancel(IfxStatement paramIfxStatement, int paramInt)
throws Exception
{
this.stmt = paramIfxStatement;
this.t = new Timer(true);
this.t.schedule(this, paramInt * 1000);
}
public void run()
{
try
{
this.stmt.cancel();
this.t.cancel();
}
catch (SQLException localSQLException)
{
this.t.cancel();
throw new Error(localSQLException.getErrorCode() + ":" + localSQLException.getMessage());
}
}
}

query timeoutはクライアントソリューションによって行われており、サーバ側は知る必要はありません.実行時間はtimerスレッドで監視され、実行時間がタイムアウトした場合はschedule run()関数になります.
Reference:
http://wangwei.cao.blog.163.com/blog/static/10236252620111119115540534/
http://sls8204.blog.163.com/blog/static/62979632200741683453114/
OceanBaseはserver側でquery timeoutをサポートし、query timeoutを設定し、現在のセッションを中断しないことができます.この点はMySQLより進んでいます.