ปลอดภัยหรือไม่ที่จะใช้ innodb_flush_log_at_trx_commit = 2


54

ฉันหมุนinnodb_flush_log_at_trx_commit = 2และรับความเร็วในการเขียนที่เร็วมาก แต่จะปลอดภัยไหมที่จะใช้ในเว็บไซต์การผลิต?

คำตอบ:


57

คุณสามารถสูญเสียธุรกรรมได้มากถึงหนึ่งวินาที ค่าเริ่มต้นคือ 1 ซึ่งจะช่วยให้ InnoDB กรดมาตรฐาน

ตามเอกสาร MySQL ในinnodb_flush_log_at_trx_commit

หากค่าของ innodb_flush_log_at_trx_commit เป็น 0 บัฟเฟอร์การบันทึกจะถูกเขียนลงในไฟล์บันทึกหนึ่งครั้งต่อวินาทีและดำเนินการ flush to disk บนไฟล์บันทึก แต่ไม่มีการทำธุรกรรมใด ๆ เมื่อค่าเป็น 1 (ค่าเริ่มต้น) บัฟเฟอร์การบันทึกจะถูกเขียนลงในไฟล์บันทึกที่แต่ละรายการที่กระทำและการดำเนินการ flush to disk จะดำเนินการในไฟล์บันทึก เมื่อค่าเป็น 2 บัฟเฟอร์การบันทึกจะถูกเขียนลงในไฟล์ในแต่ละการคอมมิต แต่การดำเนินการ flush to disk จะไม่ถูกดำเนินการ อย่างไรก็ตามการลบไฟล์บันทึกจะเกิดขึ้นหนึ่งครั้งต่อวินาทีเช่นกันเมื่อค่าเป็น 2 โปรดทราบว่าการล้างข้อมูลครั้งละหนึ่งวินาทีไม่ได้รับประกันว่าจะเกิดขึ้น 100% ทุกวินาทีเนื่องจากปัญหาการตั้งเวลาของกระบวนการ

ค่าเริ่มต้นของ 1 เป็นสิ่งจำเป็นสำหรับการปฏิบัติตาม ACID เต็มรูปแบบ คุณสามารถบรรลุประสิทธิภาพที่ดีขึ้นโดยการตั้งค่าที่แตกต่างจาก 1 แต่จากนั้นคุณสามารถทำธุรกรรมที่มีมูลค่าไม่เกินหนึ่งวินาทีในความผิดพลาด ด้วยค่า 0 ความผิดพลาดของกระบวนการ mysqld ใด ๆ สามารถลบวินาทีสุดท้ายของการทำธุรกรรม ด้วยค่าเท่ากับ 2 ระบบปฏิบัติการที่ล้มเหลวหรือระบบไฟดับเท่านั้นที่สามารถลบธุรกรรมครั้งที่สอง การกู้คืนความผิดพลาดของ InnoDB ทำงานโดยไม่คำนึงถึงคุณค่า

เพื่อความทนทานและความมั่นคงที่ยิ่งใหญ่ที่สุดที่เป็นไปได้ในการตั้งค่าการจำลองแบบโดยใช้ InnoDB พร้อมกับธุรกรรมให้ใช้ innodb_flush_log_at_trx_commit = 1 และ sync_binlog = 1 ในไฟล์ my.cnf เซิร์ฟเวอร์ต้นแบบของคุณ

ความระมัดระวัง

ระบบปฏิบัติการหลายระบบและฮาร์ดแวร์ดิสก์บางตัวไม่สามารถทำงานแบบฟลัช - ทู - ดิสก์ได้ พวกเขาอาจบอก mysqld ว่ามีการล้างเกิดขึ้นแม้ว่าจะไม่ได้ ดังนั้นความทนทานของการทำธุรกรรมจะไม่รับประกันแม้ว่าจะมีการตั้งค่า 1 และในกรณีที่เลวร้ายที่สุดไฟดับอาจทำให้ฐานข้อมูล InnoDB เสียหายได้ การใช้ดิสก์แคชที่แบตเตอรีสำรองไว้ในคอนโทรลเลอร์ดิสก์ SCSI หรือในดิสก์ของตัวเองจะเร่งความเร็วในการลบไฟล์และทำให้การดำเนินการปลอดภัยยิ่งขึ้น คุณยังสามารถลองใช้คำสั่ง Unix hdparm เพื่อปิดการใช้งานการแคชดิสก์เขียนในแคชฮาร์ดแวร์หรือใช้คำสั่งอื่นที่เฉพาะเจาะจงกับผู้จำหน่ายฮาร์ดแวร์

