Почему InnoDB хранит все базы данных в одном файле?

51

Было удобно, что MyISAM использовал для хранения каждой таблицы в соответствующем файле. InnoDB сделал успехи во многих аспектах, но мне интересно, почему InnoDB хранит все базы данных в одном файле ( ibdata1по умолчанию).

Я понимаю, что InnoDB будет отображать расположение данных в файле по отдельным индексным файлам для таблиц, но я не понимаю, почему он смешивает все данные в одном файле. И что более важно, зачем смешивать данные всех баз данных на сервере?

Интересной особенностью MyISAM является то, что можно скопировать / вставить папку базы данных на другой компьютер, а затем использовать базу данных (без дампа).

Googlebot
источник

Ответы:

67

Архитектура InnoDB требует использования четырех основных типов информационных страниц

  • Страницы табличных данных
  • Таблицы указателей страниц
  • Метаданные таблицы
  • Данные MVCC (для поддержки изоляции транзакций и соответствия ACID )
    • Откат сегментов
    • Отменить пробел
    • Double Write Buffer (фоновая запись для предотвращения зависимости от кэширования ОС)
    • Вставить буфер (управление изменениями в неуникальных вторичных индексах)

См. Графическое представление ibdata1

По умолчанию innodb_file_per_table отключен. Это приводит к тому, что все четыре типа информационных страниц получают один файл с именем ibdata1. Многие люди пытаются распространить данные, создав несколько файлов ibdata. Это может привести к фрагментации данных и индексных страниц.

Вот почему я часто рекомендую очистить инфраструктуру InnoDB, используя файл ibdata1 по умолчанию и ничего более .

Копирование очень опасно из-за инфраструктуры, в которой работает InnoDB. Есть две основные инфраструктуры

  • innodb_file_per_table отключен
  • innodb_file_per_table включен

InnoDB ( innodb_file_per_table отключен)

При отключенном innodb_file_per_table все эти типы информации InnoDB находятся в ibdata1. Единственным проявлением любой таблицы InnoDB за пределами ibdata1 является файл .frm таблицы InnoDB. Копирование всех данных InnoDB за один раз требует копирования всех файлов / var / lib / mysql.

Копирование отдельной таблицы InnoDB абсолютно невозможно. Необходимо извлечь дамп MySQL, чтобы извлечь дамп таблицы в виде логического представления данных и соответствующих им определений индекса. Затем вы должны загрузить этот дамп в другую базу данных на том же сервере или на другом сервере.

InnoDB ( innodb_file_per_table включен)

Если включен параметр innodb_file_per_table , данные таблицы и ее индексы находятся в папке базы данных рядом с файлом .frm. Например, для таблицы db1.mytable проявлением этой таблицы InnoDB вне ibdata1 будет:

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

Системное табличное пространство ibdata1

Все метаданные для db1.mytable по-прежнему хранятся в ibdata1, и это абсолютно невозможно . Журналы повторов и данные MVCC также все еще живут с ibdata1.

Когда дело доходит до фрагментации таблицы, вот что происходит с ibdata1:

  • innodb_file_per_table включен : вы можете сжать db1.mytables сALTER TABLE db1.mytable ENGINE=InnoDB;илиOPTIMIZE TABLE db1.mytable;. Это приводит к тому, что /var/lib/mysql/db1/mytable.ibd физически меньше, без фрагментации.
  • innodb_file_per_table отключен : вы не можете сжать db1.mytables сALTER TABLE db1.mytable ENGINE=InnoDB;илиOPTIMIZE TABLE db1.mytable;потому, что он находится с ibdata1. Фактически, запустив любую команду, вы сделаете таблицу смежной и быстрее будете читать и писать. К сожалению, это происходит в конце ibdata1. Это заставляет ibdata1 быстро расти. Об этом полностью говорится в моем сообщении по очистке InnoDB .

ВНИМАНИЕ (или ОПАСНОСТЬ, как сказал бы робот в «Затерянном космосе» )

Если вы думаете просто о копировании файлов .frm и .ibd, вы стоите в очереди на мир причинения вреда. Копирование файлов .frm и .ibd таблицы InnoDB хорошо только тогда и только тогда, когда вы можете гарантировать, что идентификатор табличного пространства файла .ibd точно соответствует записи идентификатора табличного пространства в метаданных файла ibdata1 .

Я написал два сообщения в DBA StackExchange об этой концепции идентификатора табличного пространства

Вот отличная ссылка о том, как заново присоединить любой файл .ibd к ibdata1 в случае несовпадения идентификаторов табличного пространства: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Прочитав это, вы должны сразу же понять, что копировать файлы .ibd просто безумие.

Для InnoDB, вам нужно только что-то это переместить

CREATE TABLE db2.mytable LIKE db1.mytable;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;

сделать копию таблицы InnoDB.

Если вы переносите его на другой сервер БД, используйте mysqldump.

