phpBB3 引發的 MySQL slow query (2) -- 修改方案

網路與網站相關議題和知識
回覆文章
dtchang
Site Admin
文章: 143
註冊時間: 2017-01-22, 16:54

phpBB3 引發的 MySQL slow query (2) -- 修改方案

文章 dtchang » 2025-08-06, 20:32

修改 phpbb/sessions.php
修改 function session_create($user_id = false, $set_admin = false, $persist_login = false, $viewonline = true)

在function session_create(...)其後加入清理和重整的機制,放在開頭處容易識別
若使用 OPTIMIZE 或 ALTER 等相關指令會有卡住的風險,運行慢一點,無妨.

代碼: 選擇全部

		// +++ InnoDB 優化清理 +++
		$sql = 'SELECT COUNT(session_id) AS sessions
				FROM ' . SESSIONS_TABLE . '
				WHERE session_time >= ' . ($this->time_now - 60);
		$result = $db->sql_query($sql);
		$row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);	
		$life_sessions = $row ? (int)$row['sessions'] : 0; //合理連線數
		$multi_sessions = 5; //合理連線數保留的倍數
		$max_sessions = 10000; // 清理的閾值
    
    // 使用快速估算方法
	// 替代 information_schema 的輕量計數
	$result = $db->sql_query("SELECT COUNT(*) AS session_count FROM ".SESSIONS_TABLE);
	$row = $db->sql_fetchrow($result);
	$session_count = $row ? (int)$row['session_count'] : 0;

    //超過預設閾值且超過保留數量的匿名資料
	if ($session_count > $max_sessions and $session_count > $life_sessions * $multi_sessions) {
        // 保留30分鐘 (不可以使用 now() 要使用 $this->time_now 以計算時間)
		$cutoff = $this->time_now - 1800;
		$batch  = 5000;   // 每批刪除上限
		$total  = 0;

do {
    // 可選:把本連線的鎖等待時間壓低,避免卡太久
    $db->sql_query('SET SESSION innodb_lock_wait_timeout = 3');

    $sql = 'DELETE FROM ' . SESSIONS_TABLE . '
            WHERE session_user_id = ' . (int) ANONYMOUS . '
              AND session_time <= ' . (int) $cutoff . '
             LIMIT ' . (int) $batch;

    $db->sql_query($sql);
    $affected = $db->sql_affectedrows();
    $total   += $affected;
	
   // 每批删除后暂停
    if ($affected > 0) 
        usleep(100000); // 100ms 暂停
	
} while ($affected === $batch);
// 分批刪除結束
		
    }
    // --- 優化結束 ---
成效需要驗證.
目前終於把無效的匿名 session 減至 20,000 以下.
註: 去掉 ORDER BY session_time 以加速運行
(待修)

回覆文章