จากสิ่งนี้ค่าอื่น ๆ ที่มากกว่า 1 ทำให้ InnoDB เสี่ยงต่อการสูญเสียมูลค่าการทำธุรกรรม 1 วินาทีหรือมูลค่าของข้อมูล

sync_binlog=1เอกสารยังกล่าวว่าการใช้งาน

ตามเอกสาร MySQL ในsync_binlog

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

ทางเลือกที่ปลอดภัยที่สุดของคุณคือ

[mysqld]
innodb_flush_log_at_trx_commit=1
sync_binlog=1

หากคุณไม่คำนึงถึงการสูญเสียข้อมูลที่เป็นไปได้ (สูงสุด 1 วินาที) จากนั้นคุณสามารถใช้ความเสี่ยงของคุณเองเป็น 0 หรือ 2 หากรางวัล (ความเร็วในการเขียนเร็วขึ้น) นั้นคุ้มค่า


3
Rolando: +1 สำหรับสองสามบรรทัดที่ผ่านมา sync_binlog = 1 ...
อับดุล Manaf

@AbdulManaf ไปเพื่อความสมบูรณ์ของข้อมูลมากกว่าความเร็วเสมอ หากคุณต้องการเสียสละความเร็วเพื่อความถูกต้องของข้อมูลคุณจะพบว่าตัวเองเสียเวลาในการจัดการกับปัญหาข้อมูลมากขึ้น
Pacerier

1
@RolandoMySQLDBA โดย "การสูญเสียมูลค่าการทำธุรกรรมครั้งที่สอง" หมายความว่าคุณประสบความสำเร็จ commitอาจหายไปจริงหรือ
Pacerier

1
Pacerier ใช่ ข้อมูลรับประกันว่าจะเขียนลงดิสก์เท่านั้นหลังจาก "ล้างลงดิสก์" จนกว่าจะถึงเวลานั้นอาจอยู่ในหน่วยความจำ RAM เท่านั้น
Emil Vikström

2
@RolandoMySQLDBA คุณเป็นคนจริงจัง หากคุณทำอะไรอื่นนอกจากกิ๊กให้คำปรึกษาแบบเต็มเวลาคุณควรเปลี่ยนเส้นทางอาชีพของคุณ
sjas

25

innodb_flush_log_at_trx_commitถูกนำมาใช้โดยมีวัตถุประสงค์เพื่อเป็น ..

หากค่าinnodb_flush_log_at_trx_commit เป็น 0 บัฟเฟอร์การบันทึกจะถูกเขียนลงในไฟล์บันทึกหนึ่งครั้งต่อวินาทีและการดำเนินการ flush to disk จะถูกดำเนินการบนล็อกไฟล์ แต่ไม่มีการทำธุรกรรมใด ๆ

เมื่อค่าเป็น 1 (ค่าเริ่มต้น) บัฟเฟอร์การบันทึกจะถูกเขียนลงในไฟล์บันทึกที่แต่ละรายการที่กระทำและการดำเนินการ flush to disk จะดำเนินการในไฟล์บันทึก

เมื่อค่าเป็น 2 บัฟเฟอร์การบันทึกจะถูกเขียนไปยังไฟล์ในแต่ละการคอมมิต แต่การดำเนินการ flush to disk จะไม่ถูกดำเนินการ อย่างไรก็ตามการลบไฟล์บันทึกจะเกิดขึ้นหนึ่งครั้งต่อวินาทีเช่นกันเมื่อค่าเป็น 2 โปรดทราบว่าการล้างข้อมูลครั้งละหนึ่งวินาทีไม่ได้รับประกันว่าจะเกิดขึ้น 100% ทุกวินาทีเนื่องจากปัญหาการตั้งเวลาของกระบวนการ

ค่าเริ่มต้นของ 1 เป็นสิ่งจำเป็นสำหรับการปฏิบัติตาม ACID เต็มรูปแบบ คุณสามารถบรรลุประสิทธิภาพที่ดีขึ้นโดยการตั้งค่าที่แตกต่างจาก 1 แต่จากนั้นคุณสามารถทำธุรกรรมที่มีมูลค่าไม่เกินหนึ่งวินาทีในความผิดพลาด ด้วยค่า 0 ความผิดพลาดของกระบวนการ mysqld ใด ๆ สามารถลบวินาทีสุดท้ายของการทำธุรกรรม ด้วยค่าเท่ากับ 2 ระบบปฏิบัติการที่ล้มเหลวหรือระบบไฟดับเท่านั้นที่สามารถลบธุรกรรมครั้งที่สอง การกู้คืนความผิดพลาดของ InnoDB ทำงานโดยไม่คำนึงถึงคุณค่า

