Linux / mysql: безопасно ли копировать файлы mysql db с помощью команды cp из одной базы данных в другую?

11

В большинстве руководств рекомендуется использовать mysqldump и простой SQL для копирования одной таблицы в другую базу данных. Как насчет командной оболочки Linux? Могу ли я просто сделать

cp /db1/mytable.frm /db2/mytable.frm

giorgio79
источник

Ответы:

21

Копирование очень просто для MyISAM и полностью 100% рискованно (почти самоубийственно) с InnoDB.

Из вашего вопроса вы воспитали

cp /db1/mytable.frm /db2/mytable.frm

MyISAM

Это нормально делать. Однако вы не можете просто переместить .frm. Вы должны переместить все компоненты. Из вашего вопроса, давайте возьмем таблицу с именем db1.mytable. В обычной установке таблица находится в / var / lib / mysql / db1. Там будет три файла, составляющих таблицу.

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.MYD (таблица базы данных)
  • /var/lib/mysql/db1/mytable.MYI (индексы таблиц)

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

Например, если вы хотите скопировать db1.mytable в базу данных db2, сделайте это:

CREATE TABLE db2.mytable LIKE db1.mytable;
ALTER TABLE db2.mytable DISABLE KEYS;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;
ALTER TABLE db2.mytable ENABLE KEYS;

Теперь, если вы просто перемещаете таблицу из db1 в db2, вы можете сделать это:

ALTER TABLE db1.mytable RENAME db2.mytable;

InnoDB

Копирование очень опасно из-за инфраструктуры, под которой работает InnoDB. Существует две основные инфраструктуры: 1) innodb_file_per_table отключена и 2) innodb_file_per_table включена

Ахиллесова пята InnoDB - это файл системного табличного пространства, известный как ibdata1 (обычно находится в / var / lib / mysql). Что содержится в этом файле ?

  • Страницы табличных данных
  • Таблицы указателей страниц
  • MetaData таблицы (список управления идентификаторами табличных пространств)
  • Данные MVCC (для поддержки изоляции транзакций и соответствия ACID )

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

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

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

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

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

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

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

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

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

Для InnoDB вам нужно только это

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

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

RolandoMySQLDBA
источник
4
В других ответах говорилось об этом, поэтому, возможно, это «само собой разумеется», но в любом случае это хорошо сказать: InnoDB продолжает запись в файлы, даже если база данных простаивает, поэтому копирование своих файлов во время работы MySQL почти наверняка приведет к повреждению! Вы можете завершить работу, сделать снимок файловой системы или использовать Percona XtraBackup, чтобы обойти это.
Барон Шварц
1
Отличный ответ, как всегда, @Rolando! Единственный большой вопрос, который у меня возникает: зачем кому-то это делать, а не делать прямой дамп и импорт MySQL? Я предполагаю большой размер базы данных, но чувствую, что это следует обсудить.
JakeGould
1
@JakeGould Загрузка сценария mysqldump в mysql требует обработки большого количества SQL, вставки тысяч строк за раз, использования циклов ЦП, запуска планов объяснения, перестройки индексов (вставки BTree, разбиения узлов листа, перебалансировки ключей, сканирования таблицы для каждого не - уникально для сборки) просто для производства одной и той же таблицы. В случае MyISAM, зачем изобретать велосипед? Просто копия .frm, .MYDи .MYI.
RolandoMySQLDBA
@JakeGould В случае InnoDB я скопировал действующую базу данных, которая использовала все InnoDB с rsync. После копирования с использованием rsync я запустил завершение работы mysql, выполнил окончательную rsync и перезапустил mysql без проблем. Я написал пост, как и раньше: serverfault.com/questions/288140/…
RolandoMySQLDBA
8

Копирование всего каталога данных MySQL является практическим методом, предполагая, что служба MySQL остановлена, и вы хотите скопировать весь сервер базы данных.

Это полезный метод для перемещения баз данных с большими индексами, и дамп mysql не будет включать индексы, которые необходимо будет восстановить во время импорта. Я нашел эту технику полезной при настройке подчиненных MySQL.

Копирование отдельного файла зависит от используемой схемы таблицы, но в большинстве случаев не является подходящим решением.

Coops
источник
2
Объяснение: вам не нужно останавливать службу как таковую, если ваша файловая система способна, вы можете либо сделать снимок LVM и сделать резервную копию этого; или заморозить саму файловую систему.
худенький
Пока личный персонал может есть простои, это самый простой способ. +1 !!!
RolandoMySQLDBA
2

Используйте xtrabackup w / ow без оболочки innobackupex, и все будет хорошо как с базами данных myisam, так и с базами данных innodb. Обратите внимание, что восстановление баз данных innodb - это не просто копирование файлов назад, даже если вы используете xtrabackup. Скажите, если вам нужно больше информации

Габор Винче
источник
1

Нет, вы должны выполнить резервное копирование с помощью mysqdump и восстановить с помощью утилиты mysql cli, копируя файл frm, вы копируете только структуру таблицы, а не данные внутри, а если вы находитесь в innodb, копировать файл напрямую невозможно.

Лучший способ - сбросить и восстановить таблицу.

aleroot
источник