Cara menonaktifkan kenaikan otomatis di mysql

Tebak apa? . Optimalisasi, Pencadangan, Replikasi, dan lainnya", Halaman 146-148 di bawah Subjudul Mempercepat ALTER TABLE. Halaman 147 Ayat 1 mengatakan

Teknik yang akan kami tunjukkan tidak didukung, tidak terdokumentasi, dan mungkin tidak berfungsi. Gunakan dengan risiko Anda. Kami menyarankan Anda untuk mencadangkan data Anda terlebih dahulu

Baru-baru ini kami menemukan bug yang sangat aneh yang membutuhkan waktu beberapa jam untuk kami temukan. Kami kehilangan data di salah satu tabel MySQL. Mari beri latar belakang pada keseluruhan penyiapan

Proyek

Kami memiliki dua tabel MySQL. "tindakan" dan "arsip_tindakan". Yang pertama menyimpan beberapa data sementara yang terus didorong ke, diperbarui, dan dihapus dari tabel ini. Yang kedua adalah cermin dari yang pertama. Perbedaannya adalah kami tidak menghapus apa pun dari tabel arsip. Ini adalah arsip 🙂 Saya tahu apa yang Anda pikirkan – ini dapat dirancang berbeda seperti menggunakan soft delete. Ya aku tahu. Tetapi ketika sistem sedang dibangun, kami tidak tahu bahwa kami memerlukan arsip tersebut. Itu diperkenalkan jauh kemudian dan untuk tujuan warisan kami membiarkan tabel "tindakan" awal tetap utuh. Mari kita abaikan bagian desain dan fokus pada arsitektur

Masalah

Suatu hari yang indah (atau mungkin hujan, saya tidak ingat), saat menelusuri konten tabel arsip, kami melihat bahwa kami memiliki entri duplikat. Setelah memeriksanya, kami menemukan bahwa beberapa catatan identik memiliki kunci utama yang berbeda. Ini adalah sesuatu yang seharusnya tidak pernah terjadi. Ini membawa kami pada kesimpulan bahwa sistem membuat entri baru di tabel arsip dengan ID dari catatan asli, yang sudah ada di tabel arsip. Oke, ini agak rumit, jadi izinkan saya menjelaskannya. Katakanlah tabel "actions_archive" yang tepat terlihat seperti ini


|---------------------------------------------------|
|  id_actions_archive  |  id_action   |  some_data  |
|---------------------------------------------------|
|  100                 |  150         |  foo        |
|  101                 |  151         |  bar        |
|  102                 |  152         |  baz        |
|---------------------------------------------------|

Sekarang mari kita lihat versi rusak dari tabel ini


|---------------------------------------------------|
|  id_actions_archive  |  id_action   |  some_data  |
|---------------------------------------------------|
|  100                 |  150         |  foo        |
|  101                 |  151         |  bar        |
(...)
|  332                 |  151         |  bar        |
(...)
|  637                 |  151         |  bar        |
|  638                 |  152         |  baz        |
|---------------------------------------------------|
_

Seperti yang Anda lihat di versi terakhir tabel, kami memiliki entri duplikat. Ini bahkan lebih buruk karena kami mungkin kehilangan beberapa data. Itu karena kami juga memperbarui rekaman di tabel arsip saat kami memperbarui data di tabel "tindakan" asli. Kami menggunakan kunci "id_action" untuk pembaruan, jadi ketika kami memiliki beberapa entri yang terikat dengan ID itu, semuanya diperbarui (sebenarnya – ditimpa). Itu tidak baik

Pencarian Bug

Kami mulai mencari masalah dan tidak menemukan apa pun. Itu jelas sangat membuat frustrasi. Semua sisipan dan pembaruan antipeluru sehingga tidak dapat merusak data. Kami bahkan membuat mekanisme logging yang akan mencatat momen saat duplikat dibuat. Tapi itu tidak membantu kami mendiagnosis masalahnya

Penemuan

Akhirnya, setelah banyak bertukar pikiran, mencari, membaca, dan membenturkan kepala ke dinding, kami menemukan bug tersebut. Itu bukan proyeknya – itu adalah MySQL

Masalahnya dapat diperbaiki dengan menghapus data dari tabel "tindakan". Setelah menghapus misalnya 10 catatan terakhir dari tabel dan memulai ulang MySQL, catatan baru menerima ID yang sudah ditetapkan sebelumnya

