~percona-core/percona-server/5.1

« back to all changes in this revision

Viewing changes to patches/innodb_kill_idle_transaction.patch

  • Committer: Stewart Smith
  • Date: 2011-11-24 08:14:40 UTC
  • Revision ID: stewart@flamingspork.com-20111124081440-jffloqgkbgytzgl5
remove now unneeded patches as we're part of a happy bzr tree

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# name       : innodb_kill_idle_transaction.patch
2
 
# introduced : 5.1.58
3
 
# maintainer : Yasufumi
4
 
#
5
 
#!!! notice !!!
6
 
# Any small change to this file in the main branch
7
 
# should be done or reviewed by the maintainer!
8
 
--- a/include/mysql/plugin.h
9
 
+++ b/include/mysql/plugin.h
10
 
@@ -847,6 +847,12 @@
11
 
 */
12
 
 void thd_set_ha_data(MYSQL_THD thd, const struct handlerton *hton,
13
 
                      const void *ha_data);
14
 
+
15
 
+int thd_command(const MYSQL_THD thd);
16
 
+long long thd_start_time(const MYSQL_THD thd);
17
 
+void thd_kill(MYSQL_THD thd);
18
 
+#define EXTENDED_FOR_KILLIDLE
19
 
+
20
 
 #ifdef __cplusplus
21
 
 }
22
 
 #endif
23
 
--- a/include/mysql/plugin.h.pp
24
 
+++ b/include/mysql/plugin.h.pp
25
 
@@ -150,3 +150,6 @@
26
 
 void *thd_get_ha_data(const void* thd, const struct handlerton *hton);
27
 
 void thd_set_ha_data(void* thd, const struct handlerton *hton,
28
 
                      const void *ha_data);
29
 
+int thd_command(const void* thd);
30
 
+long long thd_start_time(const void* thd);
31
 
+void thd_kill(void* thd);
32
 
--- a/sql/sql_class.cc
33
 
+++ b/sql/sql_class.cc
34
 
@@ -470,6 +470,26 @@
35
 
   return buffer;
36
 
 }
37
 
 
38
 
+/* extend for kill session of idle transaction from engine */
39
 
+extern "C"
40
 
+int thd_command(const THD* thd)
41
 
+{
42
 
+  return (int) thd->command;
43
 
+}
44
 
+
45
 
+extern "C"
46
 
+long long thd_start_time(const THD* thd)
47
 
+{
48
 
+  return (long long) thd->start_time;
49
 
+}
50
 
+
51
 
+extern "C"
52
 
+void thd_kill(THD* thd)
53
 
+{
54
 
+  pthread_mutex_lock(&thd->LOCK_thd_data);
55
 
+  thd->awake(THD::KILL_CONNECTION);
56
 
+  pthread_mutex_unlock(&thd->LOCK_thd_data);
57
 
+}
58
 
 
59
 
 /**
60
 
   Implementation of Drop_table_error_handler::handle_error().
61
 
--- a/storage/innodb_plugin/handler/ha_innodb.cc
62
 
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
63
 
@@ -2517,6 +2517,10 @@
64
 
 
65
 
        innobase_commit_concurrency_init_default();
66
 
 
67
 
+#ifndef EXTENDED_FOR_KILLIDLE
68
 
+       srv_kill_idle_transaction = 0;
69
 
+#endif
70
 
+
71
 
        /* Since we in this module access directly the fields of a trx
72
 
        struct, and due to different headers and flags it might happen that
73
 
        mutex_t has a different size in this module and in InnoDB
74
 
@@ -11231,6 +11235,48 @@
75
 
        return(false);
76
 
 }
77
 
 
78
 
+/***********************************************************************
79
 
+functions for kill session of idle transaction */
80
 
+extern "C"
81
 
+ibool
82
 
+innobase_thd_is_idle(
83
 
+/*=================*/
84
 
+       const void*     thd)    /*!< in: thread handle (THD*) */
85
 
+{
86
 
+#ifdef EXTENDED_FOR_KILLIDLE
87
 
+       return(thd_command((const THD*) thd) == COM_SLEEP);
88
 
+#else
89
 
+       return(FALSE);
90
 
+#endif
91
 
+}
92
 
+
93
 
+extern "C"
94
 
+ib_int64_t
95
 
+innobase_thd_get_start_time(
96
 
+/*========================*/
97
 
+       const void*     thd)    /*!< in: thread handle (THD*) */
98
 
+{
99
 
+#ifdef EXTENDED_FOR_KILLIDLE
100
 
+       return((ib_int64_t)thd_start_time((const THD*) thd));
101
 
+#else
102
 
+       return(0); /*dummy value*/
103
 
+#endif
104
 
+}
105
 
+
106
 
+extern "C"
107
 
+void
108
 
+innobase_thd_kill(
109
 
+/*==============*/
110
 
+       void*   thd)
111
 
