แก้ไขตารางโดยไม่ล็อคโต๊ะ?


107

เมื่อทำคำสั่ง ALTER TABLE ใน MySQL ตารางทั้งหมดจะถูกล็อคการอ่าน (อนุญาตให้อ่านพร้อมกัน แต่ห้ามการเขียนพร้อมกัน) ในช่วงระยะเวลาของคำสั่ง หากเป็นตารางขนาดใหญ่คำสั่ง INSERT หรือ UPDATE อาจถูกบล็อกเป็นเวลานาน มีวิธีการ "แก้ไขด่วน" เช่นการเพิ่มคอลัมน์ในลักษณะที่ตารางยังคงสามารถอัปเดตได้ตลอดกระบวนการหรือไม่

ส่วนใหญ่ฉันสนใจโซลูชันสำหรับ MySQL แต่ฉันสนใจ RDBMS อื่น ๆ หาก MySQL ไม่สามารถทำได้

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


2
ต้องสงสัยว่าคุณจะเปลี่ยนโต๊ะกี่ครั้ง?
Allain Lalonde

1
IMHO การเปลี่ยนแปลงสคีมาของฐานข้อมูลจะเชื่อมโยงกับเวอร์ชันใหม่ทั้งหมด - ไม่ได้เปิดตัวเป็นระยะ ๆ เหมือนการเปลี่ยนแปลงอื่น ๆ เป็นเรื่องใหญ่อย่างหลีกเลี่ยงไม่ได้
dkretz

9
@AllainLalonde - มากกว่า 0 ครั้งทำให้คำถามนี้ถูกต้องโดยเฉพาะอย่างยิ่งถ้าการหยุดทำงานในระบบของคุณจะทำให้เสียชีวิตหรือเสียเงินเป็นจำนวนมาก และไม่ว่าในบางครั้งข้อกำหนดซอฟต์แวร์ใหม่จะปรากฏขึ้น
Nathan Long

คำตอบ:


60

ทางเลือกเดียวคือดำเนินการด้วยตนเองในสิ่งที่ระบบ RDBMS จำนวนมากทำอยู่ ...
- สร้างตารางใหม่

จากนั้นคุณสามารถคัดลอกเนื้อหาของตารางเก่าทีละชิ้นได้ ในขณะที่ระมัดระวังการ INSERT / UPDATE / DELETE บนตารางต้นทางอยู่เสมอ (สามารถจัดการได้โดยทริกเกอร์แม้ว่าสิ่งนี้จะทำให้การทำงานช้าลง แต่ก็ไม่ใช่การล็อก ... )

เมื่อเสร็จแล้วให้เปลี่ยนชื่อของตารางต้นทางจากนั้นเปลี่ยนชื่อของตารางใหม่ โดยเฉพาะอย่างยิ่งในการทำธุรกรรม

เมื่อเสร็จแล้วให้คอมไพล์โพรซีเดอร์ที่เก็บไว้อีกครั้ง ฯลฯ ที่ใช้ตารางนั้น แผนการดำเนินการจะไม่ถูกต้องอีกต่อไป

แก้ไข:

มีบางความคิดเห็นเกี่ยวกับข้อ จำกัด นี้ว่าค่อนข้างแย่ เลยคิดว่าจะใส่มุมมองใหม่เพื่อแสดงให้เห็นว่าทำไมถึงเป็นอย่างนั้น ...

  • การเพิ่มฟิลด์ใหม่ก็เหมือนกับการเปลี่ยนฟิลด์หนึ่งฟิลด์ในทุกแถว
  • การล็อกฟิลด์จะยากกว่าการล็อกแบบแถวมาก แต่ไม่ต้องกังวลกับการล็อกตาราง

  • คุณกำลังเปลี่ยนโครงสร้างทางกายภาพบนดิสก์ทุกครั้งที่บันทึกจะเคลื่อนไหว
  • นี่เป็นเหมือนการอัปเดตบนโต๊ะทั้งหมด แต่มีผลกระทบมากกว่า ...