Jadi, katakanlah "id_action" terakhir adalah 500, lalu kami menghapus 100 catatan, memulai ulang MySQL dan memasukkan catatan baru ke tabel. ID record yang baru ditambahkan ternyata 401

"Tunggu apa?. Ya, itulah yang kami katakan. Itu benar-benar tak terduga dan aneh

Saya bertanya pada diri sendiri, “Apa yang terjadi?’ ‘Apa masalahnya?

Masalahnya adalah setelah memulai ulang MySQL, nilai auto_increment ditentukan untuk setiap tabel menggunakan algoritme ini (hanya berlaku untuk tabel InnoDB)


SELECT MAX(ai_col) FROM t FOR UPDATE;

Itu perilaku yang sangat aneh, setidaknya bagi saya. Hal penting seperti nilai auto_increment harus disimpan di suatu tempat. Ironisnya di sini adalah kita berbicara tentang MySQL (DB, duh. ) dan menyimpan nilai auto_increment di memori… Ketika MySQL direstart, ia mengambil entri terakhir dari tabel dan menyetel nilai auto_increment sama dengan ID dari catatan yang ditemukan +1

Dokumentasi sebenarnya menyatakan bahwa ini adalah "fitur" tetapi menurut saya, ini adalah bug utama. Anda dapat membaca selengkapnya di Manual Referensi MySQL. Mengetahui hal ini, kami dengan cepat menemukan solusi untuk masalah tersebut, tetapi tidak ada yang akan tahu berapa banyak air mata yang kami tumpahkan

Kesimpulan

Anda dapat menemukan bug yang membuat Anda ingin melompat keluar melalui jendela. Jangan menyerah dan selalu berusaha mencari solusi. Jika Anda tidak tahu asal bug, coba lakukan semua yang Anda bisa untuk melacaknya. Berjalan di sekitar bug, coba paku dengan cara lain. Kami menggunakan mekanisme logging dan bahkan jika itu tidak membantu kami secara langsung, itu menghilangkan beberapa kemungkinan lubang

Brainstorm sangat membantu. Bahkan ide yang paling tidak relevan (dan berpotensi bodoh) bisa membantu. Dengarkan setiap pendapat dan bicarakan dengan tim. Terkadang satu hal mengarah ke hal lain dan tiba-tiba Anda menemukan solusinya

Jangan sepenuhnya bergantung pada perangkat lunak pihak ketiga. PHP, MySQL, dan lainnya juga penuh dengan bug. Bahkan ketika tim pengembang mengatakan itu adalah fitur

Bagaimana cara menghapus kenaikan otomatis di tabel SQL?

ALTER TABLE `table` AUTO_INCREMENT = angka; Mengganti 'angka' dengan hasil perintah sebelumnya ditambah satu dan mengganti tabel dengan nama tabel. Jika Anda menghapus semua baris dalam tabel, Anda dapat menjalankan perintah ubah tabel dan meresetnya ke 0.

Apa itu AUTO_INCREMENT di MySQL?

Peningkatan otomatis memungkinkan nomor unik dihasilkan secara otomatis saat catatan baru dimasukkan ke dalam tabel . Seringkali ini adalah bidang kunci utama yang ingin kami buat secara otomatis setiap kali catatan baru dimasukkan.

Di mana kolom kenaikan otomatis di MySQL?

MySQL memiliki kata kunci AUTO_INCREMENT untuk melakukan peningkatan otomatis. Nilai awal untuk AUTO_INCREMENT adalah 1, yang merupakan nilai default. Itu akan mendapatkan kenaikan sebesar 1 untuk setiap rekor baru. Untuk mendapatkan id auto increment berikutnya di MySQL, kita bisa menggunakan fungsi last_insert_id() dari MySQL atau auto_increment dengan SELECT .

Bagaimana cara mereset Autoincrement?

Di MySQL, sintaks untuk mereset kolom AUTO_INCREMENT menggunakan pernyataan ALTER TABLE adalah. UBAH TABEL nama_tabel AUTO_INCREMENT = nilai; nama_tabel . Nama tabel yang kolom AUTO_INCREMENT-nya ingin Anda atur ulang .