+{
112
 
+#ifdef EXTENDED_FOR_KILLIDLE
113
 
+       thd_kill((THD*) thd);
114
 
+#else
115
 
+       return;
116
 
+#endif
117
 
+}
118
 
+
119
 
+
120
 
 static SHOW_VAR innodb_status_variables_export[]= {
121
 
   {"Innodb",                   (char*) &show_innodb_vars, SHOW_FUNC},
122
 
   {NullS, NullS, SHOW_LONG}
123
 
@@ -11474,6 +11520,15 @@
124
 
   "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
125
 
   NULL, NULL, 500L, 1L, ~0L, 0);
126
 
 
127
 
+static MYSQL_SYSVAR_LONG(kill_idle_transaction, srv_kill_idle_transaction,
128
 
+  PLUGIN_VAR_RQCMDARG,
129
 
+#ifdef EXTENDED_FOR_KILLIDLE
130
 
+  "If non-zero value, the idle session with transaction which is idle over the value in seconds is killed by InnoDB.",
131
 
+#else
132
 
+  "No effect for this build.",
133
 
+#endif
134
 
+  NULL, NULL, 0, 0, LONG_MAX, 0);
135
 
+
136
 
 static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
137
 
   PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR,
138
 
   "Number of file I/O threads in InnoDB.",
139
 
@@ -11767,6 +11822,7 @@
140
 
   MYSQL_SYSVAR(fast_checksum),
141
 
   MYSQL_SYSVAR(commit_concurrency),
142
 
   MYSQL_SYSVAR(concurrency_tickets),
143
 
+  MYSQL_SYSVAR(kill_idle_transaction),
144
 
   MYSQL_SYSVAR(data_file_path),
145
 
   MYSQL_SYSVAR(doublewrite_file),
146
 
   MYSQL_SYSVAR(data_home_dir),
147
 
--- a/storage/innodb_plugin/include/srv0srv.h
148
 
+++ b/storage/innodb_plugin/include/srv0srv.h
149
 
@@ -282,6 +282,7 @@
150
 
 extern ulint   srv_activity_count;
151
 
 extern ulint   srv_fatal_semaphore_wait_threshold;
152
 
 extern ulint   srv_dml_needed_delay;
153
 
+extern lint    srv_kill_idle_transaction;
154
 
 
155
 
 extern mutex_t*        kernel_mutex_temp;/* mutex protecting the server, trx structs,
156
 
                                query threads, and lock table: we allocate
157
 
--- a/storage/innodb_plugin/include/trx0trx.h
158
 
+++ b/storage/innodb_plugin/include/trx0trx.h
159
 
@@ -600,6 +600,8 @@
160
 
        ulint           mysql_process_no;/* since in Linux, 'top' reports
161
 
                                        process id's and not thread id's, we
162
 
                                        store the process number too */
163
 
+       time_t          idle_start;
164
 
+       ib_int64_t      last_stmt_start;
165
 
        /*------------------------------*/
166
 
        ulint           n_mysql_tables_in_use; /* number of Innobase tables
167
 
                                        used in the processing of the current
168
 
--- a/storage/innodb_plugin/srv/srv0srv.c
169
 
+++ b/storage/innodb_plugin/srv/srv0srv.c
170
 
@@ -86,6 +86,11 @@
171
 
 #include "trx0i_s.h"
172
 
 #include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
173
 
 
174
 
+/* prototypes of new functions added to ha_innodb.cc for kill_idle_transaction */
175
 
+ibool          innobase_thd_is_idle(const void* thd);
176
 
+ib_int64_t     innobase_thd_get_start_time(const void* thd);
177
 
+void           innobase_thd_kill(void* thd);
178
 
+
179
 
 /* prototypes for new functions added to ha_innodb.cc */
180
 
 ibool  innobase_get_slow_log();
181
 
 
182
 
@@ -100,6 +105,9 @@
183
 
 /* The following is the maximum allowed duration of a lock wait. */
184
 
 UNIV_INTERN ulint      srv_fatal_semaphore_wait_threshold = 600;
185
 
 
186
 
+/**/
187
 
+UNIV_INTERN lint       srv_kill_idle_transaction = 0;
188
 
+
189
 
 /* How much data manipulation language (DML) statements need to be delayed,
190
 
 in microseconds, in order to reduce the lagging of the purge thread. */
191
 
 UNIV_INTERN ulint      srv_dml_needed_delay = 0;
192
 
@@ -2557,6 +2565,36 @@
193
 
                old_sema = sema;
194
 
        }
195
 
 
196
 
