เวิร์กโฟลว์ DDL ของทรานแซคชันสำหรับ MySQL


25

ฉันเป็นเพียงเล็กน้อยประหลาดใจที่จะพบว่างบ DDL ( alter table, create indexฯลฯ ) โดยปริยายกระทำการทำธุรกรรมในปัจจุบันใน MySQL มาจาก MS SQL Server ความสามารถในการปรับเปลี่ยนฐานข้อมูลในการทำธุรกรรมภายใน (ที่ถูกย้อนกลับ) เป็นส่วนสำคัญของเวิร์กโฟลว์ของฉัน สำหรับการรวมอย่างต่อเนื่องการย้อนกลับถูกใช้ถ้าการโยกย้าย hiccuped ด้วยเหตุผลใด ๆ ดังนั้นอย่างน้อยเราก็ไม่ได้ออกจากฐานข้อมูลในสถานะครึ่งย้าย

ผู้คนแก้ไขปัญหาทั้งสองนี้อย่างไรเมื่อใช้ MySQL กับการย้ายข้อมูลและการรวมอย่างต่อเนื่อง


ข้ามโพสต์จาก SO stackoverflow.com/q/28197013/614523ไม่ได้รับความรักมากที่นั่น
sennett

1
สำหรับการผสานอย่างต่อเนื่องให้พิจารณา LVM Snapshots เป็นวิธีการสร้างสภาพแวดล้อมทั้งหมดที่อยู่ในสถานะที่รู้จักอย่างรวดเร็ว
Rick James

5
คุณสามารถอัปเกรดเป็น Postgres ได้ตลอดเวลา - รองรับการทำธุรกรรม DDL (SCNR)
a_horse_with_no_name

3
ฉันเห็นด้วยกับ @a_horse_with_no_name ถ้านี่เป็นเวิร์กโฟลว์ของคุณให้พิจารณาการใช้ PosgreSQL อย่างจริงจังซึ่งมี DDL ของทรานแซคชันพร้อมกับคุณสมบัติที่ดีอื่น ๆ อีกมากมาย
Renzo

คำตอบ:


9

สำหรับหลาย ๆ คนส้นเท้าของ Achilles ของ MySQL นั้นกระทำโดยปริยาย

ตามหน้า 418 วรรค 3 ของหนังสือ

คู่มือการศึกษาใบรับรอง MySQL 5.0

คำสั่งต่อไปนี้สามารถและจะทำลายการทำธุรกรรม

  • ALTER TABLE
  • BEGIN
  • CREATE INDEX
  • DROP DATABASE
  • DROP INDEX
  • DROP TABLE
  • RENAME TABLE
  • TRUNCATE TABLE
  • LOCK TABLES
  • UNLOCK TABLES
  • SET AUTOCOMMIT = 1
  • START TRANSACTION

ข้อเสนอแนะ

เมื่อพูดถึง MySQL งาน ContinuousIntegration (CI) / SelfService ใด ๆ ที่คุณสร้างควรทำให้งานธุรกรรมและสคริปต์ DDL ร่วมกันโดยเฉพาะ

สิ่งนี้เปิดโอกาสให้คุณสร้างกระบวนทัศน์ที่ต้องการ

  • สนับสนุนธุรกรรมที่แยกได้อย่างเหมาะสมกับSTART TRANSACTION/COMMITบล็อก
  • ควบคุม DDL ด้วยการเขียนสคริปต์ DDL ด้วยตัวเองโดยใช้ DDL เช่น Constructor หรือ Destructor
    • ตัวสร้าง: DDL เพื่อสร้างตารางด้วยการออกแบบใหม่
    • Destructor: DDL เพื่อให้ตารางย้อนกลับไปเป็นการออกแบบก่อนหน้า
  • ไม่รวมการดำเนินการเหล่านี้ในงานเดียว

คำเตือน:หากคุณใช้ MyISAM สำหรับสิ่งนี้คุณสามารถ (ยกเลิก) กรุณาเพิ่ม MyISAM ลงในรายการสิ่งต่าง ๆ ที่สามารถทำลายการทำธุรกรรมได้อาจไม่ใช่ในแง่ของการกระทำโดยปริยาย แต่แน่นอนว่าในแง่ของความสอดคล้องของข้อมูล จำเป็น

ทำไมไม่ใช่ LVM