ในความคิดของฉันใช้innodb_flush_log_at_trx_commitถึง 2 ไม่ควรเป็นปัญหา แต่การใช้ 1 เป็นสิ่งที่ปลอดภัยที่สุด


3
ฉันเพิ่งสังเกตเห็นว่าคุณตอบเพียง 18 วินาทีหลังจากฉันด้วยคำตอบเดียวกันโดยพื้นฐานแล้ว +1 !!!
RolandoMySQLDBA

24

ความคิดเห็นของฉันแตกต่างจากคนอื่น innodb_flush_log_at_trx_commit = 0 ถ้า: เป็นคอมพิวเตอร์พัฒนาหรือฐานข้อมูลขนาดเล็กในบ้านของฉันซึ่งไม่มีข้อมูลที่ละเอียดอ่อน

innodb_flush_log_at_trx_commit = 2 หาก: เป็นบล็อก / สถิติ / อีคอมเมิร์ซ (มีร้านค้าประมาณ 100x ต่อวัน) เป็นต้น

innodb_flush_log_at_trx_commit = 1 หาก: คุณมีลูกค้าจำนวนมากหรือคุณจำเป็นต้องทำงานกับธุรกรรมการเงินเช่นธนาคาร ดังนั้นเวลานี้คุณควรแบ่งดาต้าโฟลว์ของคุณระหว่างเซิร์ฟเวอร์ต่าง ๆ เพื่อให้มีความเร็วและความปลอดภัย

ฉันชอบ 2 เพราะมันมีความเร็วในการเขียนที่เร็วขึ้น ~ 75x และมันล้มเหลวเฉพาะในกรณีที่ฮาร์ดแวร์ล้มเหลว

อย่างไรก็ตามคุณควรทราบว่าคุณต้องการความเร็วในการเขียนมากขึ้นหรือมากถึง 1 วินาที?


1
+1 สำหรับ75x faster write speed and it fails ONLY if hardware fails.
Naman Gala

3
เร็วขึ้น 75x เหรอ? ต้องการการอ้างอิง
Pacerier

5
มาตรฐานของฉันเอง: 5000 UPDATEด้วยinnodb_flush_log_at_trx_commit = 1: 179 วินาที ด้วยinnodb_flush_log_at_trx_commit = 2: 1.12 วินาที มันเร็วกว่าการเขียน 160x ในกรณีของฉัน
เควิน

คำตอบที่ดี. สิ่งหนึ่งที่คิดว่า - หากเครื่องของคุณขัดข้องหลังจากทำธุรกรรมสำเร็จแล้วโอกาสที่ธุรกรรมนั้นไม่ได้ถูกเขียนลงดิสก์ด้วย innodb_flush_log_at_trx_commit = 2 แต่ยังแสดงถึงความสำเร็จในแอปพลิเคชันของคุณ (เช่น mysqld จัดการส่งแพ็คเก็ตเครือข่าย ถึงคนขับในแอปของคุณ) โอกาสนั้นต่ำมาก
Vladislav Vaintroub

คุณสามารถคำตอบของคุณโดยการระบุความหมายของเอกสารcrash
Shareef

2

ฉันพยายามที่จะตอบสิ่งที่เป็นวัตถุประสงค์ของ innodb_flush_log_at_trx_commit?

InnoDB ดำเนินการส่วนใหญ่ในหน่วยความจำ ( InnoDB Buffer Pool) Al ข้อมูลที่ถูกแก้ไขจะถูกเขียนไปยังInnoDB transaction log fileจากนั้นจะถูกฟลัช (เขียน) ไปยังที่เก็บข้อมูลที่ทนทาน (ฮาร์ดดิสก์)

เพื่อความปลอดภัยของข้อมูล ( Durability from ACID) InnoDB จะต้องเก็บข้อมูลที่ถูกแก้ไขของแต่ละรายการไว้ในที่เก็บข้อมูลถาวร ในเวลาเดียวกันการผูกพันกับดิสก์สำหรับแต่ละธุรกรรมนั้นมีค่าใช้จ่ายสูง

Disk I / O เป็นกระบวนการบล็อกและมันช้ามากมันเป็นดิสก์ที่ช้าและมันจะลดจำนวนInnoDB transaction per seconds(Disk throughput)

InnoDB นำเสนอinnodb_flush_log_at_trx_commitตัวแปรเพื่อควบคุมความถี่ของการดำเนินการฟลัชนี้ ขึ้นอยู่กับค่าการดำเนินการ flush ของ InnoDB จะทำงานแตกต่างกัน

(อธิบายแล้วในคำตอบอื่น ๆ )