+       if (srv_kill_idle_transaction && trx_sys) {
197
 
+               trx_t*  trx;
198
 
+               time_t  now;
199
 
+rescan_idle:
200
 
+               now = time(NULL);
201
 
+               mutex_enter(&kernel_mutex);
202
 
+               trx = UT_LIST_GET_FIRST(trx_sys->mysql_trx_list);
203
 
+               while (trx) {
204
 
+                       if (trx->conc_state == TRX_ACTIVE
205
 
+                           && trx->mysql_thd
206
 
+                           && innobase_thd_is_idle(trx->mysql_thd)) {
207
 
+                               ib_int64_t      start_time; /* as stmt ID */
208
 
+
209
 
+                               start_time = innobase_thd_get_start_time(trx->mysql_thd);
210
 
+                               if (trx->last_stmt_start != start_time) {
211
 
+                                       trx->idle_start = now;
212
 
+                                       trx->last_stmt_start = start_time;
213
 
+                               } else if (difftime(now, trx->idle_start)
214
 
+                                          > srv_kill_idle_transaction) {
215
 
+                                       /* kill the session */
216
 
+                                       mutex_exit(&kernel_mutex);
217
 
+                                       innobase_thd_kill(trx->mysql_thd);
218
 
+                                       goto rescan_idle;
219
 
+                               }
220
 
+                       }
221
 
+                       trx = UT_LIST_GET_NEXT(mysql_trx_list, trx);
222
 
+               }
223
 
+               mutex_exit(&kernel_mutex);
224
 
+       }
225
 
+
226
 
        /* Flush stderr so that a database user gets the output
227
 
        to possible MySQL error file */
228
 
 
229
 
--- a/storage/innodb_plugin/trx/trx0trx.c
230
 
+++ b/storage/innodb_plugin/trx/trx0trx.c
231
 
@@ -137,6 +137,9 @@
232
 
        trx->mysql_relay_log_file_name = "";
233
 
        trx->mysql_relay_log_pos = 0;
234
 
 
235
 
+       trx->idle_start = 0;
236
 
+       trx->last_stmt_start = 0;
237
 
+
238
 
        mutex_create(&trx->undo_mutex, SYNC_TRX_UNDO);
239
 
 
240
 
        trx->rseg = NULL;
241
 
--- /dev/null
242
 
+++ b/mysql-test/r/percona_innodb_kill_idle_trx.result
243
 
@@ -0,0 +1,41 @@
244
 
+DROP TABLE IF EXISTS t1;
245
 
+SET autocommit=0;
246
 
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
247
 
+SHOW GLOBAL VARIABLES LIKE 'innodb_kill_idle_transaction';
248
 
+Variable_name  Value
249
 
+innodb_kill_idle_transaction   0
250
 
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_kill_idle_transaction';
251
 
+VARIABLE_NAME  VARIABLE_VALUE
252
 
+INNODB_KILL_IDLE_TRANSACTION   0
253
 
+SET GLOBAL innodb_kill_idle_transaction=1;
254
 
+SHOW GLOBAL VARIABLES LIKE 'innodb_kill_idle_transaction';
255
 
+Variable_name  Value
256
 
+innodb_kill_idle_transaction   1
257
 
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_kill_idle_transaction';
258
 
+VARIABLE_NAME  VARIABLE_VALUE
259
 
+INNODB_KILL_IDLE_TRANSACTION   1
260
 
+BEGIN;
261
 
+INSERT INTO t1 VALUES (1),(2),(3);
262
 
+COMMIT;
263
 
+SELECT * FROM t1;
264
 
+a
265
 
+1
266
 
+2
267
 
+3
268
 
+BEGIN;
269
 
+INSERT INTO t1 VALUES (4),(5),(6);
270
 
+SELECT * FROM t1;
271
 
+ERROR HY000: MySQL server has gone away
272
 
+SELECT * FROM t1;
273
 
+a
274
 
+1
275
 
+2
276
 
+3
277
 
+DROP TABLE t1;
278
 
+SET GLOBAL innodb_kill_idle_transaction=0;
279
 
+SHOW GLOBAL VARIABLES LIKE 'innodb_kill_idle_transaction';
280
 
+Variable_name  Value
281
 
+innodb_kill_idle_transaction   0
282
 
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_kill_idle_transaction';
283
 
+VARIABLE_NAME  VARIABLE_VALUE
284
 
+INNODB_KILL_IDLE_TRANSACTION   0
285
 
--- /dev/null
286
 
+++ b/mysql-test/r/percona_innodb_kill_idle_trx_locks.result
287
 
@@ -0,0 +1,45 @@
288
 
+DROP TABLE IF EXISTS t1;
289
 
+SET autocommit=0;
290
 
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
291
 
+SHOW GLOBAL VARIABLES LIKE 'innodb_kill_idle_transaction';
292
 
+Variable_name  Value
293
 
+innodb_kill_idle_transaction   0
294
 
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_kill_idle_transaction';
295
 
+VARIABLE_NAME  VARIABLE_VALUE
296
 
