it-swarm.asia

MySql - تغيير innodb_file_per_table للحصول على ديسيبل مباشر

لديّ MySql DB كبير (150 غيغابايت) والآن فقط لاحظت أن innodb_file_per_table تم تعيينه على off والذي يتسبب في استضافة قاعدة البيانات بأكملها في ملف واحد (ibdata1). اريد تفعيل innodb_file_per_table وهل قام بتقسيم قاعدة البيانات بأثر رجعي إلى عدة ملفات ، ما هي أفضل طريقة للقيام بذلك؟

19
Ran

هناك حقًا طريقة واحدة لإخراج هذا. سيكون عليك تصدير البيانات باستخدام mysqldumps ، وإسقاط جميع قواعد البيانات ، وإغلاق mysqld ، وحذف ib_logfile0 ، وحذف ib_logfile1 ، وحذف ibdata1 ، وإضافة innodb_file_per_table تحت [mysqld] العنوان ، تبدأ الخلية.

لقد نشرت هذه الإجابة في StackOverflow في أكتوبر 2010

فيما يلي الخطوات المدرجة عموديا:

الخطوة 01) MySQLDump جميع قواعد البيانات في ملف نصي SQL (يطلق عليه SQLData.sql)

الخطوة 02) إسقاط جميع قواعد البيانات (باستثناء مخطط الخلية)

الخطوة 03) إيقاف تشغيل الخلية

[~ # ~] تحذير [~ # ~] : لتنظيف المعاملات غير الملزمة تمامًا من ملفات InnoDB ، قم بتشغيل هذا

mysql -uroot -p... -Ae"SET GLOBAL innodb_fast_shutdown = 0;"
service mysql stop

الخطوة 04) أضف الأسطر التالية إلى /etc/my.cnf

[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G

Sidenote: مهما كانت مجموعة Innodb_buffer_pool_size ، تأكد من أن innodb_log_file_size هو 25٪ من innodb_buffer_pool_size.

الخطوة 05) احذف ibdata1 و ib_logfile0 و ib_logfile1

عند هذه النقطة ، يجب أن يكون هناك مخطط الخلية فقط في/var/lib/mysql

الخطوة 06) إعادة تشغيل الخلية

سيؤدي هذا إلى إعادة إنشاء ibdata1 عند 10 ميغابايت و ib_logfile0 و ib_logfile1 بسرعة 1G لكل منهما

الخطوة 07) إعادة تحميل SQLData.sql إلى الخلية

سوف تنمو ibdata1 ولكنها تحتوي فقط على بيانات تعريف الجدول

سيوجد كل جدول InnoDB خارج ibdata1

افترض أن لديك جدول InnoDB يسمى mydb.mytable. إذا ذهبت إلى/var/lib/mysql/mydb ، سترى ملفين يمثلان الجدول

  • mytable.frm (رأس محرك التخزين)
  • mytable.ibd (الصفحة الرئيسية لبيانات الجدول وفهارس الجدول لـ mydb.mytable)

لن يحتوي ibdata1 أبدًا على بيانات وفهارس InnoDB بعد الآن.

باستخدام خيار innodb_file_per_table في /etc/my.cnf ، يمكنك تشغيل OPTIMIZE TABLE mydb.mytable وسوف يتقلص الملف /var/lib/mysql/mydb/mytable.ibd بالفعل.

لقد فعلت ذلك عدة مرات في مسيرتي كدائرة MySQL DBA

في الواقع ، في المرة الأولى التي قمت فيها بذلك ، انهارت ملف 50 جيجا بايت ibdata1 في 500 ميجا بايت.

جربها. إذا كان لديك المزيد من الأسئلة حول هذا ، راسلني عبر البريد الإلكتروني. ثق في. سيعمل هذا على المدى القصير وعلى المدى الطويل. !!!

هناك بديل يستخرج جدول InnoDB دون تقليص ibdata1.

الخطوة 01) أضف الأسطر التالية إلى /etc/my.cnf

[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G

الخطوة 02) service mysql restart

الخطوة 03) لاستخراج جدول InnoDB واحد يسمى mydb.mytable ، قم بما يلي:

ALTER TABLE mydb.mytable ENGINE=InnoDB;

سيؤدي هذا إلى إنشاء ملف واحد pleus الاحتفاظ بملف الهيكل الأصلي

  • /var/lib/mysql/mydb/mytable.frm
  • /var/lib/mysql/mydb/mytable.ibd

يمكنك القيام بذلك لكل جدول InnoDB. لسوء الحظ ، ستبقى ibdata1 150 جيجابايت.

32
RolandoMySQLDBA

إذا كنت تريد استعادة مساحة ibdata ، فإن التفريغ/الاستعادة هو خيارك الوحيد ، حيث يشير Rolando . من المحتمل أيضًا أن يكون الأداء الأفضل للقيام بذلك.

ومع ذلك ، إذا كنت ترغب فقط في تقليل خسائرك و "فقدان" 150 جيجابايت على القرص الصلب ، يمكنك ببساطة تمكين innodb_file_per_table في my.cnf وأعد تشغيل الخادم.

ثم لكل جدول ، يصدر:

ALTER TABLE x DISABLE KEYS;
ALTER TABLE x ENGINE=InnoDB;
ALTER TABLE x ENABLE KEYS; 

المشكلة هنا هي أن مساحات الطاولات الكبيرة ستستغرق بعض الوقت.

ما أقترحه هو إعداد عبد من ديسيبل مباشر ، وتشغيل التحويل على الرقيق ، ثم إما إغلاق السيد/العبد ونسخ مساحة البيانات الجديدة إلى السيد ، أو ترقية العبد ليكون سيدًا بمجرد أن يلحق به .

ستواجه صعوبة في إجراء هذا التغيير بدون توقف على الإطلاق.

5
Derek Downey