~ubuntu-branches/ubuntu/trusty/mysql-5.6/trusty

« back to all changes in this revision

Viewing changes to mysql-test/suite/funcs_1/datadict/processlist_val.inc

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-12 11:54:27 UTC
  • Revision ID: package-import@ubuntu.com-20140212115427-oq6tfsqxl1wuwehi
Tags: upstream-5.6.15
ImportĀ upstreamĀ versionĀ 5.6.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
########### suite/funcs_1/datadict/processlist_val.inc #########################
 
2
#                                                                              #
 
3
# Testing of values within INFORMATION_SCHEMA.PROCESSLIST                      #
 
4
#                                                                              #
 
5
# Ensure that the values fit to the current state of the connection and        #
 
6
# especially that they change if a connection does nothing or runs some SQL.   #
 
7
# runs some SQL.                                                               #
 
8
# Examples:                                                                    #
 
9
# - change the default database                                                #
 
10
# - send some period of time no SQL command to the server                      #
 
11
# - send a long running query                                                  #
 
12
#                                                                              #
 
13
# Note(mleich):                                                                #
 
14
# 1. Please inform me if this test fails because of timing problems.           #
 
15
# 2. Storage engine variants of this test do not make sense.                   #
 
16
#    -  I_S tables use the MEMORY storage engine whenever possible.            #
 
17
#    -  There are some I_S tables which need column data types which are not   #
 
18
#       supported by MEMORY. Example: LONGTEXT/BLOB                            #
 
19
#       MyISAM will be used for such tables.                                   #
 
20
#       The column PROCESSLIST.INFO is of data type LONGTEXT ----> MyISAM      #
 
21
#    -  There is no impact of the GLOBAL(server) or SESSION default storage    #
 
22
#       engine setting on the engine used for I_S tables.                      #
 
23
#       That means we cannot get NDB or InnoDB instead.                        #
 
24
# 3. The SHOW (FULL) PROCESSLIST command are for comparison.                   #
 
25
#    The main test target is INFORMATION_SCHEMA.PROCESSLIST !                  #
 
26
# 4. Attention:                                                                #
 
27
#    The values of the PROCESSLIST columns HOST and TIME tend to cause         #
 
28
#    problems and therefore their printing has to be suppressed.               #
 
29
#    Examples of the exact values:                                             #
 
30
#    HOST: 'localhost' (UNIX derivates)                                        #
 
31
#          'localhost:<varying_port>' (WINDOWS)                                #
 
32
#    TIME: In many cases within this test 0 seconds but if the testing box is  #
 
33
#          overloaded we might get up to 2 seconds.                            #
 
34
#    Solution:                                                                 #
 
35
#          --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>                      #
 
36
# 5. How to debug the script?                                                  #
 
37
#    <graphical diff tool>                          \                          #
 
38
#        suite/funcs_1/datadict/processlist_val.inc \                          #
 
39
#        <Result|Reject|Log file>                                              #
 
40
#    I tweaked a lot of the script lines around "echo" so that you will get a  #
 
41
#    lot of useful synchronisation.                                            #
 
42
#                                                                              #
 
43
# Creation:                                                                    #
 
44
# 2007-08-09 mleich Implement this test as part of                             #
 
45
#                   WL#3982 Test information_schema.processlist                #
 
46
#                                                                              #
 
47
# Last Modification:                                                           #
 
48
# 2008-07-04 mleich Fix for                                                    #
 
49
#                   Bug#37853 Test "funcs_1.processlist_val_ps" fails in       #
 
50
#                             various ways                                     #
 
51
#                       - issues with printing of port (Win only)              #
 
52
#                       - too optimistic assumptions about timing              #
 
53
#                   + corrections of logic in poll routines                    #
 
54
#                   + minor improvements                                       #
 
55
################################################################################
 
56
 
 
57
# Basic preparations
 
58
--error 0, ER_CANNOT_USER
 
59
DROP USER test_user@'localhost';
 
60
CREATE USER test_user@'localhost';
 
61
GRANT ALL ON *.* TO test_user@'localhost';
 
62
REVOKE PROCESS ON *.* FROM test_user@'localhost';
 
63
SET PASSWORD FOR test_user@'localhost' = PASSWORD('ddictpass');
 
64
--disable_warnings
 
