Merge pull request #5825 from sysown/v3.0_partition-fairness

Promote longest-waiting B session via max_connect_time fold
fix/run-tests-backtick-leak
René Cannaò 3 weeks ago committed by GitHub
commit 97eab1bbf0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -66,6 +66,7 @@ public:
// Below this attempt count a tick carries no signal: gate state and
// streak are left untouched. Avoids "2/2 NULL = 100% stressed" noise.
static constexpr unsigned int PARTITION_GATE_MIN_ATTEMPTS = 4;
static constexpr unsigned int PARTITION_FAIRNESS_MIN_B = 4;
// Called by sessions inside this worker at the get_MyConn_from_pool()
// call site to feed the gate.

@ -285,16 +285,22 @@ void Base_Thread::ProcessAllSessions_Partition() {
size_t running_end = 0;
size_t idle_begin = mysql_sessions->len;
size_t idx = 0;
size_t oldest_idx = SIZE_MAX;
unsigned long long oldest_mct = UINT64_MAX;
while (idx < idle_begin) {
S* s = static_cast<S*>(mysql_sessions->index(idx));
const bool has_be = (s->mybe && s->mybe->server_myds);
const bool is_B = has_be && (s->mybe->server_myds->max_connect_time != 0);
const unsigned long long mct = has_be ? s->mybe->server_myds->max_connect_time : 0ULL;
const bool is_B = (mct != 0);
const bool is_A = !is_B && has_be && (s->mybe->server_myds->myconn != nullptr) && (s->status != WAITING_CLIENT_DATA);
if (is_A) {
if (idx != running_end) {
// Keep the tracked oldest valid: the B session at running_end is
// about to be swapped to idx.
if (oldest_idx == running_end) oldest_idx = idx;
void* p = mysql_sessions->pdata[idx];
mysql_sessions->pdata[idx] = mysql_sessions->pdata[running_end];
mysql_sessions->pdata[running_end] = p;
@ -302,6 +308,14 @@ void Base_Thread::ProcessAllSessions_Partition() {
++running_end;
++idx;
} else if (is_B) {
// Key on max_connect_time: it was already loaded for the is_B test
// above, so this is a register compare with no extra memory access.
// Smallest max_connect_time == earliest connect start == the session
// closest to the connect_timeout_server_max abort.
if (mct < oldest_mct) {
oldest_mct = mct;
oldest_idx = idx;
}
++idx;
} else {
--idle_begin;
@ -313,6 +327,16 @@ void Base_Thread::ProcessAllSessions_Partition() {
// do NOT advance idx - re-examine the swapped-in element test
}
}
// Promote the longest-waiting B session (smallest max_connect_time) to
// running_end so the CONNECTING_SERVER pass serves it first. Gated by a
// minimum B-band size to avoid churn on tiny bands.
if (idle_begin > running_end + PARTITION_FAIRNESS_MIN_B
&& oldest_idx != SIZE_MAX && oldest_idx != running_end) {
void* p = mysql_sessions->pdata[running_end];
mysql_sessions->pdata[running_end] = mysql_sessions->pdata[oldest_idx];
mysql_sessions->pdata[oldest_idx] = p;
}
}
// this function was inline in MySQL_Thread::run()

Loading…
Cancel
Save