LVM snapshot นั้นยอดเยี่ยมและการกู้คืนอินสแตนซ์ทั้งหมดของฐานข้อมูลโดยไม่ต้องทำการประมวลผล SQL อย่างหนักเหมาะ อย่างไรก็ตามเมื่อพูดถึง MySQL คุณจะต้องคำนึงถึงสองเครื่องมือจัดเก็บข้อมูล: InnoDB และ MyISAM

ฐานข้อมูล InnoDB ทั้งหมด

ดูสถาปัตยกรรมของ InnoDB (รูปภาพที่ได้รับความอนุเคราะห์จาก Percona CTO Vadim Tkachenko)

ท่อ InnoDB

InnoDB มีชิ้นส่วนเคลื่อนไหวมากมาย

  • ตารางระบบ
    • พจนานุกรมข้อมูล
    • Double Write Buffer (รองรับความสอดคล้องของข้อมูลใช้สำหรับ Crash Recovery)
    • แทรกบัฟเฟอร์ (บัฟเฟอร์เปลี่ยนเป็นดัชนีที่ไม่ซ้ำรอง)
    • ส่วนย้อนกลับ
    • เลิกทำ Space (ซึ่งการเติบโตที่ไม่สามารถควบคุมได้มากที่สุด)
  • InnoDB Buffer Pool
    • หน้าข้อมูลสกปรก
    • หน้าดัชนีสกปรก
    • การเปลี่ยนแปลงดัชนีที่ไม่ซ้ำกัน
  • แคชหน่วยความจำที่สำคัญอื่น ๆ

การถ่ายภาพรวมของ LVM ของฐานข้อมูล allo-InnoDB ที่มีการเปลี่ยนแปลงแบบลอยตัวในบัฟเฟอร์ Buffer และหน่วยความจำแคชจะให้ชุดข้อมูลที่ต้องการการกู้คืนความเสียหายของ InnoDB เมื่อ LUN ถูกกู้คืนและ mysqld เริ่มทำงาน

คำแนะนำสำหรับ All-InnoDB

หากคุณสามารถปิดระบบ MySQL ก่อนทำการสแนปชอต

    1. วิ่ง SET GLOBAL innodb_fast_shutdown = 0;
    1. วิ่ง SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. วิ่ง SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. ทำซ้ำขั้นตอนที่ 3 จนกระทั่งInnodb_buffer_pool_pages_dirtyเป็น 0 หรือใกล้กับ 0 มากที่สุด
    1. service mysql stop
    1. ถ่ายภาพรวม LVM
    1. service mysql stop

หากคุณไม่สามารถปิดเครื่องได้ แต่ถ่ายภาพด้วย MySQL Live

    1. วิ่ง SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. วิ่ง SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. ทำซ้ำขั้นตอนที่ 2 จนกระทั่งInnodb_buffer_pool_pages_dirtyเป็น 0 หรือใกล้กับ 0 มากที่สุด
    1. ถ่ายภาพรวม LVM
    1. วิ่ง SET GLOBAL innodb_max_dirty_pages_pct = 75;

ฐานข้อมูล All-MyISAM หรือ InnoDB / MyISAM Mix

MyISAM เมื่อเข้าถึงจะรักษาจำนวนการจัดการไฟล์ที่เปิดอยู่ หาก MySQL ขัดข้องตาราง MyISAM ใด ๆ ที่มีจำนวนการจัดการไฟล์ที่เปิด> 0 จะถูกทำเครื่องหมายว่าผิดพลาดและต้องการการซ่อมแซม (แม้ว่าจะไม่มีข้อมูลใดผิด)

การถ่ายภาพสแนปชอต LVM ของฐานข้อมูลที่มีตาราง MyISAM อยู่จะมีตาราง MyISAM หนึ่งตารางขึ้นไปที่ต้องการการซ่อมแซมเมื่อสแน็ปช็อตได้รับการกู้คืนและเริ่ม mysqld

คำแนะนำสำหรับ All-MyISAM หรือ InnoDB / MyISAM Mix

หากคุณสามารถปิดระบบ MySQL ก่อนทำการสแนปชอต

    1. วิ่ง SET GLOBAL innodb_fast_shutdown = 0;
    1. วิ่ง SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. วิ่ง SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. ทำซ้ำขั้นตอนที่ 3 จนกระทั่งInnodb_buffer_pool_pages_dirtyเป็น 0 หรือใกล้กับ 0 มากที่สุด
    1. service mysql stop
    1. ถ่ายภาพรวม LVM
    1. service mysql stop

หากคุณไม่สามารถปิดเครื่องได้ แต่ถ่ายภาพด้วย MySQL Live