+INNODB_KILL_IDLE_TRANSACTION   0
297
 
+SET GLOBAL innodb_kill_idle_transaction=5;
298
 
+SHOW GLOBAL VARIABLES LIKE 'innodb_kill_idle_transaction';
299
 
+Variable_name  Value
300
 
+innodb_kill_idle_transaction   5
301
 
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_kill_idle_transaction';
302
 
+VARIABLE_NAME  VARIABLE_VALUE
303
 
+INNODB_KILL_IDLE_TRANSACTION   5
304
 
+BEGIN;
305
 
+INSERT INTO t1 VALUES (1),(2),(3);
306
 
+COMMIT;
307
 
+SELECT * FROM t1;
308
 
+a
309
 
+1
310
 
+2
311
 
+3
312
 
+### Locking rows. Lock should be released when idle trx is killed.
313
 
+BEGIN;
314
 
+SELECT * FROM t1 FOR UPDATE;
315
 
+a
316
 
+1
317
 
+2
318
 
+3
319
 
+UPDATE t1 set a=4;
320
 
+SELECT * FROM t1;
321
 
+a
322
 
+4
323
 
+4
324
 
+4
325
 
+DROP TABLE t1;
326
 
+SET GLOBAL innodb_kill_idle_transaction=0;
327
 
+SHOW GLOBAL VARIABLES LIKE 'innodb_kill_idle_transaction';
328
 
+Variable_name  Value
329
 
+innodb_kill_idle_transaction   0
330
 
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_kill_idle_transaction';
331
 
+VARIABLE_NAME  VARIABLE_VALUE
332
 
+INNODB_KILL_IDLE_TRANSACTION   0
333
 
--- /dev/null
334
 
+++ b/mysql-test/t/percona_innodb_kill_idle_trx.test
335
 
@@ -0,0 +1,28 @@
336
 
+--source include/have_innodb.inc
337
 
+--disable_warnings
338
 
+DROP TABLE IF EXISTS t1; 
339
 
+--enable_warnings
340
 
+
341
 
+SET autocommit=0;
342
 
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
343
 
+
344
 
+--source include/percona_innodb_kill_idle_trx_show.inc
345
 
+SET GLOBAL innodb_kill_idle_transaction=1;
346
 
+--source include/percona_innodb_kill_idle_trx_show.inc
347
 
+
348
 
+BEGIN;
349
 
+INSERT INTO t1 VALUES (1),(2),(3);
350
 
+COMMIT;
351
 
+SELECT * FROM t1;
352
 
+
353
 
+BEGIN;
354
 
+INSERT INTO t1 VALUES (4),(5),(6);
355
 
+sleep 3;
356
 
+
357
 
+--enable_reconnect
358
 
+--error 2006 --error CR_SERVER_GONE_ERROR
359
 
+SELECT * FROM t1;
360
 
+SELECT * FROM t1;
361
 
+DROP TABLE t1;
362
 
+SET GLOBAL innodb_kill_idle_transaction=0;
363
 
+--source include/percona_innodb_kill_idle_trx_show.inc
364
 
--- /dev/null
365
 
+++ b/mysql-test/t/percona_innodb_kill_idle_trx_locks.test
366
 
@@ -0,0 +1,31 @@
367
 
+--source include/have_innodb.inc
368
 
+--disable_warnings
369
 
+DROP TABLE IF EXISTS t1;
370
 
+--enable_warnings
371
 
+
372
 
+SET autocommit=0;
373
 
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
374
 
+
375
 
+--source include/percona_innodb_kill_idle_trx_show.inc
376
 
+SET GLOBAL innodb_kill_idle_transaction=5;
377
 
+--source include/percona_innodb_kill_idle_trx_show.inc
378
 
+
379
 
+connect (conn1,localhost,root,,);
380
 
+connection conn1;
381
 
+
382
 
+BEGIN;
383
 
+INSERT INTO t1 VALUES (1),(2),(3);
384
 
+COMMIT;
385
 
+SELECT * FROM t1;
386
 
+
387
 
+--echo ### Locking rows. Lock should be released when idle trx is killed.
388
 
+BEGIN;
389
 
+SELECT * FROM t1 FOR UPDATE;
390
 
+
391
 
+connection default;
392
 
+UPDATE t1 set a=4;
393
 
+
394
 
+SELECT * FROM t1;
395
 
+DROP TABLE t1;
396
 
+SET GLOBAL innodb_kill_idle_transaction=0;
397
 
+--source include/percona_innodb_kill_idle_trx_show.inc
398
 
--- /dev/null
399
 
+++ b/mysql-test/include/percona_innodb_kill_idle_trx_show.inc
400
 
@@ -0,0 +1,2 @@
401
 
+SHOW GLOBAL VARIABLES LIKE 'innodb_kill_idle_transaction';
402
 
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_kill_idle_transaction';