Mysql

MySQL 如何決定將哪些分區載入到記憶體中?

  • February 17, 2017

我有一個 MySQL 索引不適合記憶體的伺服器(2TB 總索引,機器上 512GB RAM),我想知道 MySQL 如何決定將哪些部分放入記憶體,哪些不放入。

相關表在 ID 上進行了範圍分區,並且我被告知(但找不到任何證明這一點)過去 3 個月在記憶體中可用。

我希望在某個地方有更實質性的答案。

InnoDB 的“buffer_pool”包含以(大致)“最近最少使用”順序保存在那裡的*塊。*也就是說,當您觸摸一個塊進行讀取或寫入時,它會被拉入 buffer_pool 並標記為“最近使用”。如果這個塊沒有空間,那麼“最近最少使用”的塊首先從 buffer_pool 中刪除。

PARTITIONing與記憶體方案無關。特別是,分區PRIMARY KEY幾乎總是無用的,並且幾乎總是讓記憶體(如上所述)發生冗餘。

如果您想討論性能改進,請提供SHOW CREATE TABLE和慢查詢。

UsingPARTITION BY RANGE(TO_DAYS(...))是對分區的一種很好的使用,但這僅僅是因為它使得刪除“舊”數據非常有效。注意:我沒有說BY RANGE(id)

即使數學是正確的,您也可能會將“最近 3 個月”記憶體在 RAM 中,也可能沒有 - 如果有人掃描 4 個月前的東西,則必須碰撞一些塊才能進行掃描。然後 4 個月大的 bllcks 將把 buffer_pool 弄得一團糟,直到它們被撞出。

更新

由於您有一個必須始終接受寫入的“關鍵任務”系統,並且沒有PRIMARY KEY,您需要採取一些激烈的行動。這就是我要做的。

我會備份到程式碼中。如果“使用者”和數據庫之間還沒有程式碼,我會從建構這樣一個層開始,並強制“使用者”呼叫一個 API,上面寫著“寫……到數據庫”。

首先,API 將簡單地執行INSERT與原始程式碼類似的操作。這影響很小。

然後我會準備新程式碼,其中 API 背後有更複雜的程式碼。特別是,它將寫入現有表新表(使用PRIMARY KEY、新索引、更改的數據類型PARTITIONing等)。

同時,另一個腳本會以塊的形式將現有數據從現有表複製到新表。(這是其中的一部分pt-online-schema-change,但我們會採取一些自由。)

我建議塊大小為 1000 行,每個塊作為它自己的“事務”(假設您是使用 InnoDB)。分塊應該遵循一些索引,以接近唯一的為準。(是/否列會很差,因為您不能獲得超過 2 個塊。)

全部完成後,您將擁有兩個數據副本;您可以在刪除舊表之前進行測試。

由於舊表保持不變,因此讀取可以在此過程中保持不變。

一些有提示的部落格:

引用自:https://dba.stackexchange.com/questions/164386