Alur kerja DDL transaksional untuk MySQL

25

Saya sedikit terkejut menemukan bahwa pernyataan DDL ( alter table, create indexdll) secara implisit melakukan transaksi saat ini di MySQL. Berasal dari MS SQL Server, kemampuan untuk melakukan perubahan basis data dalam transaksi secara lokal (yang kemudian dibatalkan) adalah bagian penting dari alur kerja saya. Untuk integrasi berkelanjutan, rollback digunakan jika migrasi terhenti karena alasan apa pun, sehingga setidaknya kami tidak meninggalkan database dalam keadaan setengah migrasi.

Bagaimana orang memecahkan dua masalah ini saat menggunakan MySQL dengan migrasi dan integrasi berkesinambungan?

sennett
sumber
Cross diposting dari SO. stackoverflow.com/q/28197013/614523 Tidak mendapatkan banyak cinta di sana.
sennett
1
Untuk Integrasi Berkelanjutan, pertimbangkan LVM Snapshots sebagai cara yang sangat cepat menciptakan seluruh lingkungan yang dalam kondisi yang diketahui.
Rick James
5
Anda selalu dapat meningkatkan ke Postgres - ini mendukung transaksional DDL (SCNR).
a_horse_with_no_name
3
Saya setuju dengan @a_horse_with_no_name, jika ini adalah alur kerja Anda, pertimbangkan dengan serius penggunaan PosgreSQL, yang memiliki DDL transaksional bersama dengan banyak fitur bagus lainnya.
Renzo

Jawaban:

9

Bagi banyak orang, kelemahan MySQL Achilles adalah komitmen implisit.

Menurut Paragraf 3 dari Buku itu

Panduan Studi Sertifikasi MySQL 5.0

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/COMMITblok
  • 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)

Pipa InnoDB

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

    1. Menjalankan SET GLOBAL innodb_fast_shutdown = 0;
    1. Menjalankan SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. Menjalankan SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Ulangi Langkah 3 hingga Innodb_buffer_pool_pages_dirty adalah 0 atau sedekat mungkin dengan 0
    1. service mysql stop
    1. Ambil snapshot LVM
    1. service mysql stop

Jika Anda Tidak Dapat Mematikan Tapi Mengambil Foto Dengan MySQL Live

    1. Menjalankan SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. Menjalankan SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Ulangi Langkah 2 sampai Innodb_buffer_pool_pages_dirty adalah 0 atau sedekat mungkin dengan 0
    1. Ambil snapshot LVM
    1. 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

    1. Menjalankan SET GLOBAL innodb_fast_shutdown = 0;
    1. Menjalankan SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. Menjalankan SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Ulangi Langkah 3 hingga Innodb_buffer_pool_pages_dirty adalah 0 atau sedekat mungkin dengan 0
    1. service mysql stop
    1. Ambil snapshot LVM
    1. service mysql stop

Jika Anda Tidak Dapat Mematikan Tapi Mengambil Foto Dengan MySQL Live

Anda bisa menerapkan pembilasan tabel InnoDB tertentu

    1. Menjalankan SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. Menjalankan SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Ulangi Langkah 2 sampai Innodb_buffer_pool_pages_dirty adalah 0 atau sedekat mungkin dengan 0
    1. Jalankan FLUSH TABLES innodb_tbl1,... FOR EXPORT;pada tabel InnoDB kritis
    1. Menjalankan FLUSH TABLES WITH READ LOCK;
    1. Ambil snapshot LVM
    1. Menjalankan UNLOCK TABLES;
    1. 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.
RolandoMySQLDBA
sumber
4

Jika Anda berbicara tentang integrasi berkelanjutan maka saya menganggap itu adalah lingkungan pengembangan. Dalam hal ini saya akan mengatakan orang yang melakukan perubahan struktural harus mengujinya untuk memastikan tidak merusak barang-barang untuk orang lain, seperti halnya seseorang memperbarui perpustakaan umum: Uji di kotak pasir Anda sendiri sebelum melakukan perubahan tersebut.

Dalam proses penyebaran produksi, Anda biasanya akan melalui lingkungan dev, QA atau bahkan pra-produksi untuk menguji perubahan Anda, sama seperti yang Anda lakukan untuk setiap perubahan kode.

Perhatikan bahwa ini bukan spesifik MySQL: Database Oracle juga secara implisit akan melakukan COMMIT ketika mengeluarkan 'alter table' dll.

Sekarang jika Anda ingin melindungi diri sendiri, Anda tentu saja dapat melakukan backup sebelumnya, atau snapshot LVM atau filesystem jika sistem Anda dapat melakukannya. Anda juga mungkin memiliki budak yang bisa Anda tunda / hentikan sebagai keamanan sebelum operasi yang sensitif.

phil_w
sumber