it-swarm-eu.dev

Jak zmenšit/vyčistit soubor ibdata1 v MySQL

Používám MySQL v localhost jako "dotazovací nástroj" pro provádění statistik v R, to je, pokaždé, když jsem spustit R skript, jsem vytvořit novou databázi (A), vytvořit novou tabulku (B), importovat data do B , odešlete dotaz, abyste dostali to, co potřebuji, a pak pustím B a pustím A.

Je to v pořádku pro mě, ale uvědomuji si, že velikost souboru ibdata rychle roste, v MySQL jsem nic neuložila, ale soubor ibdata1 již překročil 100 MB.

Používám více či méně výchozí nastavení MySQL pro nastavení, existuje způsob, jak mohu automaticky zmenšit/vyčistit soubor ibdata1 po pevně stanovené době?

530
lokheart

To, že ibdata1 se nezmenšuje, je zvláště nepříjemnou vlastností MySQL. Soubor ibdata1 nemůže být ve skutečnosti zmenšen, pokud nevymažete všechny databáze, odstraníte soubory a znovu načtete výpis.

MySQL však můžete konfigurovat tak, aby každá tabulka včetně jejích indexů byla uložena jako samostatný soubor. Tímto způsobem ibdata1 nebude růst tak velký. Podle Bill Karwinův komentář to je standardně zapnuto jako verze 5.6.6 MySQL.

Bylo to před chvílí, co jsem to udělal. Chcete-li však nastavit server tak, aby používal samostatné soubory pro každou tabulku, musíte změnit my.cnf, aby to bylo možné:

[mysqld]
innodb_file_per_table=1

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

Chcete-li obnovit prostor z ibdata1, musíte soubor odstranit:

  1. Proveďte mysqldump všech databází, postupů, spouštěčů atd. kromě databází mysql a performance_schema
  2. Zrušení všech databází kromě výše uvedených 2 databází
  3. Zastavte mysql
  4. Smazat soubory ibdata1 a ib_log
  5. Spusťte mysql
  6. Obnovení z výpisu

Při spuštění MySQL v kroku 5 budou soubory ibdata1 a ib_log znovu vytvořeny.

Teď jsi hoden jít. Když vytvoříte novou databázi pro analýzu, tabulky budou umístěny v samostatných souborech ibd*, nikoli v ibdata1. Když databázi brzy opustíte, soubory ibd* budou smazány.

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

Pravděpodobně jste to viděli:
http://bugs.mysql.com/bug.php?id=1341

Pomocí příkazu ALTER TABLE <tablename> ENGINE=innodb nebo OPTIMIZE TABLE <tablename> lze extrahovat data a indexové stránky z ibdata1 do samostatných souborů. Ibdata1 se však nezmění, pokud neprovedete výše uvedené kroky.

Co se týče information_schema, není to nutné ani možné. Je to vlastně jen pár pohledů jen pro čtení, nikoli tabulky. A nejsou s nimi spojeny žádné soubory, dokonce ani databázový adresář. informations_schema používá paměťový db-engine a po zastavení/restartu mysqld je zrušen a regenerován. Viz https://dev.mysql.com/doc/refman/5.7/en/information-schema.html .

748
John P

Přidání do odpovědi Johna P ,

U linuxového systému lze pomocí těchto příkazů provést kroky 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 (a smazat další ib_logfile, které mohou být pojmenovány ib_logfile0, ib_logfile1 atd ...)
  5. Sudo /etc/init.d/mysqld start
  6. create database [database_name];
  7. mysql -u [username]-p[root_password] [database_name] < dumpfilename.sql

Upozornění: tyto instrukce způsobí ztrátu jiných databází, pokud máte v této instanci mysql jiné databáze. Ujistěte se, že kroky 1,2 a 6,7 ​​jsou upraveny tak, aby zahrnovaly všechny databáze, které si chcete ponechat.

42
Vinay Vemula

