MXS-2794: Log changes in loaded users
By checking whether the users have changed whenever they are reloaded, we improve the visibility of the user reloading process. Using a checksum allows us to easily compress the information with acceptable loss of accuracy. Using a CAS loop prevents duplicate messages without losing any updates even if multiple user reloads result in different outcomes.
This commit is contained in:
parent
e36c7efa25
commit
cb4e43b05a
@ -1143,6 +1143,42 @@ bool query_and_process_users(const char* query, MYSQL* con, SERVICE* service, in
|
||||
return rval;
|
||||
}
|
||||
|
||||
void log_loaded_users(MYSQL_AUTH* instance, SERVICE* service, Listener* port, SERVER* srv,
|
||||
const std::vector<User>& userlist, const std::vector<std::string>& dblist)
|
||||
{
|
||||
uint64_t c = crc32(0, 0, 0);
|
||||
|
||||
for (const auto& user : userlist)
|
||||
{
|
||||
c = crc32(c, (uint8_t*)user.user.c_str(), user.user.length());
|
||||
c = crc32(c, (uint8_t*)user.host.c_str(), user.host.length());
|
||||
c = crc32(c, (uint8_t*)user.db.c_str(), user.db.length());
|
||||
uint8_t anydb = user.anydb;
|
||||
c = crc32(c, &anydb, sizeof(anydb));
|
||||
c = crc32(c, (uint8_t*)user.pw.c_str(), user.pw.length());
|
||||
}
|
||||
|
||||
for (const auto& db : dblist)
|
||||
{
|
||||
c = crc32(c, (uint8_t*)db.c_str(), db.length());
|
||||
}
|
||||
|
||||
uint64_t old_c = instance->checksum;
|
||||
|
||||
while (old_c != c)
|
||||
{
|
||||
if (mxb::atomic::compare_exchange(&instance->checksum, &old_c, c,
|
||||
mxb::atomic::RELAXED, mxb::atomic::RELAXED))
|
||||
{
|
||||
MXS_NOTICE("[%s] Loaded %lu MySQL users for listener '%s' from server '%s' with checksum 0x%0lx.",
|
||||
service->name(), userlist.size(), port->name(), srv->name(), c);
|
||||
break;
|
||||
}
|
||||
|
||||
old_c = instance->checksum;
|
||||
}
|
||||
}
|
||||
|
||||
int get_users_from_server(MYSQL* con, SERVER* server, SERVICE* service, Listener* listener)
|
||||
{
|
||||
auto server_version = server->version();
|
||||
@ -1216,6 +1252,8 @@ int get_users_from_server(MYSQL* con, SERVER* server, SERVICE* service, Listener
|
||||
|
||||
if (rv)
|
||||
{
|
||||
log_loaded_users(instance, service, listener, server, userlist, dblist);
|
||||
|
||||
auto func = [instance, userlist, dblist]() {
|
||||
sqlite3* handle = get_handle(instance);
|
||||
|
||||
|
@ -192,6 +192,7 @@ static void* mysql_auth_init(char** options)
|
||||
instance->skip_auth = false;
|
||||
instance->check_permissions = true;
|
||||
instance->lower_case_table_names = false;
|
||||
instance->checksum = 0;
|
||||
|
||||
for (int i = 0; options[i]; i++)
|
||||
{
|
||||
@ -820,12 +821,6 @@ static int mysql_auth_load_users(Listener* port)
|
||||
" will probably fail as a result.",
|
||||
service->name());
|
||||
}
|
||||
else if (loaded > 0 && first_load)
|
||||
{
|
||||
mxb_assert(srv);
|
||||
MXS_NOTICE("[%s] Loaded %d MySQL users for listener %s from server %s.",
|
||||
service->name(), loaded, port->name(), srv->name());
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -112,6 +112,7 @@ typedef struct mysql_auth
|
||||
bool skip_auth; /**< Authentication will always be successful */
|
||||
bool check_permissions;
|
||||
bool lower_case_table_names; /**< Disable database case-sensitivity */
|
||||
uint64_t checksum;
|
||||
} MYSQL_AUTH;
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user