Что касается смешивания всех таблиц InnoDB из всех баз данных, я действительно вижу мудрость в этом. В моей компании, занимающейся базой данных и веб-хостингом, у меня есть один клиент MySQL, у которого есть таблица в одной базе данных, ограничения которой сопоставлены с другой таблицей в другой базе данных в том же экземпляре MySQL. Благодаря единому хранилищу метаданных он обеспечивает поддержку транзакций и работоспособность MVCC в нескольких базах данных.

RolandoMySQLDBA
источник
Означает ли это, когда я использую файл innodb для каждой таблицы, и если мне нужно импортировать мои данные с одного сервера на другой, мне придется использовать только mysqldump, а не какие-либо другие инструменты, такие как Percona xtrabackup?
tesla747
14

Вы можете переключить InnoDB для хранения таблиц в файле, добавив innodb-file-per-table в ваш cnf.

Innodb действительно просто заботится о страницах данных на базовом уровне. На самом деле, вы можете настроить InnoDB на использование только блочного устройства без файловой системы, как раньше! http://dev.mysql.com/doc/refman/5.5/en/innodb-raw-devices.html

Для хранения таблиц для файла существуют такие удобства, как возможность более легкого восстановления используемого пространства с помощью оптимизации.

Даже при наличии файлов в таблице вы не можете просто так скопировать файлы ibd, так как InnoDB является транзакционным и хранит информацию о своем состоянии в глобально общих файлах ibdata / log.

Это не значит, что это невозможно сделать. Если таблица находится в автономном режиме, вы можете удалить / импортировать табличные пространства и скопировать .idbs вокруг http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html

atxdba
источник
Без сомнения, InnoDB - гибкий механизм, но я не понимаю, как выгодно хранить все данные в одном файле (поскольку эта новая структура была реализована в InnoDB по сравнению с MyISAM).
Googlebot
Я думаю, что это одна из тех вещей, которые задним числом - это 20/20. Опция file per table была добавлена ​​после того, как innodb впервые сошел с полок. Помимо предоставления своего собственного блочного устройства, чтобы избежать накладных расходов на файловую систему, я не могу представить причину, по которой лучше выгрузить их все вместе (и вся вещь о блочном устройстве - это собственная дискуссия). Все мои настройки innodb имеют включенный файл для каждой таблицы.
atxdba
В том-то и дело, что не полагаться на файловую систему может быть бесценным, но она по умолчанию не активна. Таким образом, несколько пользователей будут использовать его.
Googlebot
1
Опция «один файл на таблицу» может нанести вред, если у вас много таблиц и мало оперативной памяти (например, в магазине Magento может быть около 1000 таблиц). И настройки открытых файлов тоже должны быть оптимизированы (с учетом ограничений ОС). Поэтому используйте с осторожностью.
ypercubeᵀᴹ
Это, безусловно, может ослабить усилия по восстановлению. Да, у вас должна быть резервная копия, но если у вас ее нет, InnoDB усложняет ситуацию из-за этой структуры.
Микато
10

Это поведение по умолчанию, но не обязательно. Из документов MySQL, используя табличные пространства для таблиц :

По умолчанию все таблицы и индексы InnoDB хранятся в системном табличном пространстве. В качестве альтернативы вы можете хранить каждую таблицу InnoDB и ее индексы в своем собственном файле . Эта функция называется «несколько табличных пространств», поскольку каждая таблица, которая создается, когда этот параметр действует, имеет свое собственное табличное пространство.

Что касается того, почему, вероятно, причина в разных архитектурах двух движков (MyISAM и InnoDB). Например, в InnoDB вы не можете просто скопировать файл .ibd в другую базу данных или установку. Пояснение (с той же страницы):

Вопросы переносимости файлов .ibd

Вы не можете свободно перемещать файлы .ibd между каталогами базы данных, как это можно делать с помощью файлов таблиц MyISAM. Определение таблицы, хранящееся в общем табличном пространстве InnoDB, включает имя базы данных. Идентификаторы транзакций и порядковые номера журналов, хранящиеся в файлах табличных пространств, также различаются в разных базах данных.

ypercubeᵀᴹ
источник
Очень информативный ответ и прояснение вопроса, но все же мне любопытно, как большой файл, содержащий все базы данных, может улучшить производительность (если это так).
Googlebot
Производительность не лучше из-за наличия одного файла для всех. Различные характеристики, такие как блокировка на уровне строк, а не на уровне таблиц, помогают повысить производительность. И, конечно же, главное преимущество - это транзакции и ограничения FK (и, следовательно, целостность базы данных).
ypercubeᵀᴹ
1
Вы совершенно правы в отношении честности! Я понимаю, почему лучше поместить все таблицы базы данных в один отдельный файл; но я не понимаю, зачем помещать все базы данных (которые полностью независимы) в один файл. InnoDB по умолчанию использует только один файл для хранения данных.
Googlebot