mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-38019 Send ok packet to client earlier
Send ok packet earlier for SELECT queries that does not have any updates. This is done in select_send::send_eof() Axel's select benchmarks shows that this has a notable speed improvement: 1 Thread: 28% TPS speedup 8 Threads: 23% 64 Threads 6% This was meassured with t_oltp_point_select With InnoDB running the client over sockets. Other things: - Moved error reporting of LIMIT ROWS EXAMINED from handle_select() to check_limit_rows_examined(). This is to ensure that the error is reported before send_eof() is called. - Removed duplicate "Query execution was interrupted" messages for the same query. killed_for_exceeding_limit_rows_warning_given was introduced for this purpose. We cannot use 'killed' flag in killed_for_exceeding_limit_rows() to detect if we already have produced a warning as the 'killed' in this case is reset for each union. Reviewer: Sergei Golubchik <serg@mariadb.org>
This commit is contained in:
@@ -773,7 +773,6 @@ LIMIT ROWS EXAMINED 124;
|
||||
field1 field2 field3 field4 field5
|
||||
Warnings:
|
||||
Warning 1931 Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 124. The query result may be incomplete
|
||||
Warning 1931 Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 124. The query result may be incomplete
|
||||
SHOW STATUS LIKE 'Handler_read%';
|
||||
Variable_name Value
|
||||
Handler_read_first 1
|
||||
|
||||
@@ -125,15 +125,15 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re
|
||||
8 8 stage/sql/After opening tables (stage) STATEMENT 0
|
||||
9 9 stage/sql/init (stage) STATEMENT 0
|
||||
10 10 stage/sql/Optimizing (stage) STATEMENT 0
|
||||
11 11 stage/sql/Executing (stage) STATEMENT 0
|
||||
12 12 stage/sql/End of update loop (stage) STATEMENT 0
|
||||
13 14 stage/sql/Query end (stage) STATEMENT 0
|
||||
14 14 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 13
|
||||
15 15 stage/sql/closing tables (stage) STATEMENT 0
|
||||
16 16 stage/sql/Query end (stage) STATEMENT 0
|
||||
17 17 stage/sql/Starting cleanup (stage) STATEMENT 0
|
||||
18 18 stage/sql/Freeing items (stage) STATEMENT 0
|
||||
19 19 wait/io/socket/sql/client_connection send STATEMENT 0
|
||||
11 12 stage/sql/Executing (stage) STATEMENT 0
|
||||
12 12 wait/io/socket/sql/client_connection send STAGE 11
|
||||
13 13 stage/sql/End of update loop (stage) STATEMENT 0
|
||||
14 15 stage/sql/Query end (stage) STATEMENT 0
|
||||
15 15 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 14
|
||||
16 16 stage/sql/closing tables (stage) STATEMENT 0
|
||||
17 17 stage/sql/Query end (stage) STATEMENT 0
|
||||
18 18 stage/sql/Starting cleanup (stage) STATEMENT 0
|
||||
19 19 stage/sql/Freeing items (stage) STATEMENT 0
|
||||
20 21 stage/sql/Reset for next command (stage) STATEMENT 0
|
||||
21 21 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 20
|
||||
22 22 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 0
|
||||
@@ -149,15 +149,15 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re
|
||||
32 32 stage/sql/After opening tables (stage) STATEMENT 24
|
||||
33 33 stage/sql/init (stage) STATEMENT 24
|
||||
34 34 stage/sql/Optimizing (stage) STATEMENT 24
|
||||
35 35 stage/sql/Executing (stage) STATEMENT 24
|
||||
36 36 stage/sql/End of update loop (stage) STATEMENT 24
|
||||
37 38 stage/sql/Query end (stage) STATEMENT 24
|
||||
38 38 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 37
|
||||
39 39 stage/sql/closing tables (stage) STATEMENT 24
|
||||
40 40 stage/sql/Query end (stage) STATEMENT 24
|
||||
41 41 stage/sql/Starting cleanup (stage) STATEMENT 24
|
||||
42 42 stage/sql/Freeing items (stage) STATEMENT 24
|
||||
43 43 wait/io/socket/sql/client_connection send STATEMENT 24
|
||||
35 36 stage/sql/Executing (stage) STATEMENT 24
|
||||
36 36 wait/io/socket/sql/client_connection send STAGE 35
|
||||
37 37 stage/sql/End of update loop (stage) STATEMENT 24
|
||||
38 39 stage/sql/Query end (stage) STATEMENT 24
|
||||
39 39 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 38
|
||||
40 40 stage/sql/closing tables (stage) STATEMENT 24
|
||||
41 41 stage/sql/Query end (stage) STATEMENT 24
|
||||
42 42 stage/sql/Starting cleanup (stage) STATEMENT 24
|
||||
43 43 stage/sql/Freeing items (stage) STATEMENT 24
|
||||
44 45 stage/sql/Reset for next command (stage) STATEMENT 24
|
||||
45 45 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 44
|
||||
46 46 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 24
|
||||
@@ -173,15 +173,15 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re
|
||||
56 56 stage/sql/After opening tables (stage) STATEMENT 48
|
||||
57 57 stage/sql/init (stage) STATEMENT 48
|
||||
58 58 stage/sql/Optimizing (stage) STATEMENT 48
|
||||
59 59 stage/sql/Executing (stage) STATEMENT 48
|
||||
60 60 stage/sql/End of update loop (stage) STATEMENT 48
|
||||
61 62 stage/sql/Query end (stage) STATEMENT 48
|
||||
62 62 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 61
|
||||
63 63 stage/sql/closing tables (stage) STATEMENT 48
|
||||
64 64 stage/sql/Query end (stage) STATEMENT 48
|
||||
65 65 stage/sql/Starting cleanup (stage) STATEMENT 48
|
||||
66 66 stage/sql/Freeing items (stage) STATEMENT 48
|
||||
67 67 wait/io/socket/sql/client_connection send STATEMENT 48
|
||||
59 60 stage/sql/Executing (stage) STATEMENT 48
|
||||
60 60 wait/io/socket/sql/client_connection send STAGE 59
|
||||
61 61 stage/sql/End of update loop (stage) STATEMENT 48
|
||||
62 63 stage/sql/Query end (stage) STATEMENT 48
|
||||
63 63 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 62
|
||||
64 64 stage/sql/closing tables (stage) STATEMENT 48
|
||||
65 65 stage/sql/Query end (stage) STATEMENT 48
|
||||
66 66 stage/sql/Starting cleanup (stage) STATEMENT 48
|
||||
67 67 stage/sql/Freeing items (stage) STATEMENT 48
|
||||
68 69 stage/sql/Reset for next command (stage) STATEMENT 48
|
||||
69 69 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 68
|
||||
70 70 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 48
|
||||
@@ -200,15 +200,15 @@ select "With a third part to make things complete" as payload NULL NULL
|
||||
81 81 stage/sql/After opening tables (stage) STATEMENT 72
|
||||
82 82 stage/sql/init (stage) STATEMENT 72
|
||||
83 83 stage/sql/Optimizing (stage) STATEMENT 72
|
||||
84 84 stage/sql/Executing (stage) STATEMENT 72
|
||||
85 85 stage/sql/End of update loop (stage) STATEMENT 72
|
||||
86 87 stage/sql/Query end (stage) STATEMENT 72
|
||||
87 87 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 86
|
||||
88 88 stage/sql/closing tables (stage) STATEMENT 72
|
||||
89 89 stage/sql/Query end (stage) STATEMENT 72
|
||||
90 90 stage/sql/Starting cleanup (stage) STATEMENT 72
|
||||
91 92 stage/sql/Freeing items (stage) STATEMENT 72
|
||||
92 92 wait/io/socket/sql/client_connection send STAGE 91
|
||||
84 85 stage/sql/Executing (stage) STATEMENT 72
|
||||
85 85 wait/io/socket/sql/client_connection send STAGE 84
|
||||
86 86 stage/sql/End of update loop (stage) STATEMENT 72
|
||||
87 88 stage/sql/Query end (stage) STATEMENT 72
|
||||
88 88 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 87
|
||||
89 89 stage/sql/closing tables (stage) STATEMENT 72
|
||||
90 90 stage/sql/Query end (stage) STATEMENT 72
|
||||
91 91 stage/sql/Starting cleanup (stage) STATEMENT 72
|
||||
92 92 stage/sql/Freeing items (stage) STATEMENT 72
|
||||
93 110 statement/sql/select select "And this is the second part of a multi query" as payload;
|
||||
select "With a third part to make things complete" as payload NULL NULL
|
||||
94 96 stage/sql/starting (stage) STATEMENT 93
|
||||
@@ -219,15 +219,15 @@ select "With a third part to make things complete" as payload NULL NULL
|
||||
99 99 stage/sql/After opening tables (stage) STATEMENT 93
|
||||
100 100 stage/sql/init (stage) STATEMENT 93
|
||||
101 101 stage/sql/Optimizing (stage) STATEMENT 93
|
||||
102 102 stage/sql/Executing (stage) STATEMENT 93
|
||||
103 103 stage/sql/End of update loop (stage) STATEMENT 93
|
||||
104 105 stage/sql/Query end (stage) STATEMENT 93
|
||||
105 105 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 104
|
||||
106 106 stage/sql/closing tables (stage) STATEMENT 93
|
||||
107 107 stage/sql/Query end (stage) STATEMENT 93
|
||||
108 108 stage/sql/Starting cleanup (stage) STATEMENT 93
|
||||
109 110 stage/sql/Freeing items (stage) STATEMENT 93
|
||||
110 110 wait/io/socket/sql/client_connection send STAGE 109
|
||||
102 103 stage/sql/Executing (stage) STATEMENT 93
|
||||
103 103 wait/io/socket/sql/client_connection send STAGE 102
|
||||
104 104 stage/sql/End of update loop (stage) STATEMENT 93
|
||||
105 106 stage/sql/Query end (stage) STATEMENT 93
|
||||
106 106 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 105
|
||||
107 107 stage/sql/closing tables (stage) STATEMENT 93
|
||||
108 108 stage/sql/Query end (stage) STATEMENT 93
|
||||
109 109 stage/sql/Starting cleanup (stage) STATEMENT 93
|
||||
110 110 stage/sql/Freeing items (stage) STATEMENT 93
|
||||
111 129 statement/sql/select select "With a third part to make things complete" as payload NULL NULL
|
||||
112 113 stage/sql/starting (stage) STATEMENT 111
|
||||
113 113 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 112
|
||||
@@ -236,15 +236,15 @@ select "With a third part to make things complete" as payload NULL NULL
|
||||
116 116 stage/sql/After opening tables (stage) STATEMENT 111
|
||||
117 117 stage/sql/init (stage) STATEMENT 111
|
||||
118 118 stage/sql/Optimizing (stage) STATEMENT 111
|
||||
119 119 stage/sql/Executing (stage) STATEMENT 111
|
||||
120 120 stage/sql/End of update loop (stage) STATEMENT 111
|
||||
121 122 stage/sql/Query end (stage) STATEMENT 111
|
||||
122 122 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 121
|
||||
123 123 stage/sql/closing tables (stage) STATEMENT 111
|
||||
124 124 stage/sql/Query end (stage) STATEMENT 111
|
||||
125 125 stage/sql/Starting cleanup (stage) STATEMENT 111
|
||||
126 126 stage/sql/Freeing items (stage) STATEMENT 111
|
||||
127 127 wait/io/socket/sql/client_connection send STATEMENT 111
|
||||
119 120 stage/sql/Executing (stage) STATEMENT 111
|
||||
120 120 wait/io/socket/sql/client_connection send STAGE 119
|
||||
121 121 stage/sql/End of update loop (stage) STATEMENT 111
|
||||
122 123 stage/sql/Query end (stage) STATEMENT 111
|
||||
123 123 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 122
|
||||
124 124 stage/sql/closing tables (stage) STATEMENT 111
|
||||
125 125 stage/sql/Query end (stage) STATEMENT 111
|
||||
126 126 stage/sql/Starting cleanup (stage) STATEMENT 111
|
||||
127 127 stage/sql/Freeing items (stage) STATEMENT 111
|
||||
128 129 stage/sql/Reset for next command (stage) STATEMENT 111
|
||||
129 129 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 128
|
||||
130 130 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 111
|
||||
@@ -260,15 +260,15 @@ select "With a third part to make things complete" as payload NULL NULL
|
||||
140 140 stage/sql/After opening tables (stage) STATEMENT 132
|
||||
141 141 stage/sql/init (stage) STATEMENT 132
|
||||
142 142 stage/sql/Optimizing (stage) STATEMENT 132
|
||||
143 143 stage/sql/Executing (stage) STATEMENT 132
|
||||
144 144 stage/sql/End of update loop (stage) STATEMENT 132
|
||||
145 146 stage/sql/Query end (stage) STATEMENT 132
|
||||
146 146 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 145
|
||||
147 147 stage/sql/closing tables (stage) STATEMENT 132
|
||||
148 148 stage/sql/Query end (stage) STATEMENT 132
|
||||
149 149 stage/sql/Starting cleanup (stage) STATEMENT 132
|
||||
150 150 stage/sql/Freeing items (stage) STATEMENT 132
|
||||
151 151 wait/io/socket/sql/client_connection send STATEMENT 132
|
||||
143 144 stage/sql/Executing (stage) STATEMENT 132
|
||||
144 144 wait/io/socket/sql/client_connection send STAGE 143
|
||||
145 145 stage/sql/End of update loop (stage) STATEMENT 132
|
||||
146 147 stage/sql/Query end (stage) STATEMENT 132
|
||||
147 147 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 146
|
||||
148 148 stage/sql/closing tables (stage) STATEMENT 132
|
||||
149 149 stage/sql/Query end (stage) STATEMENT 132
|
||||
150 150 stage/sql/Starting cleanup (stage) STATEMENT 132
|
||||
151 151 stage/sql/Freeing items (stage) STATEMENT 132
|
||||
152 153 stage/sql/Reset for next command (stage) STATEMENT 132
|
||||
153 153 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 152
|
||||
disconnect con1;
|
||||
|
||||
@@ -580,10 +580,9 @@ void Protocol::end_statement()
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
DBUG_ENTER("Protocol::end_statement");
|
||||
DBUG_ASSERT(! thd->get_stmt_da()->is_sent());
|
||||
bool error= FALSE;
|
||||
|
||||
/* Can not be true, but do not take chances in production. */
|
||||
/* This can set in the case of early result sent by select_send::send_eof() */
|
||||
if (thd->get_stmt_da()->is_sent())
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
|
||||
@@ -884,6 +884,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
|
||||
net.reading_or_writing= 0;
|
||||
client_capabilities= 0; // minimalistic client
|
||||
system_thread= NON_SYSTEM_THREAD;
|
||||
killed_for_exceeding_limit_rows_warning_given= 0;
|
||||
shared_thd= 0;
|
||||
cleanup_done= free_connection_done= abort_on_warning= got_warning= 0;
|
||||
peer_port= 0; // For SHOW PROCESSLIST
|
||||
@@ -2358,6 +2359,32 @@ void THD::reset_killed()
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Mark query killed for exceeding limit rows
|
||||
|
||||
The current select will be aborted, but the incomplete result set will
|
||||
be sent to the user
|
||||
*/
|
||||
|
||||
void THD::killed_for_exceeding_limit_rows()
|
||||
{
|
||||
set_killed(ABORT_QUERY);
|
||||
if (!no_errors && !killed_for_exceeding_limit_rows_warning_given)
|
||||
{
|
||||
killed_for_exceeding_limit_rows_warning_given= 1;
|
||||
bool saved_abort_on_warning= abort_on_warning;
|
||||
abort_on_warning= false;
|
||||
push_warning_printf(this, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_QUERY_RESULT_INCOMPLETE,
|
||||
ER_THD(this, ER_QUERY_RESULT_INCOMPLETE),
|
||||
"LIMIT ROWS EXAMINED",
|
||||
lex->limit_rows_examined->val_uint());
|
||||
abort_on_warning= saved_abort_on_warning;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Remember the location of thread info, the structure needed for
|
||||
the structure for the net buffer
|
||||
@@ -3371,13 +3398,34 @@ int select_send::send_data(List<Item> &items)
|
||||
|
||||
bool select_send::send_eof()
|
||||
{
|
||||
/*
|
||||
/*
|
||||
Don't send EOF if we're in error condition (which implies we've already
|
||||
sent or are sending an error)
|
||||
*/
|
||||
if (unlikely(thd->is_error()))
|
||||
{
|
||||
reset_for_next_ps_execution();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
::my_eof(thd);
|
||||
|
||||
if (unlikely(thd->lex->sql_command != SQLCOM_SELECT))
|
||||
goto end; // For DELETE RETURNING
|
||||
|
||||
if (likely(!thd->transaction->stmt.is_trx_read_write()))
|
||||
{
|
||||
/*
|
||||
We are executing a readonly statement. Send the result to the
|
||||
client so that it can process the data while the server is doing
|
||||
cleanups.
|
||||
*/
|
||||
thd->push_final_warnings();
|
||||
thd->update_server_status(); // Needed for slow query status
|
||||
thd->protocol->end_statement();
|
||||
}
|
||||
|
||||
end:
|
||||
reset_for_next_ps_execution();
|
||||
return FALSE;
|
||||
}
|
||||
@@ -4679,7 +4727,6 @@ bool select_dumpvar::send_eof()
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
select_materialize_with_stats::
|
||||
create_result_table(THD *thd_arg, List<Item> *column_types,
|
||||
|
||||
@@ -3403,6 +3403,7 @@ public:
|
||||
must be reset (all items be removed from it).
|
||||
*/
|
||||
bool reset_sp_cache;
|
||||
bool killed_for_exceeding_limit_rows_warning_given;
|
||||
|
||||
/* container for handler's private per-connection data */
|
||||
Ha_data ha_data[MAX_HA];
|
||||
@@ -4010,10 +4011,11 @@ public:
|
||||
Check if the number of rows accessed by a statement exceeded
|
||||
LIMIT ROWS EXAMINED. If so, signal the query engine to stop execution.
|
||||
*/
|
||||
void killed_for_exceeding_limit_rows();
|
||||
inline void check_limit_rows_examined()
|
||||
{
|
||||
if (++accessed_rows_and_keys > lex->limit_rows_examined_cnt)
|
||||
set_killed(ABORT_QUERY);
|
||||
killed_for_exceeding_limit_rows();
|
||||
}
|
||||
|
||||
USER_CONN *user_connect;
|
||||
|
||||
@@ -655,21 +655,16 @@ bool handle_select(THD *thd, LEX *lex, select_result *result,
|
||||
if (unlikely(thd->killed == ABORT_QUERY && !thd->no_errors))
|
||||
{
|
||||
/*
|
||||
If LIMIT ROWS EXAMINED interrupted query execution, issue a warning,
|
||||
continue with normal processing and produce an incomplete query result.
|
||||
If LIMIT ROWS EXAMINED interrupted query execution
|
||||
continue with normal processing and produce an incomplete query
|
||||
result.
|
||||
A warning was generated by killed_for_exceeding_limit_rows().
|
||||
*/
|
||||
bool saved_abort_on_warning= thd->abort_on_warning;
|
||||
thd->abort_on_warning= false;
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_QUERY_RESULT_INCOMPLETE,
|
||||
ER_THD(thd, ER_QUERY_RESULT_INCOMPLETE),
|
||||
"LIMIT ROWS EXAMINED",
|
||||
thd->lex->limit_rows_examined->val_uint());
|
||||
thd->abort_on_warning= saved_abort_on_warning;
|
||||
thd->reset_killed();
|
||||
}
|
||||
/* Deactivate LIMIT ROWS EXAMINED after query execution. */
|
||||
thd->lex->deactivate_limit_rows_examined();
|
||||
thd->killed_for_exceeding_limit_rows_warning_given= 0;
|
||||
|
||||
MYSQL_SELECT_DONE((int) res, (ulong) thd->limit_found_rows);
|
||||
DBUG_RETURN(res);
|
||||
|
||||
@@ -2518,11 +2518,6 @@ bool st_select_lex_unit::exec_inner()
|
||||
Stop execution of the remaining queries in the UNIONS, and produce
|
||||
the current result.
|
||||
*/
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_QUERY_RESULT_INCOMPLETE,
|
||||
ER_THD(thd, ER_QUERY_RESULT_INCOMPLETE),
|
||||
"LIMIT ROWS EXAMINED",
|
||||
thd->lex->limit_rows_examined->val_uint());
|
||||
thd->reset_killed();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3013,11 +3013,9 @@ int ha_maria::external_lock(THD *thd, int lock_type)
|
||||
!trnman_decrement_locked_tables(trn))
|
||||
{
|
||||
/*
|
||||
OK should not have been sent to client yet (ACID).
|
||||
This is a bit excessive, ACID requires this only if there are some
|
||||
changes to commit (rollback shouldn't be tested).
|
||||
OK should not have been sent to client in case of write (ACID).
|
||||
*/
|
||||
DBUG_ASSERT(!thd->get_stmt_da()->is_sent() ||
|
||||
DBUG_ASSERT(!trn->undo_lsn || !thd->get_stmt_da()->is_sent() ||
|
||||
thd->killed);
|
||||
/*
|
||||
If autocommit, commit transaction. This can happen when open and
|
||||
|
||||
Reference in New Issue
Block a user