ฉันต้องการสร้างดัชนีบนตาราง MySQL ~ 5M แถว มันเป็นตารางการผลิตและฉันกลัวว่าทุกอย่างจะสมบูรณ์แบบถ้าฉันเรียกใช้คำสั่ง CREATE INDEX ...
มีวิธีสร้างดัชนีโดยไม่ปิดกั้นการแทรกและเลือกหรือไม่?
แค่สงสัยว่าฉันยังไม่หยุดสร้างดัชนีและรีสตาร์ทระบบของฉัน!
ฉันต้องการสร้างดัชนีบนตาราง MySQL ~ 5M แถว มันเป็นตารางการผลิตและฉันกลัวว่าทุกอย่างจะสมบูรณ์แบบถ้าฉันเรียกใช้คำสั่ง CREATE INDEX ...
มีวิธีสร้างดัชนีโดยไม่ปิดกั้นการแทรกและเลือกหรือไม่?
แค่สงสัยว่าฉันยังไม่หยุดสร้างดัชนีและรีสตาร์ทระบบของฉัน!
คำตอบ:
ใน MySQL 5.6 ขึ้นไปตารางยังคงพร้อมใช้งานสำหรับการอ่านและเขียนในขณะที่ดัชนีกำลังสร้างหรือลดลง คำสั่ง CREATE INDEX หรือ DROP INDEX จะเสร็จสิ้นหลังจากที่ธุรกรรมทั้งหมดที่เข้าถึงตารางเสร็จสมบูรณ์เท่านั้นดังนั้นสถานะเริ่มต้นของดัชนีจะแสดงถึงเนื้อหาล่าสุดของตาราง ก่อนหน้านี้การปรับเปลี่ยนตารางในขณะที่ดัชนีกำลังถูกสร้างหรือลดลงมักจะทำให้เกิดการชะงักงันที่ยกเลิกคำสั่ง INSERT, UPDATE หรือ DELETE บนตาราง
จากคำตอบด้านบน:
"หากคุณใช้เวอร์ชันที่มากกว่า 5.1 ดัชนีถูกสร้างขึ้นในขณะที่ฐานข้อมูลออนไลน์อยู่ดังนั้นไม่ต้องกังวลว่าคุณจะไม่ขัดขวางการใช้งานระบบการผลิต"
นี่คือ **** FALSE **** (อย่างน้อยสำหรับตาราง MyISAM / InnoDB ซึ่งเป็นสิ่งที่ 99.999% ของคนที่นั่นใช้ Clustered Edition แตกต่างกัน)
การดำเนินการ UPDATE บนตารางจะBLOCKในขณะที่กำลังสร้างดัชนี MySQL โง่จริงๆเกี่ยวกับเรื่องนี้ (และอีกสองสามอย่าง)
สคริปต์ทดสอบ:
(
for n in {1..50}; do
#(time mysql -uroot -e 'select * from website_development.users where id = 41225\G'>/dev/null) 2>&1 | grep real;
(time mysql -uroot -e 'update website_development.users set bio="" where id = 41225\G'>/dev/null) 2>&1 | grep real;
done
) | cat -n &
PID=$!
sleep 0.05
echo "Index Update - START"
mysql -uroot website_development -e 'alter table users add index ddopsonfu (last_name, email, first_name, confirmation_token, current_sign_in_ip);'
echo "Index Update - FINISH"
sleep 0.05
kill $PID
time mysql -uroot website_development -e 'drop index ddopsonfu on users;'
เซิร์ฟเวอร์ของฉัน (InnoDB):
Server version: 5.5.25a Source distribution
เอาต์พุต (สังเกตว่าบล็อกการดำเนินการที่ 6 สำหรับ ~ 400ms ใช้เวลาในการอัพเดตดัชนีให้เสร็จสิ้นอย่างไร):
1 real 0m0.009s
2 real 0m0.009s
3 real 0m0.009s
4 real 0m0.012s
5 real 0m0.009s
Index Update - START
Index Update - FINISH
6 real 0m0.388s
7 real 0m0.009s
8 real 0m0.009s
9 real 0m0.009s
10 real 0m0.009s
11 real 0m0.009s
Vs อ่านการดำเนินการที่ไม่ปิดกั้น (สลับความคิดเห็นบรรทัดในสคริปต์):
1 real 0m0.010s
2 real 0m0.009s
3 real 0m0.009s
4 real 0m0.010s
5 real 0m0.009s
Index Update - START
6 real 0m0.010s
7 real 0m0.010s
8 real 0m0.011s
9 real 0m0.010s
...
41 real 0m0.009s
42 real 0m0.010s
43 real 0m0.009s
Index Update - FINISH
44 real 0m0.012s
45 real 0m0.009s
46 real 0m0.009s
47 real 0m0.010s
48 real 0m0.009s
ด้วยเหตุนี้มีเพียงวิธีเดียวที่ฉันรู้ในการอัปเดตสคีมา MySql และไม่ประสบปัญหาการหยุดทำงาน ปริญญาโทแบบวงกลม:
วิธีง่ายๆในการอัปเดตสคีมานี้ไม่ใช่ สามารถทำงานได้ในสภาพแวดล้อมการผลิตที่จริงจัง ใช่แล้ว. ได้โปรดได้โปรดหากมีวิธีที่ง่ายกว่าในการเพิ่มดัชนีลงในตาราง MySQL โดยไม่ต้องบล็อกการเขียนโปรดแจ้งให้เราทราบ
Googling นำฉันไปสู่บทความนี้ซึ่งอธิบายถึงเทคนิคที่คล้ายกัน ยิ่งไปกว่านั้นพวกเขาแนะนำให้ดื่มในจุดเดียวกันในขั้นตอนการดำเนินการ (โปรดทราบว่าฉันเขียนคำตอบก่อนอ่านบทความ)!
บทความฉันเชื่อมโยงดังกล่าวพูดคุยเกี่ยวกับเครื่องมือPT-ออนไลน์คีมาเปลี่ยนงานที่ดังต่อไปนี้:
ฉันไม่เคยลองใช้เครื่องมือด้วยตัวเอง YMMV
ฉันกำลังใช้ MySQL ผ่านRDS ของ Amazon เป็นบริการที่ดีจริงๆที่รวบรวมและจัดการ MySQL ช่วยให้คุณเพิ่มแบบจำลองการอ่านใหม่ด้วยปุ่มเดียวและอัปเกรดฐานข้อมูลอย่างโปร่งใสใน SKU ของฮาร์ดแวร์ สะดวกจริงๆ คุณไม่สามารถเข้าถึงฐานข้อมูลได้อย่างยอดเยี่ยมดังนั้นคุณจึงไม่สามารถใช้การจำลองแบบโดยตรงได้ (นี่คือพรหรือคำสาป?) อย่างไรก็ตามคุณสามารถใช้Read Replica Promotionเพื่อทำการเปลี่ยนแปลงสคีมาของคุณบนทาสแบบอ่านอย่างเดียวจากนั้นเลื่อนระดับทาสนั้นให้กลายเป็นนายใหม่ของคุณ เคล็ดลับเดียวกับที่ฉันอธิบายไว้ข้างต้นเพียงแค่ดำเนินการได้ง่ายขึ้นมาก พวกเขายังไม่ช่วยคุณในการตัดต่อ คุณต้องกำหนดค่าใหม่และรีสตาร์ทแอปของคุณ
ตามที่บล็อกโพสต์นี้มีเค้าโครง InnoDBALTER TABLE
กลไกได้รับการออกแบบใหม่ทั้งหมดสำหรับ MySQL 5.6
(สำหรับภาพรวมเฉพาะของหัวข้อนี้เอกสาร MySQLสามารถให้ความคุ้มค่าในการอ่านในช่วงบ่าย)
ในการเพิ่มดัชนีลงในตารางโดยไม่มีการล็อกที่เกิดจากUPDATE
/ INSERT
สามารถใช้รูปแบบคำสั่งต่อไปนี้:
ALTER TABLE my_table ADD INDEX my_table__idx (my_column), ALGORITHM=INPLACE, LOCK=NONE;
การอัปเดต MySQL 5.6 (กุมภาพันธ์ 2013): ขณะนี้คุณสามารถดำเนินการอ่านและเขียนได้ในขณะที่สร้างดัชนีแม้จะมีตาราง InnoDB - http://dev.mysql.com/doc/refman/5.6/en/innodb-create-index -overview.html
ใน MySQL 5.6 ขึ้นไปตารางยังคงพร้อมใช้งานสำหรับการอ่านและเขียนในขณะที่ดัชนีกำลังสร้างหรือลดลง คำสั่ง CREATE INDEX หรือ DROP INDEX จะเสร็จสิ้นหลังจากที่ธุรกรรมทั้งหมดที่เข้าถึงตารางเสร็จสมบูรณ์เท่านั้นดังนั้นสถานะเริ่มต้นของดัชนีจะแสดงถึงเนื้อหาล่าสุดของตาราง ก่อนหน้านี้การปรับเปลี่ยนตารางในขณะที่ดัชนีกำลังถูกสร้างหรือลดลงมักจะทำให้เกิดการชะงักงันที่ยกเลิกคำสั่ง INSERT, UPDATE หรือ DELETE บนตาราง
และ:
ใน MySQL 5.6 คุณลักษณะนี้มีลักษณะทั่วไปมากขึ้น: คุณสามารถอ่านและเขียนลงในตารางได้ในขณะที่สร้างดัชนีและสามารถดำเนินการ ALTER TABLE ได้หลายประเภทโดยไม่ต้องคัดลอกตารางโดยไม่บล็อกการดำเนินการ DML หรือทั้งสองอย่าง ดังนั้นใน MySQL 5.6 ขึ้นไปโดยทั่วไปเราจะอ้างถึงคุณสมบัติชุดนี้ว่า DDL ออนไลน์แทนที่จะสร้างดัชนีอย่างรวดเร็ว
จากhttp://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_fast_index_creation
pt-online-schema-change เป็นวิธีที่จะไปหากคุณต้องการให้แน่ใจว่าการย้ายข้อมูลจะไม่ทำให้ไซต์ล่ม
ดังที่ฉันเขียนไว้ในความคิดเห็นข้างต้นฉันมีประสบการณ์มากมายเกี่ยวกับการเปลี่ยนแปลง pt-online-schema-change ในการผลิต เรามีตารางหลักของเรกคอร์ด 20M + และมาสเตอร์ -> 2 ทาสการจำลองแบบอ่านอย่างเดียว ฉันได้ทำการโยกย้ายอย่างน้อยหลายสิบครั้งด้วย pt-online-schema-change ตั้งแต่การเพิ่มคอลัมน์ใหม่การเปลี่ยนชุดอักขระไปจนถึงการเพิ่มดัชนีต่างๆ เราให้บริการปริมาณการใช้งานจำนวนมากในช่วงเวลาอพยพเช่นกันและเราไม่ได้มีอาการสะอึกใด ๆ แน่นอนว่าคุณต้องทดสอบสคริปต์ทั้งหมดอย่างละเอียดก่อนที่จะดำเนินการผลิต
ฉันพยายามรวมการเปลี่ยนแปลงเป็น 1 สคริปต์เพื่อให้ pt-online-schema-change ต้องคัดลอกข้อมูลเพียงครั้งเดียว และระมัดระวังในการเปลี่ยนชื่อคอลัมน์เนื่องจากข้อมูลของคุณจะสูญเสียไป อย่างไรก็ตามควรเพิ่มดัชนี
pt-online-schema-change
คุณ มันยอดเยี่ยม แต่ก็เกินความสามารถสำหรับหลาย ๆ สถานการณ์ที่ความสามารถ DDL ออนไลน์ของ MySQL 5.6 + ทำงานได้ดีอยู่แล้ว นอกจากนี้ยังมีข้อ จำกัด (เช่นการไม่เล่นกับทริกเกอร์อย่างดี) และเพิ่มจำนวนการเขียนที่จำเป็นต่อการแทรกลงในตารางเดิมเป็นสองเท่าในขณะที่กำลังดำเนินการเปลี่ยนแปลงสคีมา มันจะเก็บภาษีดิสก์ของคุณอย่างมากมากกว่าการเปลี่ยนแปลงสคีมาออนไลน์ทั่วไปดังนั้นจึงมีความเป็นไปได้ที่จะ "ลดไซต์ของคุณ" ในสถานการณ์ที่เพียงแค่เรียกใช้สคีมาเปลี่ยนวิธีง่ายๆก็จะได้ผลดี
pt-online-schema-change
จะเป็นเครื่องมือที่มีประโยชน์ แต่ก็มีหลายสถานการณ์ที่ DDL ออนไลน์ทั่วไปนั้นดีพอ ๆ กันและมีเพียงไม่กี่แห่งที่ดีกว่าดังนั้นคำแนะนำใด ๆ ควรระบุไว้อย่างรอบคอบมากกว่าสากล