Как сбросить частичное резервное копирование из большой MySql базы данных? - PullRequest
0 голосов
/ 31 января 2020

Эта топика c очень важна, потому что, может быть, нет точного ответа. У меня есть 22Gb MySql база данных в производственной среде. Но для целей теста мне нужно извлечь, например, 2 ГБ из базы данных, и это извлечение должно быть со всеми зависимостями (ключ, индекс, FK и т. Д. c). Как я могу выполнить это частичное извлечение в MySql База данных?

Ответы [ 2 ]

1 голос
/ 06 февраля 2020

С помощью Jailer вы можете экспортировать данные в сценарий SQL, который может обойти ограничения внешнего ключа и включить все данные, необходимые для сохранения ссылочной целостности.

https://github.com/Wisser/Jailer

1 голос
/ 31 января 2020

Этот запрос выбирает все имена таблиц из указанной базы данных и показывает их уровень в дереве внешних ключей.

WITH RECURSIVE
cte1 AS 
(
SELECT table_name, 
       referenced_table_name
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE table_schema = 'test'
  AND referenced_column_name IS NOT NULL
),
cte2 AS
(
SELECT t1.referenced_table_name name, 1 level
FROM cte1 t1
WHERE NOT EXISTS ( 
                 SELECT NULL
                 FROM cte1 t2
                 WHERE t1.referenced_table_name = t2.table_name
                 )
UNION ALL
SELECT cte1.table_name, cte2.level + 1
FROM cte1 
JOIN cte2 ON cte1.referenced_table_name = cte2.name
WHERE cte2.level <= (
                    SELECT COUNT(*)
                    FROM cte1
                    )
)
SELECT name, MIN(level) level
FROM cte2
GROUP BY name
ORDER BY name, level;

При повторном создании структуры базы данных или копировании данных из исходной базы данных в ее воссозданную копию необходимо обработать таблицы в указанном порядке.

При удалении таблиц вы должны делать это в обратном порядке.

В нормальном состоянии максимальное level значение не может превышать количество таблиц . Но возможно, что в структуре базы данных существует ссылочное кольцо. В таком случае максимальное level значение будет больше, чем количество таблиц, а вся техника неприменима .


В вашем конкретном случае вы:

  1. Выполните этот запрос (не забудьте заменить WHERE table_schema = 'test' вашим реальным именем базы данных).
  2. Создать новую базу данных.
  3. Для каждой строки в выводе (сохранение порядка) выполнить команду
CREATE TABLE new_database.{name} LIKE old_database.{name} ;
Для каждой строки на выходе, где level = 1 выполнить команду
INSERT INTO new_database.{name} 
SELECT * FROM old_database.{name} LIMIT {some_value};

some_value может быть одинаковым для всех root таблиц или отдельных.

Для каждой строки на выходе, где level > 1 выполнить команду
INSERT IGNORE INTO new_database.{name} 
SELECT * FROM old_database.{name} LIMIT {some_value};
Наслаждайтесь.

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

...