65
DROP TABLE IF EXISTS test.t1;
 
66
--enable_warnings
 
67
CREATE TABLE test.t1 (f1 BIGINT);
 
68
USE test;
 
69
 
 
70
 
 
71
echo
 
72
# Show the definition of the PROCESSLIST table
 
73
#--------------------------------------------------------------------------
 
74
;
 
75
SHOW CREATE TABLE INFORMATION_SCHEMA.PROCESSLIST;
 
76
 
 
77
echo
 
78
# Ensure that the information about the own connection is correct.
 
79
#--------------------------------------------------------------------------
 
80
;
 
81
# Expected values
 
82
#   - USER = 'root'
 
83
#   - HOST (printed value is unified), the exact values are often like
 
84
#        UNIX: 'localhost'
 
85
#        WIN: 'localhost:<some port>'
 
86
#   - DB = 'test'
 
87
#   - Command IN (no protocol -> 'Query', ps-protocol -> 'Execute')
 
88
#   - TIME (printed value will be unified), the exact values are like
 
89
#          "normal" load: 0 (seconds)
 
90
#          "heavy" load: 1 or more (seconds)
 
91
#   - State 'executing'
 
92
#   - INFO must contain the corresponding SHOW/SELECT PROCESSLIST
 
93
#
 
94
# 1. Just dump what we get
 
95
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
 
96
--sorted_result
 
97
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
 
98
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
 
99
--sorted_result
 
100
SHOW FULL PROCESSLIST;
 
101
#
 
102
# Determine the connection id of the current connection (default)
 
103
SET @default_id = CONNECTION_ID();
 
104
#
 
105
# 2. There must be exact one connection with @default_id;
 
106
SELECT COUNT(*)  = 1 AS "Expect exact one connection with this id"
 
107
FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = @default_id;
 
108
#
 
109
# 3. Check the remaining stuff
 
110
SELECT COUNT(*)  = 1 AS "Expect 1"
 
111
FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = @default_id
 
112
     AND USER = 'root' AND DB = 'test' AND Command IN('Query','Execute')
 
113
     AND State = 'executing';
 
114
#
 
115
# 4. Change the DB
 
116
USE information_schema;
 
117
SELECT COUNT(*)  = 1 AS "Is the DB correct?"
 
118
FROM INFORMATION_SCHEMA.PROCESSLIST
 
119
WHERE ID = @default_id AND DB = 'information_schema';
 
120
#
 
121
# 5. Change the statement
 
122
let $my_statement =
 
123
SELECT @my_info := INFO FROM INFORMATION_SCHEMA.PROCESSLIST
 
124
WHERE ID = @default_id;
 
125
eval $my_statement;
 
126
eval
 
127
SELECT @my_info = '$my_statement'
 
128
    AS 'Is the content of PROCESSLIST.INFO correct?';
 
129
#
 
130
# 6. TIME must have a reasonable value
 
131
SELECT COUNT(*) = 1 AS "Has TIME a reasonable value?"
 
132
FROM INFORMATION_SCHEMA.PROCESSLIST
 
133
WHERE ID = @default_id AND 0 <= TIME < 10;
 
134
 
 
135
 
 
136
echo
 
137
# Ensure that the information about an inactive connection is correct.
 
138
#--------------------------------------------------------------------------
 
139
;
 
140
echo
 
141
# ----- establish connection con1 (user = test_user) -----
 
142
;
 
143
connect (con1,localhost,test_user,ddictpass,information_schema);
 
144
#
 
145
echo
 
146
# ----- switch to connection default (user = root) -----
 
147
;
 
148
connection default;
 
149
# We have now a second connection.
 
150
# First working phase for the new connection is with Command = 'Connect'.
 
151
# This is a very short phase and the likelihood to meet it is
 
152
# - nearly zero on average boxes with low parallel load
 
153
# - around some percent on weak or overloaded boxes
 
154
#   (Bug#32153 Status output differs - scheduling ?)
 
155
# Therefore we do not try to catch this state.
 
156
# We poll till we reach the long lasting phase with Command = 'Sleep'.
 
157
#   - USER = 'test_user'
 
158
#   - DB = 'information_schema'
 
159
#   - Command = 'Sleep'
 
160
#   - State is empty
 
161
#   - INFO IS NULL
 
162
echo
 