0 - เขียนไปยังล็อกไฟล์และฟลัชลงดิสก์ทุกวินาที (ข้อมูลอยู่ในบัฟเฟอร์พูลไม่ถูกเขียนไปยังล็อกไฟล์ - เพื่อเพิ่มประสิทธิภาพ) 1 - ฟลัชไปยังดิสก์เมื่อทำธุรกรรม - ค่าเริ่มต้น (เพื่อความปลอดภัยของข้อมูล - ความสอดคล้องกับกรด) 2 - เขียนไปยังไฟล์บันทึกสำหรับทุกธุรกรรมและล้างไปยังดิสก์ทุกวินาที (สำหรับการเพิ่มประสิทธิภาพ)

ขึ้นอยู่กับข้อกำหนดของแอปพลิเคชัน ( Performance Vs data safety) คุณสามารถตั้งค่าตัวแปรนี้ได้ ความแตกต่างระหว่าง 0 และ 2 - ทั้งสองจะเพิ่มประสิทธิภาพการทำงานค่า 2 เก็บข้อมูลในไฟล์ธุรกรรมและสามารถกู้คืนได้ในกรณีที่เกิดข้อผิดพลาดหรือล้มเหลว แต่ไม่ใช่ใน 0

ในหลาย ๆ กรณีหมายถึง flush ไปยังดิสก์ข้อมูลจะถูกเขียนจากInnoDB buffer pool (memory) to Operating systems cacheไม่ได้เขียนลงดิสก์จัดเก็บข้อมูลจริง (ที่เก็บข้อมูลถาวร) ในกรณีที่ล้มเหลวในกรณีที่เลวร้ายที่สุดคุณอาจสูญเสียข้อมูลสูงสุดหนึ่งวินาที)

การเพิ่มประสิทธิภาพขึ้นอยู่กับสภาพแวดล้อมและคุณสามารถสร้างมาตรฐานและระบุ ในสภาพแวดล้อมการจำลองแบบเพื่อความปลอดภัยของข้อมูลและความสอดคล้องตั้งและinnodb_flush_log_trx_commit = 1sync_binlog=1

หากประสิทธิภาพเป็นเป้าหมายหลักของแอปพลิเคชั่น InnoDB จะให้ตัวแปรในการควบคุมความถี่ของการล้างบันทึกinnodb_flush_log_at_timeout- ซึ่งช่วยให้คุณตั้งค่าช่วงความถี่ในการล้างบันทึกจาก1 to 2700 secondsค่าเริ่มต้นคือ 1

ระวังเมื่อคุณเพิ่มช่วงเวลาการล้างสูงสุด N วินาทีประสิทธิภาพการทำงานจะเพิ่มขึ้นด้วยความปลอดภัยของข้อมูลที่ลดลงสูงสุด N วินาที ตัวอย่างเช่น - หากคุณตั้งค่าการฟลัชชิงเกิดขึ้นทุก ๆ 5 วินาที - อัตราการรับผลผลิตสูงมาก แต่ในกรณีที่ไฟฟ้าขัดข้องหรือระบบล่มคุณจะสูญเสียข้อมูลที่มีค่า 5 วินาที

บทความนี้อธิบายเกี่ยวกับการล้างข้อมูล InnoDB และการดำเนินการกระทำธุรกรรม

คุณสามารถเปลี่ยนหลังจากที่คุณทำโหมด 2 ใน aws rds:

สามารถเปลี่ยนได้หลังจากที่คุณทำโหมด 2 ใน aws

previewchanges

ไม่สามารถแก้ไขได้ในบางกรณีเช่นถ้าคุณมีการจำลองแบบ multi az:

FYI ไม่สามารถเปลี่ยนแปลงได้ในบางกรณี


1

หากฮาร์ดแวร์ของคุณล้มเหลวคุณสามารถหลวมข้อมูลทั้งหมดของคุณดังนั้นฉันใช้ param = 2 โดยไม่ต้องกังวล อย่างไรก็ตามคุณสามารถแยกข้อมูลที่อ่อนไหว (คำสั่งซื้อเงินเสมือนจริง ... ) และข้อมูลปกติ (สถิติรถเข็น ... ) ระหว่างเซิร์ฟเวอร์ 2 เดซิเบลและทำให้พวกเขาปลอดภัยและรวดเร็ว สำหรับการทำธุรกรรมระหว่างฐานข้อมูลคุณสามารถใช้http://dev.mysql.com/doc/refman/5.7/en/xa.html


"สูญเสียข้อมูลทั้งหมดของคุณ" หรือคุณหมายถึงธุรกรรมที่ได้รับการสอบถามในไม่กี่วินาทีที่ผ่านมาหรือดังนั้น?
NiCk Newman

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