คุณสามารถบังคับใช้การล้างตาราง InnoDB บางรายการ

    1. วิ่ง SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. วิ่ง SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. ทำซ้ำขั้นตอนที่ 2 จนกระทั่งInnodb_buffer_pool_pages_dirtyเป็น 0 หรือใกล้กับ 0 มากที่สุด
    1. ทำงานFLUSH TABLES innodb_tbl1,... FOR EXPORT;บนตาราง InnoDB ที่สำคัญ
    1. วิ่ง FLUSH TABLES WITH READ LOCK;
    1. ถ่ายภาพรวม LVM
    1. วิ่ง UNLOCK TABLES;
    1. วิ่ง SET GLOBAL innodb_max_dirty_pages_pct = 75;

การจำลองแบบ MySQL สามารถช่วย?

ในขณะที่คุณสามารถเรียกคืนหนึ่งสแน็ปช็อต LVM ไปยังเซิร์ฟเวอร์สองเครื่องและตั้งค่า MySQL Master / Slave Replication ได้ซึ่งจะกลายเป็นแหล่งรวมของ housecleaning เพิ่มเติมเมื่อกู้คืนสแน็ปช็อต

หากคุณรันงาน CI บน Master และงานเหล่านั้นมีขนาดเล็กการจำลองแบบอาจเป็นตัวจับเวลาในบางสถานการณ์ คุณสามารถวิ่งSTOP SLAVE;บน Slave ได้เริ่มงาน CI ใน Master และทำงานSTART SLAVE;Slave เมื่อข้อมูลของ Master ได้รับการรับรอง

หากงาน CI แจ้งเตือนข้อมูลมากเกินไปคุณสามารถกู้คืนสแน็ปช็อต LVM และการจำลองแบบการติดตั้งได้ตั้งแต่เริ่มต้น หากคุณพบว่าตัวเองทำสิ่งนี้บ่อยครั้งคุณอาจทำได้ด้วยการตั้งค่าการจำลองแบบ MySQL

ความคิดสุดท้าย

  • เป็นการดีที่สุดที่จะใช้เซิร์ฟเวอร์ DB หลายตัว (3 ตัวขึ้นไป) เพื่อทำการทดสอบการคืนค่าและการถดถอย
  • แปลงตาราง MyISAM ที่เหลือเป็น InnoDB หากตารางเหล่านั้นไม่ต้องการอยู่ MyISAM
  • หากเนื้อหาข้อมูลของคุณอ่อนไหวคุณควรดำเนินการงาน CI เพื่อขัดข้อมูลหลังจากกู้คืนสแน็ปช็อตก่อนเริ่มการทดสอบใด ๆ เป็นอีกทางเลือกหนึ่งคุณอาจต้องการสแนปชอตของ MySQL ด้วยข้อมูลที่ได้รับการขัดแล้ว

4

หากคุณพูดถึงการบูรณาการอย่างต่อเนื่องฉันถือว่าเป็นสภาพแวดล้อมการพัฒนา ในกรณีนี้ฉันจะบอกว่าคนที่ทำการเปลี่ยนแปลงโครงสร้างต้องทดสอบพวกเขาเพื่อให้แน่ใจว่าจะไม่ทำสิ่งต่าง ๆ ให้ผู้อื่นเหมือนกับคนที่อัปเดตไลบรารีทั่วไป: ทดสอบในแซนด์บ็อกซ์ของคุณเองก่อนที่จะยอมรับการเปลี่ยนแปลงดังกล่าว

ในกระบวนการปรับใช้การผลิตโดยทั่วไปคุณจะต้องผ่าน dev, QA หรือแม้แต่สภาพแวดล้อมก่อนการผลิตเพื่อทดสอบการเปลี่ยนแปลงของคุณเช่นเดียวกับที่คุณทำกับการเปลี่ยนแปลงรหัสใด ๆ

โปรดทราบว่านี่ไม่ใช่ MySQL เฉพาะ: ฐานข้อมูล Oracle จะกระทำโดยปริยายเช่นกันเมื่อออก 'แก้ไขตาราง' เป็นต้น

ตอนนี้ถ้าคุณต้องการป้องกันตัวเองคุณอาจสำรองข้อมูลไว้ล่วงหน้าหรือ LVM หรือระบบไฟล์ถ้าระบบของคุณสามารถทำได้ คุณอาจมีทาสซึ่งคุณสามารถหน่วงเวลา / หยุดเพื่อความปลอดภัยก่อนการดำเนินการที่ละเอียดอ่อน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.