163
# Poll till the connection con1 is in state COMMAND = 'Sleep'.
 
164
;
 
165
let $wait_timeout= 10;
 
166
let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
 
167
                     WHERE COMMAND = 'Sleep' AND USER = 'test_user';
 
168
--source include/wait_condition.inc
 
169
# 1. Just dump what we get
 
170
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
 
171
--sorted_result
 
172
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
 
173
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
 
174
--sorted_result
 
175
SHOW FULL PROCESSLIST;
 
176
#
 
177
# Pull ID and TIME of the second connection
 
178
SELECT ID,TIME INTO @test_user_con1_id,@time FROM INFORMATION_SCHEMA.PROCESSLIST
 
179
WHERE COMMAND = 'Sleep' AND USER = 'test_user';
 
180
#
 
181
# 2. The second connection must (behaviour at least since 2007) have an
 
182
#    ID = ID_of_previous_connection + 1
 
183
SELECT @test_user_con1_id = @default_id + 1
 
184
    AS "Did we got the next higher PROCESSLIST ID?";
 
185
#
 
186
# 3. TIME must have a reasonable value
 
187
SELECT 0 <=  @time < 10 AS "Has TIME a reasonable value?";
 
188
#
 
189
# 4. HOST must be for both connections similar (varying port on Win)
 
190
SELECT COUNT(*) = 2 AS "Is HOST LIKE 'localhost%'?"
 
191
FROM INFORMATION_SCHEMA.PROCESSLIST
 
192
WHERE HOST LIKE 'localhost%';
 
193
#
 
194
# 5. Check the remaining stuff
 
195
SELECT COUNT(*)  = 1 AS "Expect 1"
 
196
FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = @test_user_con1_id
 
197
     AND USER = 'test_user' AND DB = 'information_schema'
 
198
     AND Command = 'Sleep' AND State = '' AND INFO IS NULL;
 
199
#
 
200
# 6. Check that TIME increases
 
201
let $wait_timeout= 10;
 
202
let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
 
203
                     WHERE COMMAND = 'Sleep' AND USER = 'test_user'
 
204
                       AND TIME > @time;
 
205
--source include/wait_condition.inc
 
206
 
 
207
 
 
208
echo
 
209
# Ensure that the user test_user sees only connections with his username
 
210
# because he has not the PROCESS privilege.
 
211
#----------------------------------------------------------------------------
 
212
;
 
213
echo
 
214
# ----- switch to connection con1 (user = test_user) -----
 
215
;
 
216
connection con1;
 
217
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
 
218
--sorted_result
 
219
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
 
220
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
 
221
--sorted_result
 
222
SHOW FULL PROCESSLIST;
 
223
 
 
224
 
 
225
echo
 
226
# Ensure that the user test_user sees all connections with his username.
 
227
#----------------------------------------------------------------------------
 
228
;
 
229
echo
 
230
----- establish connection con2 (user = test_user) ------
 
231
;
 
232
connect (con2,localhost,test_user,ddictpass,information_schema);
 
233
echo
 
234
# ----- switch to connection default (user = root) -----
 
235
;
 
236
connection default;
 
237
# If the testing box is under heavy load we might see within some of the
 
238
# next queries connection
 
239
# con2 with Command = 'Connect'
 
240
# con1 with INFO = 'SHOW FULL PROCESSLIST' and STATE = 'Writing to net'
 
241
# Both phases are too short to be checked.
 
242
echo
 
243
# Poll till all connections of 'test_user' are in a state with COMMAND = 'Sleep'
 
244
;
 
245
let $wait_condition= SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.PROCESSLIST
 
246
        WHERE USER = 'test_user' AND COMMAND = 'Sleep';
 
247
--source include/wait_condition.inc
 
248
echo
 
249
# ----- switch to connection con2 (user = test_user) -----
 
250
;
 
251
connection con2;
 
252
# Just dump what we get
 
253
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
 
254
--sorted_result
 
255
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
 
256
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
 
257
--sorted_result
 
258
SHOW FULL PROCESSLIST;
 
259
#
 
260
echo
 
261
# ----- switch to connection default (user = root) -----
 
262
;
 
263
connection default;
 
264
# Pull the ID of con2, we will need it later
 
265
SELECT ID INTO @test_user_con2_id FROM INFORMATION_SCHEMA.PROCESSLIST
 
