Mysql

MySQL自動增量欄位自行重置

  • April 18, 2018

我們有一個 MySQL 表,它的自動遞增欄位設置為 INT (11)。該表幾乎儲存了在應用程序中執行的作業列表。在應用程序生命週期的任何給定時刻,該表很可能包含數千個條目或完全為空(即一切都已完成)。

該欄位與其他任何內容都沒有外鍵。

自動增量似乎將自身隨機重置為零,儘管我們實際上從未能夠擷取重置。

問題變得很明顯,因為我們看到自動增量欄位達到了 600,000 條左右的記錄,然後過了一會兒,自動增量欄位似乎在低 1000 條記錄中執行。

如果表為空,就好像自動增量會自行重置一樣。

這可能嗎?如果是,我該如何關閉它或更改它的重置方式?

如果不是,是否有人解釋它為什麼會這樣做?

謝謝!

自增計數器僅儲存在主記憶體儲器中,而不儲存在磁碟上。

http://dev.mysql.com/doc/refman/4.1/en/innodb-auto-increment-handling.html

因此,當服務(或伺服器)重新啟動時,將發生以下情況:

在伺服器啟動後,對於第一次插入表 t,InnoDB 執行與此語句等效的語句:SELECT MAX(ai_col) FROM t FOR UPDATE;

InnoDB 將語句檢索到的值加一,並將其分配給列和表的自動增量計數器。如果表為空,則 InnoDB 使用值 1。

所以用簡單的英語來說,在 MySQL 服務啟動後,它不知道你的表的自動增量值應該是多少。所以當你第一次插入一行時,它會找到使用自動增量的欄位的最大值,將這個值加 1,然後使用結果值。如果沒有行,它將從 1 開始。

這對我們來說是個問題,因為我們使用 table 和 mysql 的自動增量功能在多執行緒環境中巧妙地管理 ID,使用者被重定向到第三方支付站點。所以我們必須確保第三方獲得併發送回給我們的 ID 是唯一的,並且會保持這種狀態(當然,使用者可能會在重定向後取消交易)。

所以我們正在創建一行,獲取生成的自動增量值,刪除該行以保持表清潔,並將該值轉發到支付站點。我們最終解決 InnoDB 處理 AI 值的方式的問題如下:

$query = "INSERT INTO transactions_counter () VALUES ();";
mysql_query($query);
$transactionId = mysql_insert_id();
$previousId = $transactionId - 1;
$query = "DELETE FROM transactions_counter WHERE transactionId='$previousId';";
mysql_query($query); 

這始終將生成的最新 transactionId 保留為表中的一行,而不會不必要地炸毀表。

希望對可能遇到此問題的其他人有所幫助。

編輯(2018-04-18)

正如下面提到的 Finesse,它的行為似乎在 MySQL 8.0+ 中已被修改。

https://dev.mysql.com/worklog/task/?id=6204

該工作日誌中的措辭充其量是錯誤的,但是在那些較新版本中的 InnoDB 現在支持跨重啟的持久 autoinc 值。

-公會

引用自:https://serverfault.com/questions/228690