แนวทางปฏิบัติที่ดีที่สุดสำหรับการเปลี่ยนสคีมาและการย้ายข้อมูลไปยังฐานข้อมูลสดโดยไม่ต้องหยุดทำงาน


43

คุณทำการเปลี่ยนแปลง schema กับฐานข้อมูลจริงโดยไม่ต้องหยุดทำงานได้อย่างไร

ตัวอย่างเช่นสมมติว่าฉันมีฐานข้อมูล PostgreSQL พร้อมตารางรวมถึงข้อมูลผู้ใช้ที่หลากหลายเช่นที่อยู่อีเมล ฯลฯ ทั้งหมดที่เกี่ยวข้องกับผู้ใช้เฉพาะ หากฉันต้องการย้ายที่อยู่อีเมลไปยังตารางเฉพาะใหม่ฉันต้องเปลี่ยนสคีมาแล้วย้ายข้อมูลอีเมลไปยังตารางใหม่ วิธีนี้สามารถทำได้โดยไม่หยุดเขียนไปยังตารางต้นฉบับ? แน่นอนว่าในขณะที่ข้อมูลถูกเขียนทับจากตารางเก่าไปยังตารางใหม่ข้อมูลใหม่จะถูกเขียนลงในตารางเดิมต่อไปและจะพลาดใช่ไหม

ฉันเดาว่าปัญหานี้เกิดขึ้นค่อนข้างบ่อย แต่ฉันไม่สามารถหาวิธีแก้ปัญหามาตรฐานใด ๆ สำหรับจัดการกับมัน

บทความนี้เกี่ยวกับปัญหา แต่ฉันไม่เข้าใจขั้นตอนที่ 3 เขาบอกว่าเขียนไปยังทั้งสองตารางจากนั้นย้ายข้อมูลเก่าจากตารางแรกไปยังตารางใหม่ คุณแน่ใจได้อย่างไรว่าคุณเพียงแค่ย้ายข้อมูลเก่าเท่านั้น

(ฉันใช้PostgreSQL กับ Heroku )


2
Facebook พัฒนาเครื่องมือสำหรับทำ MySQL
Nick Chammas

2
เคสกอตต์อัลเลนเขียนเกี่ยวกับระบบการจัดการรุ่นสคีมาที่นี่ ฉันสร้าง DbUpdater ซึ่งเป็นเครื่องมือโอเพนซอร์ซสำหรับการปรับใช้สกีมาที่ตระหนักถึงเวอร์ชัน เพิ่มเติมได้ที่นี่ - http://www.tewari.info/dbupdater
เถ้า

@NickChammas ขอบคุณสำหรับการแบ่งปัน ฉันมีคำถามมากมาย คุณช่วยแนะนำการสอนรายละเอียดเพิ่มเติมวิดีโอที่ดีกว่าซึ่งจะอธิบายสิ่งต่าง ๆ เช่นบันทึกบิตดัชนีที่ไม่ทำคลัสเตอร์และตอบคำถามเช่น - 1. การเลือกข้อมูลจากตารางต้นฉบับลงในไฟล์ outfile ลดภาระเมื่อเทียบกับการคัดลอกไปยังปลายทาง ตารางโดยตรง 2. ขั้นตอนการคัดลอกจะสิ้นสุดเมื่อใด นี่เป็นเพียงคำถามสองสามข้อที่ฉันมีและฉันเพิ่งเริ่มอ่าน
Sandeepan Nath

@SandeepanNath - ขออภัยฉันไม่คุ้นเคยกับเครื่องมือของ Facebook และไม่สามารถชี้นำคุณไปยังแหล่งข้อมูลเพิ่มเติมได้ ฉันอ่านประกาศเกี่ยวกับเรื่องนี้และโพสต์ความคิดเห็นของฉันเมื่อหลายปีก่อน แต่ฉันไม่เคยใช้มันเลย
Nick Chammas

คำตอบ:


27

คุณมีคำตอบอยู่แล้ว:

  1. สร้างโครงสร้างใหม่ในแบบคู่ขนาน
  2. เริ่มเขียนไปที่โครงสร้างทั้งสอง
  3. โอนย้ายข้อมูลเก่าไปยังโครงสร้างใหม่
  4. เขียนและอ่านโครงสร้างใหม่เท่านั้น
  5. ลบคอลัมน์เก่า

สำหรับขั้นตอนที่ 3ให้ใช้สิ่งนี้ (ในหนึ่งธุรกรรม):

แทรกสิ่งที่ยังไม่มี:

INSERT INTO new_tbl (old_id, data)
SELECT old_id, data
FROM   old_tbl
WHERE  NOT EXISTS (SELECT * FROM new_tbl WHERE new_tbl.old_id = old_tbl.old_id);

อัปเดตสิ่งที่มีการเปลี่ยนแปลงในระหว่างนี้:

UPDATE new_tbl
SET    data  = old.data
USING  old_tbl
WHERE  new_tbl.old_id = old_tbl.old_id
AND    new_tbl.data IS DISTINCT FROM old_tbl.data;

ข้อมูลใหม่จะไม่ถูกสัมผัสเพราะมันเหมือนกันทั้งสองแห่ง


ฉันมีคำถามสองสามข้อในขณะที่พยายามเข้าใจสถานการณ์ที่คุณเสนอคำตอบนี้ - 1. การเปลี่ยนแปลงรหัสจะถูกปรับใช้พร้อมกับการเริ่มต้นของการเปลี่ยนแปลง db หรือไม่? 2. เหตุใดจึงจำเป็นต้องเขียนถึงโครงสร้างทั้งสอง 3. เหตุใดจึงไม่สามารถนำโครงสร้างใหม่มาใช้ก่อนจากนั้นจึงย้ายข้อมูลที่มีอยู่แล้วจึงนำรหัสการเปลี่ยนแปลงไปใช้ซึ่งจะเติมโครงสร้างใหม่ 4. เหตุใดจึงมีความจำเป็นต้องค้นหาสิ่งที่ไม่มี (แบบสอบถามแรกของคุณ) คุณกำลังเสนอการแทรกหลายครั้งหรือไม่?
Sandeepan Nath

2
@SandeepanNath เพื่อตอบคำถาม 3 ในความคิดเห็นของคุณ: เพราะถ้าคุณ (ก) แสดงโครงสร้างใหม่ (ข) ย้ายข้อมูลไปยังมัน (c) เปลี่ยนรหัสของคุณเพื่อเขียนข้อมูลไปยังโครงสร้างใหม่แทนที่จะเป็นแบบเก่าทั้งหมด การเปลี่ยนแปลงข้อมูลที่ทำระหว่างขั้นตอน b และขั้นตอน cจะมีอยู่ในโครงสร้างเดิมเท่านั้น คำถามคือทำอย่างไรถึงจะเปลี่ยนแปลงสคีมาโดยไม่ต้องหยุดทำงาน อ่านคำตอบนี้อีกครั้งอย่างระมัดระวัง
Wildcard
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.