Linux / mysql: чи безпечно копіювати файли mysql db командою cp з одного db в інший?


11

Більшість посібників рекомендують mysqldump та простий SQL для копіювання однієї таблиці в інший db. Як щодо linux shell CP? Чи можу я просто зробити

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

Відповіді:


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). Що міститься у цьому файлі ?

  • Сторінки даних таблиці
  • Сторінки покажчиків таблиць
  • Метадані таблиці (список управління ідентифікатором простору таблиць)
  • Дані 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.

ПОПЕРЕДЖЕННЯ (або НЕБЕЗПЕЧНО, як би сказав Робот у програші Lost in Space )

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

Я написав два повідомлення в 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.


4
Інші відповіді сказали це, тому, можливо, це "само собою зрозуміло", але все одно добре сказати: InnoDB продовжує писати у файли, навіть якщо база даних не працює, тому копіювання файлів під час роботи MySQL майже напевно спричинить корупцію! Ви можете закрити, зробити знімок файлової системи або використовувати Percona XtraBackup для вирішення цього питання.
Барон Шварц

1
Відмінна відповідь, як завжди, @Rolando! Єдине велике питання, яке у мене виникає: чому б хтось хотів це зробити, на відміну від прямого демпінгу та імпорту MySQL? Я припускаю, що саме розмір бази даних, але я вважаю, що це слід виховувати.
JakeGould

1
@JakeGould Завантаження сценарію mysqldump в mysql вимагає обробляти багато SQL, вставляти тисячі рядків одночасно, використовуючи цикли процесорів, виконувати роз'яснення планів, відновлення індексів (вкладки BTree, розріз листя вузла, перестановка ключів, сканування таблиці для кожного не -unique будувати) просто для створення тієї ж таблиці. Що стосується MyISAM, навіщо винаходити колесо? Просто скопіювати з .frm, .MYDі .MYI.
RolandoMySQLDBA

@JakeGould У випадку InnoDB я скопіював живу базу даних, яка використовувала всі InnoDB з rsync. Після копіювання за допомогою rsync я запустив відключення mysql, зробив остаточну rsync і без проблем перезапустив mysql. Я написав публікацію, як і раніше: serverfault.com/questions/288140/…
RolandoMySQLDBA

8

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

Це корисна методика для переміщення баз даних з великими індексами, а дамп mysql не буде включати індекси, які потрібно буде регенерувати під час імпорту. Я вважав цю техніку корисною під час налаштування рабів MySQL.

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


2
Щоб пояснити: вам не потрібно зупиняти службу як такої, якщо ваша файлова система здатна, ви можете виконати знімок LVM та створити резервну копію цього; або заморозити саму файлову систему.
thinice

Поки особисті можуть їсти простої, це найпростіший спосіб. +1 !!!
RolandoMySQLDBA

2

Використовуйте xtrabackup без оболонки innobackupex, і вам буде добре як в базі даних myisam, так і в innodb. Зауважте, що відновлення баз даних innodb - це не просто копіювання файлів назад, навіть якщо ви використовуєте xtrabackup. Скажіть, якщо вам потрібна додаткова інформація


1

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

Найкращий спосіб - скинути та відновити таблицю.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.