it-swarm.asia

كيف تقليص/تطهير ملف ibdata1 في MySQL

أنا أستخدم MySQL في مضيف محلي "كأداة استعلام" لإجراء إحصائيات في R ، أي أنه في كل مرة أقوم فيها بتشغيل برنامج نصي R ، أقوم بإنشاء قاعدة بيانات جديدة (A) ، وإنشاء جدول جديد (B) ، واستيراد البيانات إلى B ، إرسال استعلام للحصول على ما أحتاج إليه ، ثم إسقاط B وإسقاط A.

إنه أمر جيد بالنسبة لي ، لكنني أدرك أن حجم ملف ibdata يتزايد بسرعة ، ولم أقوم بتخزين أي شيء في MySQL ، لكن ملف ibdata1 تجاوز بالفعل 100 ميجابايت.

أنا أستخدم إعداد MySQL الافتراضي أكثر أو أقل للإعداد ، هل هناك طريقة يمكنني من خلالها تقليص/إزالة ملف ibdata1 تلقائيًا بعد فترة زمنية محددة؟

530
lokheart

هذا ibdata1 لا يتقلص هو ميزة مزعجة بشكل خاص في MySQL. لا يمكن بالفعل تقليص ملف ibdata1 إلا إذا قمت بحذف جميع قواعد البيانات وإزالة الملفات وإعادة تحميل ملف التفريغ.

ولكن يمكنك تكوين MySQL بحيث يتم تخزين كل جدول ، بما في ذلك فهارسه ، كملف منفصل. بهذه الطريقة ، لن ينمو رمز ibdata1. وفقًا لـ تعليق Bill Karwin يتم تمكين هذا افتراضيًا اعتبارًا من الإصدار 5.6.6 من MySQL.

كان منذ فترة فعلت هذا. ومع ذلك ، لإعداد الخادم الخاص بك لاستخدام ملفات منفصلة لكل جدول ، تحتاج إلى تغيير my.cnf لتمكين هذا:

[mysqld]
innodb_file_per_table=1

http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html

كما تريد استعادة المساحة من ibdata1 ، فعليك بالفعل حذف الملف:

  1. قم بإجراء mysqldump من جميع قواعد البيانات والإجراءات والمشغلات وما إلى ذلك باستثناء قواعد البيانات mysql و performance_schema
  2. إسقاط جميع قواعد البيانات باستثناء قواعد البيانات 2 أعلاه
  3. وقف mysql
  4. احذف ملفات ibdata1 و ib_log
  5. بدء mysql
  6. استعادة من تفريغ

عند بدء تشغيل MySQL في الخطوة 5 ، سيتم إعادة إنشاء ملفات ibdata1 و ib_log.

الآن أنت لائق للذهاب. عندما تقوم بإنشاء قاعدة بيانات جديدة للتحليل ، سيتم وضع الجداول في ملفات ibd* منفصلة ، وليس في ibdata1. كما يمكنك عادةً إسقاط قاعدة البيانات بعد فترة وجيزة ، سيتم حذف ملفات ibd*.

http://dev.mysql.com/doc/refman/5.1/ar/drop-database.html

ربما رأيت هذا:
http://bugs.mysql.com/bug.php؟id=1341

باستخدام الأمر ALTER TABLE <tablename> ENGINE=innodb أو OPTIMIZE TABLE <tablename> ، يمكن للمرء استخراج البيانات وفهرسة الصفحات من ibdata1 لفصل الملفات. ومع ذلك ، لن يتقلص ibdata1 إلا إذا قمت بالخطوات المذكورة أعلاه.

فيما يتعلق بـ information_schema ، هذا ليس ضروريًا ولا يمكن إسقاطه. إنها في الحقيقة مجرد مجموعة من المشاهدات للقراءة فقط ، وليس الجداول. وليس هناك ملفات مرتبطة بها ، ولا حتى دليل قاعدة البيانات. يستخدم informations_schema محرك الذاكرة db ويتم إسقاطه وتجديده عند إيقاف/إعادة تشغيل mysqld. راجع https://dev.mysql.com/doc/refman/5.7/ar/information-schema.html .

748
John P

إضافة إلى إجابة John P ،

بالنسبة لنظام linux ، يمكن تنفيذ الخطوات من 1-6 باستخدام هذه الأوامر:

  1. mysqldump -u [username] -p[root_password] [database_name] > dumpfilename.sql
  2. DROP DATABASE [database_name];
  3. Sudo /etc/init.d/mysqld stop
  4. Sudo rm /var/lib/mysql/ibdata1
    Sudo rm /var/lib/mysql/ib_logfile (وحذف أي ib_logfile الأخرى التي قد تتم تسمية ib_logfile0 ، ib_logfile1 الخ ...)
  5. Sudo /etc/init.d/mysqld start
  6. create database [database_name];
  7. mysql -u [username]-p[root_password] [database_name] < dumpfilename.sql

تحذير: هذه الإرشادات ستتسبب في فقد قواعد البيانات الأخرى إذا كان لديك قواعد بيانات أخرى على مثيل mysql هذا. تأكد من تعديل الخطوتين 1،2 و 6،7 لتغطية جميع قواعد البيانات التي ترغب في الاحتفاظ بها.

42
Vinay Vemula

عندما تقوم بحذف الجداول innodb ، لا يقوم MySQL بتحرير المساحة الموجودة داخل ملف ibdata ، ولهذا يواصل نموه. هذه الملفات بالكاد تقلص من أي وقت مضى.

كيفية تقليص ملف ibdata موجود:

http://dev.mysql.com/doc/refman/5.5/en/innodb-resize-system-tablespace.html