2
และมีแผนการทดสอบอย่างละเอียดก่อนทำการแลกเปลี่ยน หากล้มเหลวให้เริ่มต้นใหม่
dkretz

2
การจัดการการซิงโครไนซ์ผ่านทริกเกอร์เป็นความคิดที่ดี ฉันใช้ MySQL มานานมากจนลืมไปแล้วว่ามีอะไรเกิดขึ้นในตอนนี้ ฉันเคยใช้เทคนิคนี้และตอนนี้ฉันมีสคริปต์แก้ไขด่วนที่ใช้งานได้ พร้อมแถบความคืบหน้า และใช้งานได้กับ MyISAM ชีวิตเป็นสิ่งที่ดี.
Daniel

2
+1 นี่คือสิ่งที่ผู้จัดการ SQL Enterprise ทำเบื้องหลังเมื่อคุณทำการเปลี่ยนแปลงตารางบางประเภทใน UI ใน SQL 2008 พวกเขาได้เพิ่มคำเตือนเพื่อให้ผู้ใช้ทราบว่ากำลังดำเนินการที่รุนแรงนี้
BradC

2
คุณไม่ได้พูดถึงอะไรเกี่ยวกับคีย์ต่างประเทศที่อ้างถึงตารางที่กำลังเปลี่ยนแปลง นั่นจะไม่เป็นปัญหาหรือ?
Rafay

2
@MohammadRafayAleem - และช่อง AUTOINCREMENT และมุมมองและทริกเกอร์ ฯลฯ แต่ถึงอย่างนั้นวิธีนี้ก็ยังใช้งานได้
MatBailie

42

Percona สร้างเครื่องมือที่เรียกว่าpt-online-schema-changeที่ช่วยให้สามารถทำได้

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

วิธีนี้คล้ายกับวิธีที่ Dems แนะนำไว้ข้างต้น แต่จะเป็นแบบอัตโนมัติ

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

เช่น:

pt-online-schema-change --alter "ADD COLUMN c1 INT" D=db,t=numbers_are_friends

ดูเหมือนว่าลิงก์จะเสีย ฉันพบว่าลิงก์นี้ใช้งานได้
Noam Ben Ari

25

คำถามนี้ตั้งแต่ปี 2009 ตอนนี้ MySQL เสนอวิธีแก้ปัญหา:

DDL ออนไลน์ (ภาษานิยามข้อมูล)

คุณลักษณะที่ปรับปรุงประสิทธิภาพการทำงานพร้อมกันและความพร้อมใช้งานของตาราง InnoDB ในระหว่างการดำเนินการ DDL (โดยหลักแล้วแก้ไขตาราง) ดูรายละเอียดในหัวข้อ 14.11“ InnoDB และ Online DDL”

รายละเอียดแตกต่างกันไปตามประเภทของการดำเนินการ ในบางกรณีตารางสามารถแก้ไขได้พร้อมกันในขณะที่กำลังดำเนินการแก้ไขตาราง การดำเนินการอาจสามารถทำได้โดยไม่ต้องทำสำเนาตารางหรือใช้สำเนาตารางชนิดที่ปรับให้เหมาะสมเป็นพิเศษ การใช้พื้นที่ถูกควบคุมโดยอ็อพชันการกำหนดคอนฟิก innodb_online_alter_log_max_size

ช่วยให้คุณปรับสมดุลระหว่างประสิทธิภาพและการทำงานพร้อมกันในระหว่างการดำเนินการ DDL โดยเลือกว่าจะบล็อกการเข้าถึงตารางทั้งหมดหรือไม่ (LOCK = EXCLUSIVE clause) อนุญาตการสืบค้น แต่ไม่ใช่ DML (LOCK = SHARED clause) หรืออนุญาตการสืบค้นแบบเต็มและ DML เข้าถึงตาราง (LOCK = NONE clause) เมื่อคุณละเว้นประโยค LOCK หรือระบุ LOCK = DEFAULT MySQL จะอนุญาตให้เกิดการทำงานพร้อมกันได้มากที่สุดโดยขึ้นอยู่กับประเภทของการดำเนินการ