266
WHERE ID <> @test_user_con1_id
 
267
  AND USER = 'test_user' AND DB = 'information_schema';
 
268
 
 
269
 
 
270
echo
 
271
# Ensure we get correct information about a connection during work
 
272
#----------------------------------------------------------------------------
 
273
;
 
274
echo
 
275
# ----- switch to connection con2 (user = test_user) -----
 
276
;
 
277
connection con2;
 
278
# "Organise" a long running command to be observed by the root user.
 
279
echo
 
280
# Send a long enough running statement to the server, but do not
 
281
# wait till the result comes back.
 
282
;
 
283
# Worst case scenario (=high I/O load on testing box):
 
284
# - My experience:
 
285
#   Up to 2 seconds runtime per SELECT ... FROM INFORMATION_SCHEMA.PROCESSLIST
 
286
#   in rare cases.
 
287
# - The following sequence contains ~ 4 of such SELECTs
 
288
# Therefore we sleep 10 seconds.
 
289
let $sleep_command =
 
290
SELECT sleep(10), 17;
 
291
send;
 
292
eval $sleep_command;
 
293
#
 
294
echo
 
295
# ----- switch to connection default (user = root) -----
 
296
;
 
297
connection default;
 
298
echo
 
299
# Poll till connection con2 is in state 'User sleep'.
 
300
;
 
301
# Expect to see within the processlist the other connection just during
 
302
# statement execution.
 
303
#   - USER = 'test_user'
 
304
#   - DB = 'information_schema'
 
305
#   - Command = 'Query'(run without --ps-protocol)/'Execute' (run --ps-protocol)
 
306
#   - TIME >= 0
 
307
#   - State = 'User sleep'
 
308
#   - INFO = $sleep_command
 
309
let $wait_condition=
 
310
SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST
 
311
WHERE ID = @test_user_con2_id AND Command IN('Query','Execute')
 
312
  AND State = 'User sleep' AND INFO IS NOT NULL ;
 
313
--source include/wait_condition.inc
 
314
# 1. Just dump what we get
 
315
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
 
316
--sorted_result
 
317
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
 
318
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
 
319
--sorted_result
 
320
SHOW FULL PROCESSLIST;
 
321
#
 
322
# Pull some information about the connection con2
 
323
SELECT STATE, TIME, INFO INTO @state, @time, @info
 
324
FROM INFORMATION_SCHEMA.PROCESSLIST
 
325
WHERE ID = @test_user_con2_id;
 
326
# 2. TIME must have a reasonable value
 
327
SELECT 0 <= @time < 10 AS "Has TIME a reasonable value?";
 
328
# 3. STATE must be 'User sleep'
 
329
SELECT @state = 'User sleep' AS "Has STATE the expected value?";
 
330
# 4. INFO must fit
 
331
eval SELECT @info = '$sleep_command' AS "Has INFO the expected value?";
 
332
# 5. Check that TIME increases
 
333
let $wait_timeout= 10;
 
334
let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
 
335
    WHERE ID = @test_user_con2_id AND INFO IS NOT NULL AND TIME > @time;
 
336
--source include/wait_condition.inc
 
337
echo
 
338
# ----- switch to connection con2 (user = testuser) -----
 
339
;
 
340
connection con2;
 
341
echo
 
342
# Pull("reap") the result set from the statement executed with "send".
 
343
;
 
344
reap;
 
345
echo
 
346
# ----- switch to connection default (user = root) -----
 
347
;
 
348
connection default;
 
349
echo
 
350
# Poll till all connections of 'test_user' are in a state with COMMAND = 'Sleep'
 
351
;
 
352
let $wait_timeout= 10;
 
353
let $wait_condition= SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.PROCESSLIST
 
354
                     WHERE COMMAND = 'Sleep' AND USER = 'test_user';
 
355
--source include/wait_condition.inc
 
356
 
 
357
 
 
358
echo
 
359
# Ensure that we see that a connection "hangs" when colliding with a
 
360
# WRITE TABLE LOCK
 
361
#----------------------------------------------------------------------------
 
362
;
 
363
LOCK TABLE test.t1 WRITE;
 
364
#
 
365
echo
 
366
# ----- switch to connection con2 (user = test_user) -----
 
367
;
 
368
connection con2;
 
369
echo
 