يمكنك كتابة هذا البرنامج وجدولة البرنامج النصي ليتم تشغيله بعد فترة زمنية محددة ، لكن بالنسبة للإعداد الموضح أعلاه ، يبدو أن مساحات الجداول المتعددة هي الحل الأسهل.

إذا كنت تستخدم خيار التكوين innodb_file_per_table ، فإنك تنشئ مساحات متعددة للجداول. بمعنى ، يقوم MySQL بإنشاء ملفات منفصلة لكل جدول بدلاً من ملف مشترك واحد. هذه الملفات منفصلة تخزينها في دليل قاعدة البيانات ، ويتم حذفها عند حذف قاعدة البيانات هذه. سيؤدي ذلك إلى إزالة الحاجة إلى تقليص/إزالة ملفات ibdata في قضيتك.

مزيد من المعلومات حول مساحات الجداول المتعددة:

http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html

33
titanoboa

إذا كنت تستخدم محرك تخزين InnoDB (لبعض) جداول MySQL ، فمن المحتمل أنك واجهت مشكلة في التكوين الافتراضي. كما قد تلاحظ في دليل بيانات MySQL (في Debian/Ubuntu -/var/lib/mysql) يوجد ملف يسمى lies ibdata1 ′. إنه يحتفظ بكافة بيانات InnoDB تقريبًا (ليس سجل معاملات) لمثيل MySQL وقد يكون كبيرًا جدًا. افتراضيًا ، يبلغ حجم هذا الملف 10 ميغابايت ، ويمتد تلقائيًا. لسوء الحظ ، لا يمكن تقليص ملفات بيانات InnoDB حسب التصميم. هذا هو السبب في أن DELETEs و TRUNCATEs و DROPs وغيرها لن يستعيدوا المساحة المستخدمة من قبل الملف.

أعتقد أنه يمكنك العثور على تفسير جيد والحل هناك:

http://vdachev.net/2007/02/22/mysql-reducing-ibdata1/

14
Vik

كتابتها بسرعة إجراء الإجابة المقبولة في باش:

#!/usr/bin/env bash
DATABASES="$(mysql -e 'show databases \G' | grep "^Database" | grep -v '^Database: mysql$\|^Database: binlog$\|^Database: performance_schema\|^Database: information_schema' | sed 's/^Database: //g')"
mysqldump --databases $DATABASES -r alldatabases.sql && echo "$DATABASES" | while read -r DB; do
    mysql -e "drop database \`$DB\`"
done && \
    /etc/init.d/mysql stop && \
    find /var/lib/mysql -maxdepth 1 -type f \( -name 'ibdata1' -or -name 'ib_logfile*' \) -delete && \
    /etc/init.d/mysql start && \
    mysql < alldatabases.sql && \
    rm -f alldatabases.sql

احفظ كـ purge_binlogs.sh وقم بتشغيل كـ root.

يستبعد mysql و information_schema و performance_schema (ودليل binlog).

يفترض أن لديك اعتمادات المسؤول في /root/.my.cnf وأن قاعدة البيانات الخاصة بك تعيش في دليل /var/lib/mysql الافتراضي.

يمكنك أيضًا إزالة السجلات الثنائية بعد تشغيل هذا البرنامج النصي لاستعادة المزيد من مساحة القرص باستخدام:

PURGE BINARY LOGS BEFORE CURRENT_TIMESTAMP;
7
Pierre-Alexis de Solminihac

إذا كان هدفك هو مراقبة المساحة الخالية لـ MySQL ولا يمكنك إيقاف MySQL لتقليص ملف ibdata ، فاحصل عليه من خلال أوامر حالة الجدول. مثال:

الخلية> 5.1.24:

mysqlshow --status myInnodbDatabase myTable | awk '{print $20}'

الخلية <5.1.24:

mysqlshow --status myInnodbDatabase myTable | awk '{print $35}'

ثم قارن هذه القيمة بملف ibdata الخاص بك:

du -b ibdata1

المصدر: http://dev.mysql.com/doc/refman/5.1/en/show-table-status.html

6
Cyno

في إصدار جديد من وصفات خادم mysql أعلاه سوف تسحق قاعدة بيانات "mysql". في الإصدار القديم يعمل. في بعض الجداول الجديدة ، يتم التبديل إلى نوع الجدول INNODB ، وبذلك ستؤدي إلى إتلافها. أسهل طريقة هي تفريغ جميع قواعد البيانات ، وإلغاء تثبيت خادم mysql ، والإضافة التي بقيت my.cnf:

[mysqld]
innodb_file_per_table=1


erase all in /var/lib/mysql
install mysql-server
restore users and databases
4
adjustable_wrench

كما ذكرنا سابقًا ، لا يمكنك تقليص ibdata1 (للقيام بذلك ، تحتاج إلى تفريغ وإعادة بناء) ، ولكن غالبًا ما لا توجد حاجة حقيقية لذلك.

باستخدام الإضافة التلقائية (ربما أكثر إعدادات الحجم شيوعًا) ، يقوم ibdata1 بتخصيص مساحة التخزين ، ويزداد في كل مرة يكون فيها ممتلئًا تقريبًا. هذا يجعل الكتابة أسرع حيث يتم تخصيص مساحة بالفعل.

عندما تقوم بحذف البيانات ، لا يتم تقليصها ولكن يتم وضع علامة على المساحة الموجودة داخل الملف. الآن عند إدراج بيانات جديدة ، ستعيد استخدام المساحة الفارغة في الملف قبل زيادة حجم الملف.

لذلك سوف تستمر في النمو فقط إذا كنت بحاجة فعليًا إلى هذه البيانات. ما لم تكن بحاجة بالفعل إلى مساحة لتطبيق آخر ، فليس هناك على الأرجح سبب لتقليص حجمها.

0
steveayre