ทำการเปลี่ยนแปลงในสถานที่ที่เป็นไปได้แทนที่จะสร้างสำเนาใหม่ของตารางหลีกเลี่ยงการเพิ่มขึ้นชั่วคราวของการใช้พื้นที่ดิสก์และค่าใช้จ่าย I / O ที่เกี่ยวข้องกับการคัดลอกตารางและสร้างดัชนีรองขึ้นใหม่

ดูคู่มืออ้างอิง MySQL 5.6 -> InnoDB และ DDL ออนไลน์สำหรับข้อมูลเพิ่มเติม

ดูเหมือนว่า DDL ออนไลน์มีให้ใน MariaDB ด้วย

หรือคุณสามารถใช้ ALTER ONLINE TABLE เพื่อให้แน่ใจว่า ALTER TABLE ของคุณไม่บล็อกการทำงานพร้อมกัน (ไม่ต้องล็อก) เทียบเท่ากับ LOCK = NONE

MariaDB KB เกี่ยวกับ ALTER TABLE


3
เป็นเรื่องที่น่าเสียดายที่ไม่มีวิธีอื่นใดนอกจากคะแนนโหวตที่จะทำให้คะแนนนี้อยู่ในอันดับต้น ๆ เนื่องจากส่วนใหญ่ปฏิเสธคำตอบอื่น ๆ ทั้งหมดเนื่องจากไม่ได้อ้างอิง MySQL เวอร์ชันปัจจุบันอีกต่อไป
Burhan Ali


14

ฉันแนะนำ Postgres ถ้าเป็นตัวเลือก สำหรับ postgres โดยพื้นฐานแล้วจะไม่มีการหยุดทำงานด้วยขั้นตอนต่อไปนี้:

คุณสมบัติที่ยอดเยี่ยมอื่น ๆ คือคำสั่ง DDL ส่วนใหญ่เป็นธุรกรรมดังนั้นคุณสามารถทำการโยกย้ายทั้งหมดภายในธุรกรรม SQL และหากมีบางอย่างผิดพลาดสิ่งทั้งหมดจะถูกย้อนกลับ

ฉันได้เขียนสิ่งนี้ไปเมื่อไม่นานมานี้บางทีมันอาจทำให้เข้าใจถึงข้อดีอื่น ๆ ได้มากขึ้น


6
Postgres ยังคงสร้างการล็อกเฉพาะสำหรับการเปลี่ยนแปลงเพื่อป้องกันไม่ให้ผู้อื่นอ่านจากตารางนั้น
clofresh

5
ฉันไม่เห็นด้วยกับบิต "โดยพื้นฐานแล้วไม่มีการหยุดทำงาน" ดังที่ clofresh กล่าวว่า ALTER TABLE คว้าตัวล็อกพิเศษบนโต๊ะที่บล็อกการอ่านและเขียนพร้อมกันทั้งหมด จากประสบการณ์ของฉันสำหรับตารางที่ใช้งานเกือบตลอดเวลาคุณจะไม่ได้รับการล็อค (ALTER TABLE จะอดตาย) และด้วยการทำธุรกรรมคุณสามารถจบลงด้วยการหยุดชะงักได้อย่างง่ายดายหากคุณไม่ระมัดระวังอย่างยิ่ง ด้วยเหตุนี้ฉันจึงตั้งเวลาหยุดทำงานเมื่อแก้ไขตารางที่มีอยู่ใน Postgres
ปานรัตน์

1
คำอธิบายโดยละเอียดเพิ่มเติม: dba.stackexchange.com/questions/27153/…กล่าวถึงผลกระทบของการล็อกแบบพิเศษและวิธีการบางอย่างในการแก้ไขปัญหา
John Douthat