370
# Send a statement to the server, but do not wait till the result
 
371
# comes back. We will pull this later.
 
372
;
 
373
send
 
374
SELECT COUNT(*) FROM test.t1;
 
375
echo
 
376
# ----- switch to connection default (user = root) -----
 
377
;
 
378
connection default;
 
379
echo
 
380
# Poll till INFO is no more NULL and State = 'Waiting for table metadata lock'.
 
381
;
 
382
let $wait_condition= SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST
 
383
        WHERE INFO IS NOT NULL AND STATE = 'Waiting for table metadata lock';
 
384
--source include/wait_condition.inc
 
385
#
 
386
# Expect to see the state 'Waiting for table metadata lock' for the third
 
387
# connection because the SELECT collides with the WRITE TABLE LOCK.
 
388
--replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME>
 
389
--sorted_result
 
390
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
 
391
UNLOCK TABLES;
 
392
#
 
393
echo
 
394
# ----- switch to connection con2 (user = test_user) -----
 
395
;
 
396
connection con2;
 
397
echo
 
398
# Pull("reap") the result set from the statement executed with "send".
 
399
;
 
400
reap;
 
401
 
 
402
 
 
403
echo
 
404
# Ensure that SHOW/SELECT processlist can handle extreme long commands
 
405
#----------------------------------------------------------------------------
 
406
;
 
407
# We do not want to waste runtime, therefore we run the following test based
 
408
# on "Lock collision" and not with some "sleep(10)".
 
409
echo
 
410
# ----- switch to connection default (user = root) -----
 
411
;
 
412
connection default;
 
413
LOCK TABLE test.t1 WRITE;
 
414
#
 
415
echo
 
416
# ----- switch to connection con2 (user = test_user) -----
 
417
;
 
418
connection con2;
 
419
echo
 
420
# Send a long (~20 KB code) statement to the server, but do not wait
 
421
# till the result comes back. We will pull this later.
 
422
;
 
423
let $string=
 
424
`SELECT CONCAT('BEGIN-',
 
425
        REPEAT('This is the representative of a very long statement.',400),
 
426
        '-END')`;
 
427
let $my_statement =
 
428
SELECT count(*),'$string' AS "Long string" FROM test.t1;
 
429
send;
 
430
eval $my_statement;
 
431
echo
 
432
# ----- switch to connection default (user = root) -----
 
433
;
 
434
connection default;
 
435
echo
 
436
# Poll till INFO is no more NULL and State = 'Waiting for table metadata lock'.
 
437
;
 
438
let $wait_condition= SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST
 
439
        WHERE INFO IS NOT NULL AND STATE = 'Waiting for table metadata lock';
 
440
--source include/wait_condition.inc
 
441
echo
 
442
# Expect result:
 
443
# Statement                                      Content of INFO
 
444
# SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST   Complete statement
 
445
# SHOW FULL PROCESSLIST                          Complete statement
 
446
# SHOW PROCESSLIST                               statement truncated after 100 char
 
447
;
 
448
--replace_column 1 <ID> 3 <HOST_NAME> 5 <COMMAND> 6 <TIME> 7 <STATE>
 
449
--sorted_result
 
450
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
 
451
--replace_column 1 <ID> 3 <HOST_NAME> 5 <COMMAND> 6 <TIME> 7 <STATE>
 
452
--sorted_result
 
453
SHOW FULL PROCESSLIST;
 
454
--replace_column 1 <ID> 3 <HOST_NAME> 5 <COMMAND> 6 <TIME> 7 <STATE>
 
455
--sorted_result
 
456
SHOW PROCESSLIST;
 
457
UNLOCK TABLES;
 
458
echo
 
459
# ----- switch to connection con2 (user = test_user) -----
 
460
;
 
461
connection con2;
 
462
echo
 
463
# Pull("reap") the result set from the monster statement executed with "send".
 
464
;
 
465
reap;
 
466
 
 
467
 
 
468
# Cleanup
 
469
echo
 
470
# ----- switch to connection default (user = root) -----
 
471
;
 
472
connection default;
 
473
echo
 
474
----- disconnect con1 and con2 -----
 
475
;
 
476
disconnect con1;
 
477
disconnect con2;
 
478
DROP USER test_user@'localhost';
 
479
DROP TABLE test.t1;