Kami memiliki tabel MySQL yang memiliki bidang penambahan otomatis ditetapkan sebagai INT (11). Tabel ini cukup banyak menyimpan daftar pekerjaan yang berjalan dalam suatu aplikasi. Pada saat tertentu selama masa aplikasi, tabel bisa berisi ribuan entri atau benar-benar kosong (yaitu semuanya telah selesai).
Bidang ini tidak memiliki kunci asing untuk hal lain.
Peningkatan otomatis tampaknya secara otomatis me-reset sendiri ke nol, meskipun kami tidak pernah benar-benar dapat menjebak reset.
Masalahnya menjadi jelas karena kita melihat bidang kenaikan otomatis bangun, katakanlah, 600.000 rekaman atau lebih dan kemudian beberapa saat kemudian bidang kenaikan otomatis tampaknya berjalan di 1000 rendah.
Hampir seolah-olah kenaikan otomatis me-reset sendiri jika tabel kosong.
Apakah ini mungkin dan jika ya, bagaimana cara mematikannya atau mengubah cara pengaturannya?
Jika tidak, apakah ada yang punya alasan mengapa melakukan ini?
Terima kasih!
sumber
Jawaban:
http://dev.mysql.com/doc/refman/4.1/en/innodb-auto-increment-handling.html
Karena hal ini ketika layanan (atau server) restart maka hal berikut akan terjadi:
Jadi, dalam bahasa Inggris yang sederhana, setelah layanan MySQL dimulai, tidak tahu berapa nilai kenaikan otomatis untuk tabel Anda. Jadi ketika Anda pertama kali menyisipkan baris, ia menemukan nilai maksimum bidang yang menggunakan kenaikan otomatis, menambahkan 1 ke nilai ini, dan menggunakan nilai yang dihasilkan. Jika tidak ada baris, itu akan mulai dari 1.
Ini merupakan masalah bagi kami, karena kami menggunakan tabel dan fitur penambahan otomatis mysql untuk mengelola ID dengan rapi di lingkungan multi-utas tempat pengguna diarahkan kembali ke situs pembayaran pihak ketiga. Jadi kami harus memastikan ID pihak ketiga yang didapat dan dikirim kembali kepada kami adalah unik dan akan tetap seperti itu (dan tentu saja ada kemungkinan pengguna akan membatalkan transaksi setelah mereka dialihkan).
Jadi kami membuat baris, memperoleh nilai kenaikan-otomatis yang dihasilkan, menghapus baris agar tabel tetap bersih, dan meneruskan nilai ke situs pembayaran. Apa yang akhirnya kami lakukan untuk memperbaiki masalah cara InnoDB menangani nilai-nilai AI adalah sebagai berikut:
Ini selalu membuat transactionId terbaru dihasilkan sebagai baris dalam tabel, tanpa perlu meledakkan tabel.
Semoga itu bisa membantu orang lain yang mungkin mengalami ini.
Edit (2018-04-18) :
Seperti yang disebutkan Finesse di bawah ini, kelihatannya perilaku ini telah dimodifikasi di MySQL 8.0+.
https://dev.mysql.com/worklog/task/?id=6204
Kata-kata dalam worklog itu paling buruk, namun tampaknya InnoDB di versi yang lebih baru sekarang mendukung nilai autoinc yang persisten di seluruh reboot.
-Gremio
sumber
Kami telah mengalami masalah ini dan telah menemukan bahwa ketika tabel optimal dijalankan pada tabel kosong, nilai kenaikan otomatis juga direset. Lihat laporan bug MySQL ini .
Sebagai solusinya, Anda dapat melakukan:
Alih-alih
OPTIMIZE TABLE
.Sepertinya inilah yang dilakukan MySQL secara internal (tanpa menetapkan nilai kenaikan otomatis, jelas)
sumber
Hanya bidikan dalam gelap - jika aplikasi menggunakan
TRUNCATE TABLE
untuk mengosongkan tabel saat selesai diproses, itu akan mengatur ulang bidang kenaikan-otomatis. Berikut ini adalah diskusi singkat tentang pertanyaan itu. Meskipun tautan itu menyebutkan bahwa InnoDB tidak menyetel ulang auto_increments pada trunc, itu dilaporkan sebagai bug dan diperbaiki beberapa tahun lalu.Dengan asumsi dugaan saya benar, Anda dapat mengubah dari memotong ke menghapus untuk memperbaiki masalah.
sumber
Hanya setel ulang nilai itu secara eksplisit, atau setetes / buat ulang bidang itu, atau operasi kekerasan serupa lainnya yang akan mengatur ulang penghitung auto_increment. (The TRUNCATE adalah teori yang sangat bagus.) Tampaknya tidak mungkin Anda tiba-tiba membungkus INT 32-bit ketika nilai terakhir yang Anda saksikan hanya 600k. Ini pasti tidak seharusnya direset hanya karena meja kosong. Anda juga memiliki bug mysql atau sesuatu di kode PHP Anda. Atau pria di bilik sebelah sedang mempermainkanmu.
Anda bisa melakukan debug dengan menyalakan log biner , karena akan berisi pernyataan seperti ini di seluruh:
Maka setidaknya Anda dapat melihat setiap detail dari apa yang terjadi pada tabel itu, termasuk tepat sebelum penghitung ulang.
sumber
ALTER TABLE table_name ENGINE = MyISAM
Bekerja untukku. Meja kami selalu disimpan sangat kecil, jadi tidak perlu untuk InnoDB.
sumber
InnoDB tidak menyimpan nilai kenaikan otomatis pada disk sehingga lupa ketika server MySQL dimatikan. Ketika MySQL dimulai lagi, mesin InnoDB mengembalikan nilai auto increment cara ini:
SELECT (MAX(id) + 1) AS auto_increment FROM table
. Ini adalah bug yang diperbaiki di MySQL versi 8.0.Ubah engine meja untuk memecahkan masalah:
Atau perbarui server MySQL ke versi 8.0 saat dirilis.
sumber