4
ใช่การแก้ไขตารางใน postgres จะทำให้เกิดการล็อกแบบเอกสิทธิ์เฉพาะบุคคล แต่เนื่องจากการดำเนินการนั้นเสร็จสิ้นในมิลลิวินาทีจึงไม่เกี่ยวข้องในทางปฏิบัติในกรณีส่วนใหญ่ ฉันได้เพิ่มคอลัมน์เป็นการส่วนตัวในตารางร้อยล้านแถวในช่วงกลางของวันทำการโดยไม่มีเวลาหยุดทำงานเป็นศูนย์
Noah Yetter

2
@cobbzilla ใช่ DROP COLUMN เร็วพอ ๆ กัน ภายใต้ฝากระโปรงสิ่งที่ทำโดยทั่วไปคือทำเครื่องหมายคอลัมน์ว่าซ่อนอยู่ ค่าที่มีอยู่ในคอลัมน์นั้นก่อนที่จะถูกทิ้งจะยังคงอยู่ในไฟล์ข้อมูล (และสามารถมองเห็นได้ในธุรกรรมอื่น ๆ ) และจะยังคงอยู่จนกว่าคุณจะทำ VACUUM FULL
Noah Yetter

7

เนื่องจากคุณถามเกี่ยวกับฐานข้อมูลอื่นนี่คือข้อมูลบางส่วนเกี่ยวกับ Oracle

การเพิ่มคอลัมน์ NULL ลงในตาราง Oracle เป็นการดำเนินการที่รวดเร็วมากเนื่องจากอัปเดตพจนานุกรมข้อมูลเท่านั้น สิ่งนี้ถือเป็นการล็อคพิเศษบนโต๊ะในช่วงเวลาสั้น ๆ อย่างไรก็ตามจะทำให้กระบวนงานที่จัดเก็บไว้มุมมองทริกเกอร์ ฯลฯ เป็นโมฆะสิ่งเหล่านี้จะถูกคอมไพล์ใหม่โดยอัตโนมัติ

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

หากคุณต้องการเพิ่มคีย์ภายนอกคุณสามารถทำได้และขอให้ Oracle เชื่อมั่นว่าข้อมูลถูกต้อง มิฉะนั้นจะต้องอ่านทั้งตารางและตรวจสอบค่าทั้งหมดซึ่งอาจช้า (สร้างดัชนีของคุณก่อน)

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

จากนั้นคุณสามารถทำการสลับบนแอปพลิเคชันเซิร์ฟเวอร์ของคุณไปยังรหัสเวอร์ชันใหม่และจะทำงานต่อไป ปล่อยทริกเกอร์ลับๆของคุณ

หรือคุณสามารถใช้ DBMS_REDEFINITION ซึ่งเป็นกล่องดำที่ออกแบบมาเพื่อทำสิ่งนี้

ทั้งหมดนี้เป็นเรื่องยุ่งยากมากที่จะทดสอบและอื่น ๆ ที่เราเพิ่งหยุดทำงานในเช้าวันอาทิตย์เมื่อใดก็ตามที่เราปล่อยเวอร์ชันหลัก


3

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

  • รอให้การเปลี่ยนแปลงทั้งหมดถูกจำลองแบบบนทาสแบบพาสซีฟ
  • เปลี่ยน passive slave ให้เป็น active master
  • ทำการเปลี่ยนแปลงโครงสร้างต้นแบบเก่า
  • จำลองการเปลี่ยนแปลงกลับจากต้นแบบใหม่เป็นต้นแบบเก่า
  • ทำการสลับต้นแบบอีกครั้งและการปรับใช้แอพใหม่พร้อมกัน

ไม่ใช่เรื่องง่ายเสมอไป แต่ใช้ได้ผลโดยปกติจะมีการหยุดทำงาน 0 ครั้ง! โหนดที่สองไม่จำเป็นต้องเป็นโหนดแบบพาสซีฟเท่านั้นสามารถใช้สำหรับการทดสอบทำสถิติหรือเป็นโหนดสำรอง หากคุณไม่มีการจำลองแบบโครงสร้างพื้นฐานสามารถตั้งค่าได้ภายในเครื่องเดียว (ด้วย MySQL สองอินสแตนซ์)


