在 MYSQL 5.7 中插入單行需要 15 秒(偶爾會發生)
至少,我在 MYSQL 中看到非常零星的慢查詢,這就是 Datadog 所暗示的問題所在。例如,在過去 48 小時內,我有 726K 跟踪(包括選擇和更新)中有 5 個查詢很慢。它似乎與磁碟延遲的峰值和/或 CPU 被盜有關(但是,盒子上有足夠的備用容量)。我很困惑,我不確定從哪裡開始嘗試尋找修復(或者即使它值得嘗試)
這是 15 秒 COMMIT 的範例。它正在對錶進行一次插入
visitors
。該表有約 500 萬行和以下結構:CREATE TABLE `visitors` ( `id` int(11) NOT NULL AUTO_INCREMENT, `session_id` varchar(255) DEFAULT NULL, `market_code` varchar(255) DEFAULT NULL, `user_id` int(11) DEFAULT NULL, `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_visitors_on_session_id` (`session_id`) ) ENGINE=InnoDB AUTO_INCREMENT=41764933 DEFAULT CHARSET=utf8;
在這個特定範例中,是否可能正在更新索引並導致這種極端峰值?奇怪的是,這些緩慢的更新通常是“集群”(同時會有 4 或 5 個事務到不同的表,這些事務同時很慢)事實上,對於上面過去 48 小時內 5 個慢查詢的範例,它們一切都發生在一秒鐘之內。
歡迎任何關於可能導致這種情況的建議。
下面的慢跡(輪廓)
較慢的“COMMIT”和“BEGIN”用於兩個不同的表,它們都包裝了一個更新由主鍵索引的單行的事務。
更新 1 - 回答查詢
- 我在日誌中看到的 iops 或批量傳輸沒有峰值。磁碟延遲和 cpu.iowait 出現峰值(見附件)
2. 我確實啟用了慢查詢日誌。它是巨大的,因為它記錄了太多並且很長時間沒有被清除。我可能需要重新設置它才能很好地使用它——我會調查的。3. 我無權訪問主機,但在 VM 上 Datadog 確實報告了
stolen
cpu,這肯定是 ~ nil(它報告了上個月被盜 cpu < .01%)。
sync_binlog
提供者確實建議更改和 的值innodb_flush_log_at_trx_commit
。我實際上已經設置innodb_flush_log_at_trx_commit=2
好了(如果發生崩潰,我們可以失去幾秒鐘甚至幾分鐘的數據)。我還沒有嘗試改變sync_binlog=0
,我需要更多地了解這一點。我想知道這是否有幫助?更新 2 - 9 個月的磁碟延遲圖表。
我認為這張過去 9 個月的磁碟延遲圖表很有趣。3 月 13 日左右,我們的託管服務提供商 (linode) 環境中的某處似乎發生了一些變化。也許是一個吵鬧的鄰居,也許他們的儲存方式發生了變化。我正在與他們跟進此事,希望它可以解決我們一直看到的問題。雖然該圖只顯示了約 3 毫秒的峰值,但潛在的峰值要高得多。
更新 3 - Wilson Hauck 的值
SELECT @@innodb_file_per_table; = 1
SELECT @@innodb_io_capacity; = 200
- 顯示全域狀態,如“%flush%”;
- 正常執行時間 - 138437
在周末,我嘗試將其更改
sync_binlog
為零。我似乎仍然在那裡得到一些奇怪的慢查詢。例如,在慢查詢日誌中,我看到了這個:SET timestamp=1595871703; SHOW /*!50000 ENGINE*/ INNODB STATUS; # Time: 2020-07-27T17:41:43.145667Z # # Query_time: 2.138283 Lock_time: 0.000169 Rows_sent: 1 Rows_examined: 1 SET timestamp=1595871703; SELECT `public_codes`.* FROM `public_codes` WHERE `public_codes`.`code` = 'fwreh7x1' LIMIT 1;
再次對應於延遲的峰值。為什麼這樣的查詢時間是 2 秒?
更新 5
所以,我重置了慢查詢日誌。從那以後發生了一件有趣的事情.. datadog例如報告執行 4.43 秒
UPDATE documents SET last_browse_path = ? WHERE documents . id = ?
(更新主鍵引用的單個非索引列)。但是,我沒有看到慢查詢日誌中列出的內容,我想我應該看到。可能 Datadog 給出了一些虛假的結果?更新 6 - 顯示創建表結果
請注意,這裡只有 240 萬行,儘管自動增量是這樣說的。很長一段時間,我們的增量值都是 10。
CREATE TABLE `public_codes` ( `id` int(11) NOT NULL AUTO_INCREMENT, `document_id` int(11) NOT NULL, `code` varchar(255) DEFAULT NULL, `enabled` tinyint(1) DEFAULT '0', `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, `collaborative_editing` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `index_public_codes_on_document_id` (`document_id`), UNIQUE KEY `index_public_codes_on_public_code` (`code`) ) ENGINE=InnoDB AUTO_INCREMENT=17148900 DEFAULT CHARSET=utf8
更新 7。
供應商正要關閉票並問“還有什麼要補充的嗎?”,所以我說問題仍然存在,以及在 3 月 12 日發生了一些變化但我仍然不知道這很奇怪什麼。當時他們說我們已在 3 月 12 日實時遷移到新的(共享)主機。他們給我們發了郵件,不幸的是我們沒有監控收件箱。
我正在等待將數據庫盒遷移到專用主機,因為我懷疑這是一個嘈雜的鄰居問題。一旦我完成了遷移(希望在一兩個星期內),然後我會在此更新票證,假設它解決了問題。
很生氣他們沒有告訴我我第一次問起 3 月 12 日的事.. 仍然,只是希望這能解決問題。
它似乎與磁碟延遲的峰值相關
將有 4 或 5 個事務到不同的表,同時速度很慢
磁碟吞吐量(批量傳輸還是 IOP?)是否也出現了峰值?如果是這樣,那麼它可能只是 IO 爭用的突然過剩。檢查是否有一些令人討厭的查詢正在執行,這些查詢正在掃描大型表/索引或併發臨時增加(即您當時看到使用者活動增加?和/或周圍是否有計劃的維護工作?)
都包裝交易
這裡可能存在鎖定問題,您的更新正在等待其他對受影響的行/頁/表持有讀鎖的事務。這些等待可能一直發生,但僅由於我上一段中的一種可能性而引起注意,或者如果由持有相關鎖的單個(或少量)長時間執行的語句引起,則可能是其本身的問題。
如果您還沒有啟用慢查詢日誌(mariadb、IIRC it 和 mysql 的文件在這方面沒有區別),因為如果在出現明顯問題的同時出現重大問題,這可能會提供進一步的線索。
被盜 CPU
這表示您正在虛擬機中執行,因此如果您在內部找不到充分的理由,可能會有很多額外的外部原因導致性能暫時下降。您是否有權訪問主機以檢查其日誌/指標,還是只有此客人?
建議為您的 my.ini 考慮
$$ mysqld $$部分
innodb-io-capacity=1900 # from 200 to allow higher IOPS for your SSD device
考慮在您的 public_codes 表上執行 ANALYZE 以確保索引是最新的。
我懷疑緩慢的查詢與某種形式的刷新活動發生衝突,導致它需要 2 秒。