Skip to content

Commit 37cbb28

Browse files
committed
Exclude users from rows_read counts
This introduces a command line option, `--rows_read_exclude_users=name,name,...` that excludes specified logged-in users from counting against rows read. That excludes rows read from both Insights tracking (i.e., sending a JSON info packet) and server-wide tracking. There is an equivalent `rows-read-exclude-users = name,name,...` key supported in `my.cnf` as well. Checking a user against the exclusion list is moderately expensive -- it parses the string with a for loop and strtok -- so we only do it when creating a new Security_context object, or changing the in an existing Security_context object. That check corresponds with new logins and, for some reason, `USE` statements. The per-row hot path just checks a boolean in the Security_context object, so it's minimal added cost.
1 parent faed54e commit 37cbb28

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

sql/auth/sql_security_ctx.cc

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ void Security_context::init() {
9494
m_has_drop_policy = false;
9595
m_executed_drop_policy = false;
9696
m_registration_sandbox_mode = false;
97+
m_exclude_user_from_rows_read = false;
9798
}
9899

99100
void Security_context::logout() {
@@ -816,6 +817,8 @@ void Security_context::set_user_ptr(const char *user_arg,
816817

817818
// set new user value to m_user.
818819
m_user.set(user_arg, user_arg_length, system_charset_info);
820+
821+
recheck_exclude_rows_read();
819822
}
820823

821824
/**
@@ -838,6 +841,30 @@ void Security_context::assign_user(const char *user_arg,
838841
m_user.copy(user_arg, user_arg_length, system_charset_info);
839842
else
840843
m_user.set((const char *)nullptr, 0, system_charset_info);
844+
845+
recheck_exclude_rows_read();
846+
}
847+
848+
char *rows_read_exclude_users = nullptr;
849+
850+
void Security_context::recheck_exclude_rows_read() {
851+
printf("PIKI: recheck_exclude_rows_read: user=\"%s\"\n", m_user.ptr());
852+
853+
m_exclude_user_from_rows_read = false;
854+
if (rows_read_exclude_users) {
855+
printf("PIKI: rows_read_exclude_users=\"%s\"\n", rows_read_exclude_users);
856+
char *copy = strdup(rows_read_exclude_users);
857+
char *saveptr, *tok;
858+
for (tok=my_strtok_r(copy, ",", &saveptr); tok; tok=my_strtok_r(NULL, ",", &saveptr)) {
859+
printf("PIKI: tok=\"%s\"\n", tok);
860+
if (!strcmp(tok, m_user.ptr())) {
861+
printf("PIKI: yes, exclude them!\n");
862+
m_exclude_user_from_rows_read = true;
863+
break;
864+
}
865+
}
866+
free(copy);
867+
}
841868
}
842869

843870
/**
@@ -881,7 +908,7 @@ void Security_context::set_host_ptr(const char *host_arg,
881908
/**
882909
Setter method for member m_host.
883910
884-
Copies host_arg value to the m_host if it is not null else m_user is set
911+
Copies host_arg value to the m_host if it is not null else m_host is set
885912
to empty string.
886913
887914

sql/auth/sql_security_ctx.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class Security_context {
6262
void skip_grants(const char *user = "skip-grants user",
6363
const char *host = "skip-grants host");
6464
bool is_skip_grants_user();
65+
bool exclude_user_from_rows_read() const { return m_exclude_user_from_rows_read; }
6566

6667
/**
6768
Getter method for member m_user.
@@ -381,6 +382,9 @@ class Security_context {
381382
*/
382383
bool m_is_skip_grants_user;
383384

385+
bool m_exclude_user_from_rows_read;
386+
void recheck_exclude_rows_read();
387+
384388
bool m_executed_drop_policy;
385389
bool m_has_drop_policy;
386390
std::unique_ptr<std::function<void(Security_context *)>> m_drop_policy;

sql/sys_vars.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,13 @@ static Sys_var_charptr Sys_my_bind_addr(
10031003
READ_ONLY NON_PERSIST GLOBAL_VAR(my_bind_addr_str), CMD_LINE(REQUIRED_ARG),
10041004
IN_FS_CHARSET, DEFAULT(MY_BIND_ALL_ADDRESSES));
10051005

1006+
extern char *rows_read_exclude_users;
1007+
static Sys_var_charptr Sys_my_rows_read_exclude_users(
1008+
"rows_read_exclude_users",
1009+
"Comma-separated list of users whose queries do not increment rows_read",
1010+
READ_ONLY NON_PERSIST GLOBAL_VAR(rows_read_exclude_users), CMD_LINE(REQUIRED_ARG),
1011+
IN_FS_CHARSET, DEFAULT(nullptr));
1012+
10061013
static Sys_var_charptr Sys_admin_addr(
10071014
"admin_address",
10081015
"IP address to bind to for service connection. Address can be an IPv4"

storage/innobase/handler/ha_innodb.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10131,7 +10131,7 @@ int ha_innobase::index_read(
1013110131
if (m_prebuilt->table->is_system_table) {
1013210132
srv_stats.n_system_rows_read.add(
1013310133
thd_get_thread_id(m_prebuilt->trx->mysql_thd), 1);
10134-
} else {
10134+
} else if (!m_user_thd->security_context()->exclude_user_from_rows_read()) {
1013510135
srv_stats.n_rows_read.add(thd_get_thread_id(m_prebuilt->trx->mysql_thd),
1013610136
1);
1013710137
m_user_thd->get_stmt_da()->inc_rows_read();
@@ -10379,7 +10379,7 @@ int ha_innobase::general_fetch(
1037910379
if (m_prebuilt->table->is_system_table) {
1038010380
srv_stats.n_system_rows_read.add(
1038110381
thd_get_thread_id(m_prebuilt->trx->mysql_thd), 1);
10382-
} else {
10382+
} else if (!m_user_thd->security_context()->exclude_user_from_rows_read()) {
1038310383
srv_stats.n_rows_read.add(thd_get_thread_id(m_prebuilt->trx->mysql_thd),
1038410384
1);
1038510385
m_user_thd->get_stmt_da()->inc_rows_read();

0 commit comments

Comments
 (0)