1
Old master ออกจากคลัสเตอร์หรือภายในคลัสเตอร์?
John Chornelius

2

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

นี่เป็นการเปลี่ยนแปลงครั้งใหญ่ที่ฉันสงสัยว่า DBMS จะรองรับมัน ถือว่าเป็นประโยชน์ที่สามารถทำได้กับข้อมูลในตารางตั้งแต่แรก


InnoDB ใช้การล็อกแถว - dev.mysql.com/doc/refman/5.0/en/internal-locking.html
Eran Galperin

ใช่ MySQL คือความคลาด นั่นเป็นเหตุผลที่ฉันเจาะจงเกี่ยวกับตาราง "มาตรฐาน"
dkretz

คุณเขียน - ตาราง MySQL มาตรฐานทำเฉพาะการล็อกตาราง - ซึ่งไม่ถูกต้อง
Eran Galperin

คุณตีความสิ่งนี้เกี่ยวกับตาราง MyISAM (เช่น MySQL standard) จากหน้าที่คุณยกมาอย่างไร "MySQL ใช้การล็อกระดับตารางสำหรับตาราง MyISAM และ MEMORY การล็อกระดับหน้าสำหรับตาราง BDB และการล็อกระดับแถวสำหรับตาราง InnoDB"
dkretz

เครื่องมือจัดเก็บข้อมูลบางตัวใช้การล็อกระดับแถวและบางส่วนใช้การล็อกระดับโต๊ะ ไม่มีเครื่องมือจัดเก็บข้อมูลมาตรฐาน (บางทีคุณอาจหมายถึงค่าเริ่มต้นใน phpMyAdmin ... )
Eran Galperin

2

วิธีแก้ชั่วคราว ...

วิธีแก้ปัญหาอื่น ๆ คือเพิ่มตารางอื่นที่มีคีย์หลักของตารางเดิมพร้อมกับคอลัมน์ใหม่ของคุณ

เติมคีย์หลักของคุณลงในตารางใหม่และเติมค่าสำหรับคอลัมน์ใหม่ในตารางใหม่ของคุณและแก้ไขคิวรีของคุณเพื่อเข้าร่วมตารางนี้สำหรับการดำเนินการที่เลือกและคุณต้องแทรกอัปเดตแยกต่างหากสำหรับค่าคอลัมน์นี้

เมื่อคุณสามารถหยุดทำงานได้คุณสามารถแก้ไขตารางเดิมแก้ไขแบบสอบถาม DML ของคุณและวางตารางใหม่ที่สร้างไว้ก่อนหน้านี้

มิฉะนั้นคุณอาจใช้วิธีการจัดกลุ่มการจำลองแบบเครื่องมือ pt-online-schema จาก percona


1

การใช้ปลั๊กอิน Innodb คำสั่ง ALTER TABLE ซึ่งเพิ่มหรือวางดัชนีรองเท่านั้นที่สามารถทำได้ "อย่างรวดเร็ว" กล่าวคือไม่ต้องสร้างตารางใหม่

อย่างไรก็ตามโดยทั่วไปแล้วใน MySQL ตารางการเปลี่ยนแปลงใด ๆ เกี่ยวข้องกับการสร้างตารางใหม่ทั้งหมดซึ่งอาจใช้เวลานานมาก (เช่นในกรณีที่ตารางมีข้อมูลที่เป็นประโยชน์อยู่ในนั้น)

คุณจำเป็นต้องออกแบบแอปพลิเคชันของคุณเพื่อให้ไม่จำเป็นต้องทำงบ ALTER TABLE เป็นประจำ คุณไม่ต้องการให้มีการเปลี่ยนแปลงตารางใด ๆ ในระหว่างการทำงานปกติของแอปพลิเคชันเว้นแต่คุณจะพร้อมที่จะรอหรือกำลังแก้ไขตารางเล็ก ๆ