Když smažete tabulky inodb, MySQL neuvolní prostor uvnitř souboru ibdata, to je důvod, proč stále roste. Tyto soubory se sotva zmenšují.

Jak zmenšit existující soubor ibdata:

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

Můžete to skriptovat a naplánovat spuštění skriptu po pevně stanovené době, ale pro nastavení popsané výše se zdá, že více tabulkových prostorů je jednodušší.

Pokud použijete volbu innodb_file_per_table, vytvoříte více tabulkových prostorů. MySQL tedy vytváří samostatné soubory pro každou tabulku namísto jednoho sdíleného souboru. Tyto oddělené soubory jsou uloženy v adresáři databáze a při odstranění této databáze jsou odstraněny. To by mělo odstranit potřebu zmenšit/vyčistit soubory ibdata ve vašem případě.

Další informace o více tabulkových prostorech:

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

33
titanoboa

Pokud používáte úložný modul InnoDB pro (některé) tabulky MySQL, pravděpodobně jste již narazili na problém s jeho výchozí konfigurací. Jak jste si možná všimli v datovém adresáři MySQL (v Debianu/Ubuntu -/var/lib/mysql) leží soubor nazvaný „ibdata1 ′“. Obsahuje téměř všechna data InnoDB (není to transakční protokol) instance MySQL a může být dost velká. Ve výchozím nastavení má tento soubor počáteční velikost 10 MB a automaticky se rozšiřuje. Bohužel podle návrhu nelze datové soubory InnoDB zmenšit. To je důvod, proč DELETEs, TRUNCATEs, DROPs atd. Neobnoví prostor používaný souborem.

Myslím, že zde můžete najít dobré vysvětlení a řešení:

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

14
Vik

Rychlý zápis procedury přijaté odpovědi do bash:

#!/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

Uložit jako purge_binlogs.sh a spustit jako root.

Nezahrnuje mysql, information_schema, performance_schema (a binlog adresář).

Předpokládá se, že máte v /root/.my.cnf pověření administrátora a že vaše databáze žije ve výchozím adresáři /var/lib/mysql.

Po spuštění tohoto skriptu můžete také vyčistit binární protokoly, abyste získali více místa na disku pomocí:

PURGE BINARY LOGS BEFORE CURRENT_TIMESTAMP;

Pokud je vaším cílem sledovat MySQL volné místo a nemůžete zastavit MySQL, aby zmenšil váš soubor ibdata, pak si to prostudujte přes příkazy stavu tabulky. Příklad:

MySQL> 5.1.24:

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

MySQL <5.1.24:

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

Poté porovnejte tuto hodnotu s vaším souborem ibdata:

du -b ibdata1

Zdroj: http://dev.mysql.com/doc/refman/5.1/en/show-table-status.html

6
Cyno

V nové verzi mysql-server recepty výše bude rozdrtit "mysql" databáze. Ve staré verzi to funguje. V nových tabulkách se přepne na typ tabulky INNODB a tím se poškodí. Nejjednodušším způsobem je vypsat všechny databáze, odinstalovat mysql-server, přidat zůstal my.cnf:

[mysqld]
innodb_file_per_table=1


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

Jak již bylo zmíněno, nemůžete zmenšovat ibdata1 (abyste tak učinili, musíte vypálit a znovu sestavit), ale často to také není potřeba.

Pomocí autoextendu (pravděpodobně nejběžnějšího nastavení velikosti) ibdata1 předdefinuje úložiště, které roste pokaždé, když je téměř plné. Díky tomu je zápis rychlejší, protože prostor je již přidělen.

Když data odstraníte, nezmrští se, ale prostor uvnitř souboru je označen jako nepoužitý. Nyní, když vložíte nová data, znovu použije prázdné místo v souboru před dalším rozšiřováním souboru.

Takže to bude jen nadále růst, pokud budete potřebovat ta data. Pokud ve skutečnosti nepotřebujete prostor pro jinou aplikaci, není důvod, aby se to zmenšilo.

0
steveayre