Skip to content

Commit 0851194

Browse files
committed
Merge branch 'mysql-8.0' into mysql-trunk
Change-Id: I80167b568559852474a01e98ef368423d1c319fd
2 parents 491059a + 1dec2d2 commit 0851194

11 files changed

+87
-22
lines changed

sql/sql_error.cc

+8-2
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ Diagnostics_area::Diagnostics_area(bool allow_unlimited_conditions)
352352
memset(m_current_statement_cond_count_by_qb, 0,
353353
sizeof(m_current_statement_cond_count_by_qb));
354354
m_message_text[0] = '\0';
355+
m_message_text_length = 0;
355356
}
356357

357358
Diagnostics_area::~Diagnostics_area() {}
@@ -362,6 +363,7 @@ void Diagnostics_area::reset_diagnostics_area() {
362363
set_overwrite_status(false);
363364
// Don't take chances in production.
364365
m_message_text[0] = '\0';
366+
m_message_text_length = 0;
365367
m_mysql_errno = 0;
366368
m_affected_rows = 0;
367369
m_last_insert_id = 0;
@@ -386,10 +388,13 @@ void Diagnostics_area::set_ok_status(ulonglong affected_rows,
386388
m_last_statement_cond_count = current_statement_cond_count();
387389
m_affected_rows = affected_rows;
388390
m_last_insert_id = last_insert_id;
389-
if (message_text)
391+
if (message_text) {
390392
strmake(m_message_text, message_text, sizeof(m_message_text) - 1);
391-
else
393+
m_message_text_length = strlen(m_message_text);
394+
} else {
392395
m_message_text[0] = '\0';
396+
m_message_text_length = 0;
397+
}
393398
m_status = DA_OK;
394399
}
395400

@@ -448,6 +453,7 @@ void Diagnostics_area::set_error_status(uint mysql_errno,
448453
memcpy(m_returned_sqlstate, returned_sqlstate, SQLSTATE_LENGTH);
449454
m_returned_sqlstate[SQLSTATE_LENGTH] = '\0';
450455
strmake(m_message_text, message_text, sizeof(m_message_text) - 1);
456+
m_message_text_length = strlen(m_message_text);
451457

452458
m_status = DA_ERROR;
453459
}

sql/sql_error.h

+10
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,11 @@ class Diagnostics_area {
377377
return m_message_text;
378378
}
379379

380+
uint message_text_length() const {
381+
assert(m_status == DA_ERROR || m_status == DA_OK);
382+
return m_message_text_length;
383+
}
384+
380385
uint mysql_errno() const {
381386
assert(m_status == DA_ERROR);
382387
return m_mysql_errno;
@@ -624,6 +629,11 @@ class Diagnostics_area {
624629
*/
625630
char m_message_text[MYSQL_ERRMSG_SIZE];
626631

632+
/**
633+
Length, in bytes, of m_message_text.
634+
*/
635+
uint m_message_text_length;
636+
627637
/**
628638
SQL RETURNED_SQLSTATE condition item.
629639
This member is always NUL terminated.

storage/perfschema/mysql_server_telemetry_traces_service_imp.cc

+6-6
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ bool server_telemetry_traces_service_initialized = false;
199199
#endif /* HAVE_PSI_SERVER_TELEMETRY_TRACES_INTERFACE */
200200

201201
// currently registered collection of telemetry trace callbacks
202-
std::atomic<telemetry_t *> g_telemetry = nullptr;
202+
PFS_ALIGNED PFS_cacheline_atomic_ptr<telemetry_t *> g_telemetry;
203203

204204
// locking for callback register/unregister
205205
mysql_mutex_t LOCK_pfs_tracing_callback;
@@ -213,7 +213,7 @@ static PSI_mutex_info info_LOCK_pfs_tracing_callback = {
213213

214214
void initialize_mysql_server_telemetry_traces_service() {
215215
#ifdef HAVE_PSI_SERVER_TELEMETRY_TRACES_INTERFACE
216-
g_telemetry = nullptr;
216+
g_telemetry.m_ptr = nullptr;
217217

218218
assert(!server_telemetry_traces_service_initialized);
219219

@@ -231,7 +231,7 @@ void cleanup_mysql_server_telemetry_traces_service() {
231231
mysql_mutex_destroy(&LOCK_pfs_tracing_callback);
232232
server_telemetry_traces_service_initialized = false;
233233
}
234-
g_telemetry = nullptr;
234+
g_telemetry.m_ptr = nullptr;
235235
#endif /* HAVE_PSI_SERVER_TELEMETRY_TRACES_INTERFACE */
236236
}
237237

@@ -254,7 +254,7 @@ bool impl_register_telemetry(telemetry_t *telemetry [[maybe_unused]]) {
254254
// telemetry available, if we would need to uninstall previous component using
255255
// this before installing new one
256256
mysql_mutex_lock(&LOCK_pfs_tracing_callback);
257-
g_telemetry = telemetry;
257+
g_telemetry.m_ptr = telemetry;
258258
mysql_mutex_unlock(&LOCK_pfs_tracing_callback);
259259
// Success
260260
return false;
@@ -268,8 +268,8 @@ bool impl_unregister_telemetry(telemetry_t *telemetry [[maybe_unused]]) {
268268
#ifdef HAVE_PSI_SERVER_TELEMETRY_TRACES_INTERFACE
269269
if (!server_telemetry_traces_service_initialized) return true;
270270
mysql_mutex_lock(&LOCK_pfs_tracing_callback);
271-
if (g_telemetry == telemetry) {
272-
g_telemetry = nullptr;
271+
if (g_telemetry.m_ptr == telemetry) {
272+
g_telemetry.m_ptr = nullptr;
273273
mysql_mutex_unlock(&LOCK_pfs_tracing_callback);
274274
// Success
275275
return false;

storage/perfschema/mysql_server_telemetry_traces_service_imp.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include <mysql/components/services/mysql_server_telemetry_traces_service.h>
2727
#include <mysql/plugin.h>
2828

29+
#include "pfs_global.h"
30+
2931
/**
3032
@file storage/perfschema/mysql_server_telemetry_traces_service_imp.h
3133
The performance schema implementation of server telemetry traces service.
@@ -45,7 +47,7 @@ bool impl_unregister_telemetry(telemetry_t *telemetry);
4547

4648
extern mysql_mutex_t LOCK_pfs_tracing_callback;
4749
#ifdef HAVE_PSI_SERVER_TELEMETRY_TRACES_INTERFACE
48-
extern std::atomic<telemetry_t *> g_telemetry;
50+
extern PFS_cacheline_atomic_ptr<telemetry_t *> g_telemetry;
4951
#endif /* HAVE_PSI_SERVER_TELEMETRY_TRACES_INTERFACE */
5052

5153
#endif /* MYSQL_SERVER_TELEMETRY_TRACES_SERVICE_IMP_H */

storage/perfschema/pfs.cc

+20-6
Original file line numberDiff line numberDiff line change
@@ -3681,14 +3681,14 @@ void pfs_detect_telemetry_vc(PSI_thread *thread [[maybe_unused]]) {
36813681
assert(pfs_thread != nullptr);
36823682

36833683
// Dirty read
3684-
telemetry_t *actual_telemetry = g_telemetry.load();
3684+
telemetry_t *actual_telemetry = g_telemetry.m_ptr.load();
36853685

36863686
telemetry_t *expected_telemetry = pfs_thread->m_telemetry;
36873687

36883688
if (actual_telemetry != expected_telemetry) {
36893689
server_telemetry_tracing_lock();
36903690
// Safe read
3691-
actual_telemetry = g_telemetry.load();
3691+
actual_telemetry = g_telemetry.m_ptr.load();
36923692
if (actual_telemetry != expected_telemetry) {
36933693
if (expected_telemetry == nullptr) {
36943694
pfs_thread->m_telemetry = actual_telemetry;
@@ -6617,6 +6617,7 @@ void pfs_start_statement_vc(PSI_statement_locker *locker, const char *db,
66176617
pfs->m_sqltext_cs_number = system_charset_info->number; /* default */
66186618

66196619
pfs->m_message_text[0] = '\0';
6620+
pfs->m_message_text_length = 0;
66206621
pfs->m_sql_errno = 0;
66216622
pfs->m_sqlstate[0] = '\0';
66226623
pfs->m_error_count = 0;
@@ -6966,15 +6967,22 @@ void pfs_end_statement_vc(PSI_statement_locker *locker, void *stmt_da) {
69666967
reinterpret_cast<PFS_events_statements *>(state->m_statement);
69676968
assert(pfs != nullptr);
69686969

6970+
size_t message_text_length;
69696971
pfs_dirty_state dirty_state;
69706972
thread->m_stmt_lock.allocated_to_dirty(&dirty_state);
69716973

69726974
switch (da->status()) {
69736975
case Diagnostics_area::DA_EMPTY:
69746976
break;
69756977
case Diagnostics_area::DA_OK:
6976-
memcpy(pfs->m_message_text, da->message_text(), MYSQL_ERRMSG_SIZE);
6977-
pfs->m_message_text[MYSQL_ERRMSG_SIZE] = 0;
6978+
message_text_length = da->message_text_length();
6979+
if (message_text_length > 0) {
6980+
memcpy(pfs->m_message_text, da->message_text(),
6981+
message_text_length);
6982+
}
6983+
pfs->m_message_text[message_text_length] = '\0';
6984+
pfs->m_message_text_length = message_text_length;
6985+
69786986
pfs->m_rows_affected = da->affected_rows();
69796987
pfs->m_warning_count = da->last_statement_cond_count();
69806988
memcpy(pfs->m_sqlstate, "00000", SQLSTATE_LENGTH);
@@ -6983,8 +6991,14 @@ void pfs_end_statement_vc(PSI_statement_locker *locker, void *stmt_da) {
69836991
pfs->m_warning_count = da->last_statement_cond_count();
69846992
break;
69856993
case Diagnostics_area::DA_ERROR:
6986-
memcpy(pfs->m_message_text, da->message_text(), MYSQL_ERRMSG_SIZE);
6987-
pfs->m_message_text[MYSQL_ERRMSG_SIZE] = 0;
6994+
message_text_length = da->message_text_length();
6995+
if (message_text_length > 0) {
6996+
memcpy(pfs->m_message_text, da->message_text(),
6997+
message_text_length);
6998+
}
6999+
pfs->m_message_text[message_text_length] = '\0';
7000+
pfs->m_message_text_length = message_text_length;
7001+
69887002
pfs->m_sql_errno = da->mysql_errno();
69897003
memcpy(pfs->m_sqlstate, da->returned_sqlstate(), SQLSTATE_LENGTH);
69907004
pfs->m_error_count++;

storage/perfschema/pfs_events_statements.cc

+10-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ void cleanup_events_statements_history_long() {
158158

159159
static inline void copy_events_statements(PFS_events_statements *dest,
160160
const PFS_events_statements *source) {
161-
/* Copy all attributes except SQL TEXT and DIGEST */
161+
/* Copy all attributes except SQL TEXT, DIGEST and MESSAGE_TEXT */
162162
dest->PFS_events::operator=(*source);
163163
memcpy(&dest->m_statement_id, &source->m_statement_id,
164164
pointer_cast<const char *>(&source->m_sqltext) -
@@ -176,6 +176,15 @@ static inline void copy_events_statements(PFS_events_statements *dest,
176176

177177
/* Copy DIGEST */
178178
dest->m_digest_storage.copy(&source->m_digest_storage);
179+
180+
/* Copy MESSAGE_TEXT */
181+
const uint message_text_length = source->m_message_text_length;
182+
183+
if (message_text_length > 0) {
184+
memcpy(dest->m_message_text, source->m_message_text, message_text_length);
185+
}
186+
dest->m_message_text[message_text_length] = '\0';
187+
dest->m_message_text_length = message_text_length;
179188
}
180189

181190
/**

storage/perfschema/pfs_events_statements.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ struct PFS_events_statements : public PFS_events {
6363
/** Locked time. */
6464
ulonglong m_lock_time;
6565

66-
/** Diagnostics area, message text. */
67-
char m_message_text[MYSQL_ERRMSG_SIZE + 1];
6866
/** Diagnostics area, error number. */
6967
uint m_sql_errno;
7068
/** Diagnostics area, @c SQLSTATE. */
@@ -144,6 +142,14 @@ struct PFS_events_statements : public PFS_events {
144142
and always point to pre allocated memory.
145143
*/
146144
sql_digest_storage m_digest_storage;
145+
146+
/**
147+
Length of @c m_message_text.
148+
This is placed __before__ m_message_text[], for data locality.
149+
*/
150+
uint m_message_text_length;
151+
/** Diagnostics area, message text. */
152+
char m_message_text[MYSQL_ERRMSG_SIZE + 1];
147153
};
148154

149155
void insert_events_statements_history(PFS_thread *thread,

storage/perfschema/pfs_global.h

+12
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,18 @@ struct PFS_cacheline_atomic_size_t {
102102
PFS_cacheline_atomic_size_t() : m_size_t(0) {}
103103
};
104104

105+
/**
106+
An atomic<T> variable, guaranteed to be alone in a CPU cache line.
107+
This is for performance, for variables accessed very frequently.
108+
*/
109+
template <class T>
110+
struct PFS_cacheline_atomic_ptr {
111+
std::atomic<T> m_ptr;
112+
char m_full_cache_line[PFS_CACHE_LINE_SIZE - sizeof(std::atomic<T>)];
113+
114+
PFS_cacheline_atomic_ptr() : m_ptr(nullptr) {}
115+
};
116+
105117
struct PFS_builtin_memory_class;
106118

107119
/** Memory allocation for the performance schema. */

storage/perfschema/table_events_statements.cc

+8-3
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,13 @@ int table_events_statements_common::make_row_part_1(
342342
m_row.m_source, sizeof(m_row.m_source),
343343
m_row.m_source_length);
344344

345-
memcpy(m_row.m_message_text, statement->m_message_text,
346-
sizeof(m_row.m_message_text));
345+
m_row.m_message_text_length = statement->m_message_text_length;
346+
if (m_row.m_message_text_length > 0) {
347+
memcpy(m_row.m_message_text, statement->m_message_text,
348+
m_row.m_message_text_length);
349+
}
350+
m_row.m_message_text[m_row.m_message_text_length] = '\0';
351+
347352
memcpy(m_row.m_sqlstate, statement->m_sqlstate, SQLSTATE_LENGTH);
348353

349354
m_row.m_sql_errno = statement->m_sql_errno;
@@ -532,7 +537,7 @@ int table_events_statements_common::read_row_values(TABLE *table,
532537
}
533538
break;
534539
case 19: /* MESSAGE_TEXT */
535-
len = (uint)strlen(m_row.m_message_text);
540+
len = m_row.m_message_text_length;
536541
if (len) {
537542
set_field_varchar_utf8mb4(f, m_row.m_message_text, len);
538543
} else {

storage/perfschema/table_events_statements.h

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ struct row_events_statements {
116116

117117
/** Column MESSAGE_TEXT. */
118118
char m_message_text[MYSQL_ERRMSG_SIZE + 1];
119+
uint m_message_text_length;
119120
/** Column MYSQL_ERRNO. */
120121
uint m_sql_errno;
121122
/** Column RETURNED_SQLSTATE. */

storage/perfschema/unittest/stub_server_telemetry.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ SERVICE_TYPE(mysql_server_telemetry_traces_v1)
3333
SERVICE_IMPLEMENTATION(performance_schema, mysql_server_telemetry_traces_v1){
3434
nullptr, nullptr, nullptr};
3535

36-
std::atomic<telemetry_t *> g_telemetry = nullptr;
36+
PFS_cacheline_atomic_ptr<telemetry_t *> g_telemetry;

0 commit comments

Comments
 (0)