1

ฉันอยากจะแนะนำหนึ่งในสองวิธี:

  1. ออกแบบตารางฐานข้อมูลของคุณโดยคำนึงถึงการเปลี่ยนแปลงที่อาจเกิดขึ้น ตัวอย่างเช่นฉันเคยทำงานกับระบบจัดการเนื้อหาซึ่งเปลี่ยนช่องข้อมูลในเนื้อหาเป็นประจำ แทนที่จะสร้างโครงสร้างฐานข้อมูลทางกายภาพให้ตรงกับข้อกำหนดฟิลด์ CMS เริ่มต้นจะดีกว่ามากหากสร้างโครงสร้างที่ยืดหยุ่น ในกรณีนี้ใช้ช่องข้อความหยด (ตัวอย่างเช่น varchar (สูงสุด)) เพื่อเก็บข้อมูล XML ที่ยืดหยุ่น สิ่งนี้ทำให้การเปลี่ยนแปลงโครงสร้างเกิดขึ้นน้อยมาก การเปลี่ยนแปลงโครงสร้างอาจมีค่าใช้จ่ายสูงดังนั้นจึงมีประโยชน์ที่จะเสียค่าใช้จ่ายที่นี่เช่นกัน

  2. มีเวลาบำรุงรักษาระบบ ระบบจะออฟไลน์ระหว่างการเปลี่ยนแปลง (รายเดือน ฯลฯ ) และการเปลี่ยนแปลงจะถูกกำหนดไว้ในช่วงเวลาที่มีการเข้าชมมากน้อยที่สุดของวัน (เช่น 3-5.00 น.) การเปลี่ยนแปลงจะจัดขั้นตอนก่อนการเปิดตัวการผลิตดังนั้นคุณจะมีช่วงเวลาหยุดทำงานโดยประมาณที่ดี

2a. มีเซิร์ฟเวอร์ซ้ำซ้อนดังนั้นเมื่อระบบหยุดทำงานทั้งไซต์จะไม่ล่ม วิธีนี้จะช่วยให้คุณสามารถ "เผยแพร่" การอัปเดตของคุณในรูปแบบที่ไม่ถูกต้องโดยไม่ต้องลบทั้งไซต์

ตัวเลือก 2 และ 2a อาจไม่สามารถทำได้ พวกเขามักจะใช้สำหรับไซต์ / การดำเนินงานขนาดใหญ่เท่านั้น อย่างไรก็ตามพวกเขาเป็นตัวเลือกที่ถูกต้องและฉันได้ใช้ตัวเลือกทั้งหมดที่นำเสนอนี้เป็นการส่วนตัว


1

หากใครยังคงอ่านสิ่งนี้หรือบังเอิญมาที่นี่นี่เป็นประโยชน์อย่างมากของการใช้ระบบฐานข้อมูล NoSQL อย่าง mongodb ฉันมีปัญหาเดียวกันกับการแก้ไขตารางเพื่อเพิ่มคอลัมน์สำหรับคุณสมบัติเพิ่มเติมหรือดัชนีบนตารางขนาดใหญ่ที่มีแถวนับล้านและการเขียนสูง มันจะจบลงด้วยการล็อคเป็นเวลานานมากดังนั้นการทำเช่นนี้บนฐานข้อมูล LIVE จะทำให้ผู้ใช้ของเราไม่พอใจ บนโต๊ะเล็ก ๆ คุณสามารถหนีไปได้

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

มูลค่าการตรวจสอบ: www.mongodb.com


2
MySQL ยังคงใช้ในหลายระบบดังนั้นคำถามจึงเกี่ยวกับวิธีการเปลี่ยนแปลง schema ใน SQL RDBMS แม้ว่าฉันจะเป็นผู้สนับสนุน NoSQL ที่กระตือรือร้นเช่นกัน
Alexy

