У меня 1.800 (innodb) БД в моем MariaDB 10.0, mysqldump работает очень медленно!
Если я запускаю mysqldump, процесс запускается:
"SELECT LOGFILE_GROUP_NAME, FILE_NAME, TOTAL_EXTENTS, INITIAL_SIZE, ENGINE, EXTRA FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'UNDO LOG' И FILE_NAME НЕ НУЛЕВО И LOGFILE_GROUP_NAME IN (
ВЫБЕРИТЕ DISTINCT LOGFILE_GROUP_NAME ИЗ INFORMATION_SCHEMA.FILES, ГДЕ FILE_TYPE = 'DATAFILE' И TABLESPACE_NAME IN (
ВЫБЕРИТЕ DISTINCT TABLESPACE_NAME ИЗ INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA IN ('table_test'))) GROUP BY LOGFILE_GROUP_NAME, FILE_NAME, ENGINE ORDER BY LOGFILE_GROUP_NAME "в information_schema
Как это исправить? Как отключить этот процесс в mysqldump?
Спасибо!
Редактировать:
Проблема в том подтверждено в MariaDB 10.0.8 и 5.5.36, и подтверждено, что его не существует в MySQL 5.5.36, по-видимому, из-за различий в реализации оптимизатора запросов.
Поэтому приведенный ниже текст корректируется в соответствии с рекомендациями Елены Степановой из MariaDB.
Я воспроизвел это поведение в MariaDB 10.0.8 на Debian wheezy. Мне не удалось воспроизвести это в MySQL 5.5.36.
Если вы выполните mysqldump -uroot
, или любого пользователя с полными правами, это генерирует запрос, который заставляет MySQL MySQL сканировать супердиректорию базы данных и все подкаталоги и все метаданные таблицы для все таблицы в этих подкаталогах.
Если вы выполняете mysqldump с определенными привилегиями пользователя, и им предоставлен доступ только к одной или двум базам данных, mysqldump работает так же быстро, как и следовало ожидать.
Есть два обходных пути.
Обход A по-прежнему использует сверхпривилегированного пользователя с доступом ко всем базам данных, но ускоряет процесс, отключив функцию полусоединения.
Обход B создает резервного пользователя, которому по очереди предоставляется доступ к каждой базе данных, сужая набор привилегий.
Какой метод лучше всего подходит для вас, зависит от того, насколько вам комфортно использовать сверхпривилегированного пользователя для доступа ко всем базам данных, сколько у вас баз данных, сколько у вас пользователей, имеющих доступ к нескольким базам данных, сколько баз данных имеют зависимости между ними, и как осуществляется доступ к вашей базе данных, пока вы делаете ее дампы.
Обход А, вероятно, самый быстрый, обход В немного медленнее.
Обход A - суперпривилегированный пользователь, отключенное полусоединение
Обратите внимание, что отключение полусоединения может повлиять на производительность других запросов. Хотя его можно установить в my.cnf, вам, вероятно, не следует этого делать.
Временно отключить полусоединение:
SET GLOBAL optimizer_switch='semijoin=off';
Выгрузите базу данных, например как пользователь "root":
mysqldump db -uroot -prootpassword | gzip > DB.sql.gz
Повторно включить полусоединение:
SET GLOBAL optimizer_switch='semijoin=on';
Обход B - отдельный пользователь резервного копирования
Предоставьте пользователю резервного копирования полные права доступа к базе данных:
GRANT USAGE ON `db`.* TO 'backup'@'%' IDENTIFIED BY 'backuppassword';
GRANT SELECT, LOCK TABLES ON `mysql`.* TO 'backup'@'%';
GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON `db`.* TO 'backup'@'%';
FLUSH PRIVILEGES;
Выгрузите базу данных от имени этого пользователя:
mysqldump db -ubackup -pbackuppassword | gzip > DB.sql.gz
Отозвать привилегии:
REVOKE ALL PRIVILEGES ON `db`.* FROM 'backup'@'%';
REVOKE ALL PRIVILEGES ON `mysql`.* FROM 'backup'@'%';
FLUSH PRIVILEGES;
Если каждая база данных принадлежит отдельному пользователю, и вы знаете пароли этих пользователей, вы, конечно, можете использовать их вместо пользователя резервного копирования и его пароля и тем самым полностью пропустить шаги 1 и 3.
Кстати: я также сообщил об этом команде разработчиков MariaDB, если у вас есть что-нибудь полезное, не стесняйтесь следить за этим здесь: