Bagi banyak orang, kelemahan MySQL Achilles adalah komitmen implisit.
Menurut Paragraf 3 dari Buku itu
perintah berikut dapat dan akan memecah transaksi
ALTER TABLE
BEGIN
CREATE INDEX
DROP DATABASE
DROP INDEX
DROP TABLE
RENAME TABLE
TRUNCATE TABLE
LOCK TABLES
UNLOCK TABLES
SET AUTOCOMMIT = 1
START TRANSACTION
SARAN
Ketika datang ke MySQL, setiap pekerjaan ContinuousIntegration (CI) / SelfService yang Anda buat harus selalu membuat pekerjaan Transaksional dan skrip DDL saling eksklusif.
Ini memberi Anda kesempatan untuk menciptakan paradigma yang akan
- mendukung transaksi yang diisolasi dengan benar dengan
START TRANSACTION/COMMIT
blok
- kontrol DDL dengan membuat skrip sendiri DDL, jalankan DDL seperti konstruktor atau destruktor
- Konstruktor: DDL untuk membuat Tabel dengan Desain Baru
- Destructor: DDL untuk membuat Tabel Kembalikan Kembali ke Desain Sebelumnya
- tidak pernah menggabungkan operasi ini di bawah satu pekerjaan
PERINGATAN: Jika Anda menggunakan MyISAM untuk semua ini, Anda dapat (tidak) dengan senang hati menambahkan MyISAM ke daftar hal-hal yang dapat memecah transaksi, mungkin tidak dalam hal komitmen implisit, tetapi pasti dalam hal konsistensi data seandainya kemunduran pernah terjadi. dibutuhkan.
MENGAPA TIDAK LVM?
Snapshots LVM sangat bagus dan mengembalikan seluruh instance dari database tanpa harus melakukan pemrosesan SQL yang berat sangat ideal. Namun, ketika datang ke MySQL, Anda harus memperhitungkan dua mesin penyimpanan: InnoDB dan MyISAM.
Basis Data All-InnoDB
Lihatlah Arsitektur InnoDB (Gambar milik Percona CTO Vadim Tkachenko)
InnoDB memiliki banyak bagian yang bergerak
- Tablespace Sistem
- Kamus data
- Double Write Buffer (mendukung konsistensi data; digunakan untuk Crash Recovery)
- Masukkan Buffer (Perubahan Buffer ke Indeks Non-Unik Sekunder)
- Segmen kembalikan
- Undo Space (tempat pertumbuhan paling tak terkendali bisa terjadi)
- Pool Buffer InnoDB
- Halaman Data Kotor
- Halaman Indeks Kotor
- Perubahan pada Indeks Non-Unik
- Tembolok Memori Penting Lainnya
Mengambil snapshot LVM dari database semua-InnoDB dengan perubahan yang tidak dikomit mengambang di Buffer Pool dan cache Memori akan menghasilkan dataset yang akan membutuhkan pemulihan crash InnoDB setelah LUN dipulihkan dan mysqld dimulai.
SARAN UNTUK SEMUA-InnoDB
Jika Anda Dapat Mematikan MySQL Sebelum Mengambil Foto
- Menjalankan
SET GLOBAL innodb_fast_shutdown = 0;
- Menjalankan
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Menjalankan
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Ulangi Langkah 3 hingga Innodb_buffer_pool_pages_dirty adalah 0 atau sedekat mungkin dengan 0
service mysql stop
- Ambil snapshot LVM
service mysql stop
Jika Anda Tidak Dapat Mematikan Tapi Mengambil Foto Dengan MySQL Live
- Menjalankan
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Menjalankan
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Ulangi Langkah 2 sampai Innodb_buffer_pool_pages_dirty adalah 0 atau sedekat mungkin dengan 0
- Ambil snapshot LVM
- Menjalankan
SET GLOBAL innodb_max_dirty_pages_pct = 75;
Basis Data All-MyISAM atau Campuran InnoDB / MyISAM
MyISAM, ketika diakses, mengelola hitungan pegangan file terbuka yang menentangnya. Jika MySQL lumpuh, tabel MyISAM apa pun dengan jumlah file yang dibuka menangani> 0 akan ditandai sebagai macet dan perlu diperbaiki (bahkan jika tidak ada yang salah dengan data).
Mengambil snapshot LVM dari database yang memiliki tabel MyISAM digunakan akan memiliki satu atau lebih tabel MyISAM yang perlu diperbaiki ketika snapshot dipulihkan dan mysqld dimulai.
SARAN UNTUK All-MyISAM atau InnoDB / MyISAM Mix
Jika Anda Dapat Mematikan MySQL Sebelum Mengambil Foto
- Menjalankan
SET GLOBAL innodb_fast_shutdown = 0;
- Menjalankan
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Menjalankan
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Ulangi Langkah 3 hingga Innodb_buffer_pool_pages_dirty adalah 0 atau sedekat mungkin dengan 0
service mysql stop
- Ambil snapshot LVM
service mysql stop
Jika Anda Tidak Dapat Mematikan Tapi Mengambil Foto Dengan MySQL Live
Anda bisa menerapkan pembilasan tabel InnoDB tertentu
- Menjalankan
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Menjalankan
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Ulangi Langkah 2 sampai Innodb_buffer_pool_pages_dirty adalah 0 atau sedekat mungkin dengan 0
- Jalankan
FLUSH TABLES innodb_tbl1,... FOR EXPORT;
pada tabel InnoDB kritis
- Menjalankan
FLUSH TABLES WITH READ LOCK;
- Ambil snapshot LVM
- Menjalankan
UNLOCK TABLES;
- Menjalankan
SET GLOBAL innodb_max_dirty_pages_pct = 75;
Bisakah Replikasi MySQL Membantu?
Meskipun Anda dapat mengembalikan satu snapshot LVM ke dua server dan mengatur MySQL Master / Slave Replication, itu menjadi sumber tambahan pembersihan rumah saat mengembalikan snapshot.
Jika Anda menjalankan pekerjaan CI pada Master dan pekerjaan itu kecil, replikasi bisa menjadi penghemat waktu dalam keadaan tertentu. Anda bisa menjalankan STOP SLAVE;
pada Slave, memulai pekerjaan CI pada Master, dan menjalankan START SLAVE;
pada Slave ketika data Master disertifikasi.
Jika CI pekerjaan memperingatkan terlalu banyak data, Anda dapat mengembalikan snapshot LVM dan mengatur replikasi dari awal. Jika Anda sering melakukan hal ini, Anda mungkin dapat melakukan pengaturan dengan Replikasi MySQL.
PIKIRAN FINAL
- Cara terbaik adalah menggunakan beberapa Server DB (3 atau lebih) untuk melakukan tes pemulihan dan regresi.
- Konversikan tabel MyISAM yang tersisa ke InnoDB jika tabel tersebut tidak perlu tetap menjadi MyISAM.
- Jika konten data Anda sensitif, Anda harus melakukan pekerjaan CI untuk menggosok data setelah mengembalikan snapshot sebelum memulai tes apa pun. Sebagai alternatif, Anda mungkin ingin mengambil snapshot dari MySQL dengan data yang sudah dihapus.