1

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

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

เพียงแค่ความคิด


1

ความแตกต่างระหว่าง Postgres และ MySQL ในเรื่องนี้คือใน Postgres จะไม่สร้างตารางขึ้นมาใหม่ แต่แก้ไขพจนานุกรมข้อมูลซึ่งคล้ายกับ Oracle ดังนั้นการดำเนินการจึงรวดเร็วในขณะที่ยังต้องจัดสรรการล็อกตาราง DDL แบบเอกสิทธิ์เฉพาะบุคคลในช่วงเวลาสั้น ๆ ตามที่ระบุไว้ข้างต้น

ใน MySQL การดำเนินการจะคัดลอกข้อมูลไปยังตารางใหม่ในขณะที่บล็อกธุรกรรมซึ่งเป็นปัญหาหลักสำหรับ MySQL DBA ก่อนหน้าเวอร์ชัน 5.6

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


3
ดูเหมือนว่าคุณพยายามเชื่อมโยงไปยังข้อมูลอ้างอิงเกี่ยวกับการเปลี่ยนแปลงใน MySql 5.6 แต่ไม่ได้ผล กรุณาลองอีกครั้ง.
dg99

1

ดังที่ SeanDowney ได้กล่าวไว้pt-online-schema-changeเป็นหนึ่งในเครื่องมือที่ดีที่สุดในการทำสิ่งที่คุณได้อธิบายไว้ในคำถามที่นี่ เมื่อเร็ว ๆ นี้ฉันได้ทำการเปลี่ยนแปลงสคีมาจำนวนมากบนฐานข้อมูลสดและมันก็ไปได้สวย คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ในโพสต์บล็อกของฉันที่นี่: http://mrafayaleem.com/2016/02/08/live-mysql-schema-changes-with-percona/


1

pt-online-schema-changeแน่นอนคุณควรพยายาม ฉันใช้เครื่องมือนี้เพื่อทำการโยกย้ายบน AWS RDS กับทาสหลายคนและมันก็ทำงานได้ดีสำหรับฉัน ฉันเขียนบล็อกโพสต์อย่างละเอียดเกี่ยวกับวิธีการซึ่งอาจเป็นประโยชน์สำหรับคุณ

บล็อก: http://mrafayaleem.com/2016/02/08/live-mysql-schema-changes-with-percona/


0

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

MyISAM จะล็อคทุกอย่างหากคุณเอ่ยชื่อโต๊ะในการส่งผ่านทางโทรศัพท์ที่สนามบิน มันทำอย่างนั้น ...

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


1
ฉันลองเพิ่มคอลัมน์ NULL ลงในตาราง InnoDB และต้องสร้างทั้งตารางใหม่ ไม่ใช่การดำเนินการ "อัปเดตข้อมูลเมตา" ง่ายๆ
Daniel

ฉันคิดว่าแนวคิดคือการรวมคอลัมน์พิเศษที่เป็นค่าว่างได้ในฐานข้อมูลเมื่อได้รับการออกแบบดังนั้นหากจำเป็นต้องใช้คุณลักษณะใหม่ก็สามารถ "เพิ่ม" คอลัมน์ใหม่ได้ง่ายๆโดยเริ่มใช้งาน จะไม่มีชื่อที่ดี แต่หากเลือก / คาดการณ์ประเภทข้อมูลอย่างถูกต้องก็ควรใช้งานได้
supercat

0

TokuDB สามารถเพิ่ม / วางคอลัมน์และเพิ่มดัชนี "ร้อน" ตารางพร้อมใช้งานตลอดกระบวนการ ได้ทาง www.tokutek.com


-6

ไม่จริง

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

หากคุณวางแผนที่จะทำสิ่งนี้เป็นจำนวนมากคุณจะดีกว่าเพียงแค่เติมตารางด้วยคอลัมน์ "จำลอง" ที่พร้อมใช้งานในอนาคต


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