Tombol DISABLE MySqlDump tidak berpengaruh pada impor

10

Saya memiliki tindak lanjut atas pertanyaan saya sebelumnya mengenai kecepatan impor dengan Inno-Tables (kejutan!).

Skenario
Saya mencoba mengimpor beberapa dump database * besar di mesin dev lokal saya dalam waktu yang wajar. Kami memiliki banyak KEYlampiran pada tabel yang ternyata menjadi hambatan tetapi masih penting untuk sistem live kami.

Pendekatan saya setelah mengajukan pertanyaan di atas adalah menghapus KEY ...pernyataan dari dump, import, dan menambahkan kembali kunci.

Namun saya sering menemukan diri saya mengedit dump saat ini untuk mengimpor secara lokal dan saya menemukan "komentar" lucu ini (The disable/enable keys-lines)

--
-- Dumping data for table `monster`
--

LOCK TABLES `monster` WRITE;
/*!40000 ALTER TABLE `monster` DISABLE KEYS */;
INSERT  INSERT  INSERT
/*!40000 ALTER TABLE `monster` ENABLE KEYS */;
UNLOCK TABLES;

Tetapi sebenarnya "komentar" ini adalah Pernyataan MySql bersyarat

Itu adalah berita baru bagi saya, tetapi baiklah, mengingat bentuk outputnya, mysql --versionsemuanya tampak baik bagi saya: mysql Ver 14.14 Distrib 5.5.38, for debian-linux-gnu (x86_64) using readline 6.3

Apa yang saya asumsikan
Meja terkunci (baik, hanya saya di dev mashine). Kemudian kunci sebagaimana didefinisikan dalam skema tabel dinonaktifkan, data diimpor, kunci diaktifkan.
Jadi selama "penyisipan data" -fase seharusnya tidak ada waktu yang terbuang pada kunci melainkan diperiksa setelah semua data dimasukkan.

Saya akan berpikir ini adalah perilaku yang sama seperti jika saya menghapus semua- KEY 'foo' (foo)'baris dari dump, impor dump dan jalankan skrip dengan ADD KEY 'foo' ...setelahnya.

Apa yang saya amati.
Ini adalah cara yang lebih cepat untuk secara manual menghapus kunci, mengimpor dan menambahkan kembali kunci kemudian mengandalkan DISABLE KEYSpernyataan bersyarat yang dibuat sayamysqldump

Pengeditan manual dump + impor mysql + menambahkan kunci = 15 + 8 + 8 ≈ 30 mnt
Impor mysql polos: menyerah, (Saya baru saja dibayar untuk 8 jam / hari> :))

Mau tidak mau saya berpikir saya kehilangan sesuatu yang sangat mendasar di sini (atau database mengganggu saya).

nuala
sumber
2
Jangka pendek: gunakan mysqldump --innodb-optimize-keysdari Percona percona.com/doc/percona-server/5.5/management/... Jangka panjang: berhenti menggunakan mysqldump dan gunakan mydumper atau xtrabackup.
jynus

Jawaban:

12

Anda tidak dapat mengandalkan DISABLE KEYS;dan ENABLE KEYS;untuk InnoDB karena tidak diterapkan di InnoDB Storage Engine. Berjalan ALTER TABLE ... DISABLE KEYS;dan ALTER TABLE ... ENABLE KEYS;dirancang untuk MyISAM. Seperti yang tertulis di Dokumentasi MySQL untukALTER TABLE :

Jika Anda menggunakan ALTER TABLE pada tabel MyISAM, semua indeks tidak unik dibuat dalam batch terpisah (seperti untuk REPAIR TABLE). Ini akan membuat ALTER TABLE lebih cepat ketika Anda memiliki banyak indeks.

Untuk tabel MyISAM, pembaruan kunci dapat dikontrol secara eksplisit. Gunakan ALTER TABLE ... DISABLE KEYS untuk memberi tahu MySQL agar berhenti memperbarui indeks nonunique. Kemudian gunakan ALTER TABLE ... ENABLE KEYS untuk membuat kembali indeks yang hilang. MyISAM melakukan ini dengan algoritma khusus yang jauh lebih cepat daripada memasukkan kunci satu per satu, sehingga menonaktifkan kunci sebelum melakukan operasi memasukkan massal harus memberikan peningkatan yang cukup besar. Menggunakan ALTER TABLE ... DISABLE KUNCI membutuhkan hak istimewa INDEX di samping hak istimewa yang disebutkan sebelumnya.

Sementara indeks nonunique dinonaktifkan, mereka diabaikan untuk pernyataan seperti SELECT dan EXPLAIN yang sebaliknya akan menggunakannya.

Tidak disebutkan tentang InnoDB dalam konteks dengan ALTER TABLE ... DISABLE/ENABLE KEYS;

Bahkan jika Anda menjalankan ALTER TABLE ... DISABLE KEYS;terhadap tabel InnoDB, itu menghasilkan peringatan:

mysql> show create table mytimes\G
*************************** 1. row ***************************
       Table: mytimes
Create Table: CREATE TABLE `mytimes` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `totalTime` int(11) NOT NULL,
  `totalTimeDesc` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> alter table mytimes disable keys;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> show warnings;
+-------+------+-------------------------------------------------------------+
| Level | Code | Message                                                     |
+-------+------+-------------------------------------------------------------+
| Note  | 1031 | Table storage engine for 'mytimes' doesn't have this option |
+-------+------+-------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

Itu sebabnya tidak ada pengaruhnya. Harap ingat bahwa @ jynus menyebutkan hal yang sama dalam jawabannya di bulletpoint 7 .

Perlu diingat juga bahwa MyISAM menyimpan data dan indeks dalam dua file terpisah (.MYD untuk data, .MYI untuk indeks), sehingga sepele untuk menonaktifkan dan mengaktifkan indeks. InnoDB menyimpan KUNCI UTAMA dan data baris di halaman InnoDB yang sama (melalui Indeks Clustered). Indeks sekunder akan membawa KUNCI UTAMA sebagai lampiran untuk setiap entri daun indeks sekunder . Karena data dan indeks terjalin melalui Clustered Index, belum ada yang mencoba untuk mengimplementasikan DISABLE KEYSdan ENABLE KEYSdalam InnoDB.

RolandoMySQLDBA
sumber
1
"Sudah kubilang" :-)
jynus
@ jynus HA HA :-). Anda harus memposting komentar mysqldump Anda untuk InnoDB ( dba.stackexchange.com/questions/76565/… ) sebagai jawaban.
RolandoMySQLDBA
@Yoshi Saya menulis artikel berdasarkan pertanyaan awal Anda, tetap disini.
jynus
@yosi Seperti yang dijanjikan: dbahire.com/...
jynus
@RolandoMySQLDBA, Jika InnoDB tidak dapat mengaktifkan / menonaktifkan kunci, apakah itu tidak memberikan kesalahan alih-alih peringatan semata?
Pacerier