Оптимизация MySQL для параллельного импорта массивных файлов данных.1 соединение на таблицу - PullRequest
6 голосов
/ 15 марта 2011

Я делаю некоторые подготовительные работы для миграции большого сайта.

Размер базы данных составляет около 10 ГБ, а в нескольких таблицах содержится более 15 миллионов записей. К сожалению, это происходит только в виде большого файла mysqldump в формате SQL из-за отношений с клиентами за пределами моей компетенции, но вы знаете, как это происходит. Моя цель - минимизировать время простоя и, следовательно, импортировать данные как можно быстрее.

Я попытался использовать стандартный интерфейс MySQL CLI следующим образом:

$mysql database_name < superhuge_sql_file -u username -p

Это, однако, очень медленно.

Чтобы попытаться ускорить процесс, я использовал awk, чтобы разбить файл на куски для каждой таблицы со связанными данными, и создал небольшой сценарий оболочки, чтобы попытаться импортировать таблицы параллельно, вот так;

#!/bin/sh

awk '/DROP TABLE/{f=0 ;n++; print >(file="out_" n); close("out_" n-1)} f{ print > file}; /DROP TABLE/{f=1}'  superhuge.sql

for (( i = 1; i <= 95; i++ )) 
do
    mysql -u admin --password=thepassword database_name < /path/to/out_$i &
done

Стоит отметить, что это скрипт «один раз и уничтожь» (пароли в скриптах и ​​т. Д.).

Теперь, это работает, но все еще занимает более 3 часов, чтобы завершить работу на четырехъядерном сервере, не делая ничего другого в настоящее время. Таблицы выполняют импорт параллельно, но не все сразу, и попытка получить информацию о сервере MySQL через интерфейс командной строки очень медленная во время процесса. Я не уверен, почему, но попытка получить доступ к таблицам, используя ту же учетную запись пользователя mysql, зависает, пока это происходит. max_user_connections не ограничено.

Я установил максимальное число соединений в my.cnf на 500, но в противном случае не настроил MySQL на этом сервере.

У меня была хорошая охота, но мне было интересно, есть ли какие-либо параметры конфигурации MySQL, которые помогут ускорить этот процесс, или какие-либо другие методы, которые я пропустил, будут быстрее.

Ответы [ 3 ]

5 голосов
/ 18 марта 2016

Если вы можете рассмотреть возможность использования GNU parallel, проверьте этот пример, найденный в wardbekker gist:

# Split MYSQL dump file
zcat dump.sql.gz | awk '/DROP TABLE IF EXISTS/{n++}{print >"out" n ".sql" }'
# Parallel import using GNU Parallel http://www.gnu.org/software/parallel/
ls -rS *.sql | parallel --joblog joblog.txt mysql -uXXX -pYYY db_name "<"

, который разбивает большой файл на отдельные файлы SQL, а затем запускает parallel для параллельной обработки.

Таким образом, чтобы запустить 10 потоков в GNU параллельно, вы можете запустить:

ls -rS data.*.sql | parallel -j10 --joblog joblog.txt mysql -uuser -ppass dbname "<"

В OS X это может быть:

gunzip -c wiebetaaltwat_stable.sql.gz | awk '/DROP TABLE IF EXISTS/{n++}{filename = "out" n ".sql"; print > filename}'

Источник: Вардбеккер / Гист: 964146


Related: Импорт файлов sql с использованием xargs в Unix.SE

0 голосов
/ 03 января 2019

Импорт файла дампа на сервер

$ sudo apt-get install pigz pv
$ zcat /path/to/folder/<dbname>_`date +\%Y\%m\%d_\%H\%M`.sql.gz | pv | mysql --user=<yourdbuser> --password=<yourdbpassword> --database=<yournewdatabasename> --compress --reconnect --unbuffered --net_buffer_length=1048576 --max_allowed_packet=1073741824 --connect_timeout=36000 --line-numbers --wait --init-command="SET GLOBAL net_buffer_length=1048576;SET GLOBAL max_allowed_packet=1073741824;SET FOREIGN_KEY_CHECKS=0;SET UNIQUE_CHECKS = 0;SET AUTOCOMMIT = 1;FLUSH NO_WRITE_TO_BINLOG QUERY CACHE, STATUS, SLOW LOGS, GENERAL LOGS, ERROR LOGS, ENGINE LOGS, BINARY LOGS, LOGS;"

Необязательно: Аргументы команд для соединения

--host=127.0.0.1 / localhost / IP Address of the Import Server
--port=3306

Дополнительные программные пакеты полезны для более быстрого импорта файла базы данных SQL

with a progress view (pv)
Parallel gzip (pigz/unpigz) to gzip/gunzip files in parallel

для более быстрого архивирования на выходе

В качестве альтернативы у вас есть диапазон параметров MySQL для

Экспорт

https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html

Импорт

https://dev.mysql.com/doc/refman/5.7/en/mysql-command-options.html

Конфигурация

https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html

https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html

Вот пример my.cnf, который я запускаю на своем сервере SSD Quad Core и обычно импортирует файл DB объемом 100 ГБ примерно за 8 часов. Но вы можете настроить свой сервер в соответствии с настройками, чтобы он мог писать гораздо быстрее.

Проверьте каждую переменную конфигурации, используя приведенную выше ссылку, чтобы сопоставить ваш MySQL Server с переменной и значениями.

# Edit values to as per your Server Processor and Memory requirements.
[mysqld]
# Defaults
pid-file = /var/run/mysqld/mysqld.pid
socket   = /var/run/mysqld/mysqld.sock
log-error = /var/log/mysql/error.log
datadir = /var/lib/mysql
log_timestamps = SYSTEM
character_set_server = utf8mb4
collation_server = utf8mb4_general_ci

# InnoDB
innodb_buffer_pool_size = 48G
innodb_buffer_pool_instances = 48
innodb_log_file_size = 3G
innodb_log_files_in_group = 4
innodb_log_buffer_size = 256M
innodb_log_compressed_pages = OFF
innodb_large_prefix = ON
innodb_file_per_table = true
innodb_buffer_pool_load_at_startup = ON
innodb_buffer_pool_dump_at_shutdown = ON
innodb_autoinc_lock_mode = 2
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 360
innodb_flush_neighbors = 0
innodb_flush_method = O_DIRECT
innodb_io_capacity = 2500
innodb_io_capacity_max = 5000
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_monitor_enable = all
performance_schema = ON

key_buffer_size = 32M
wait_timeout = 30
interactive_timeout = 3600
max_connections = 1000
table_open_cache = 5000
open_files_limit = 8000
tmp_table_size = 32M
max_heap_table_size = 64M

# Slow/Error
log_output = file
slow_query_log = ON
slow_query_log_file = /var/log/mysql/slow_query.log
long_query_time = 10
log_queries_not_using_indexes = ON
log_slow_rate_limit = 100
log_slow_rate_type = query
log_slow_verbosity = full
log_slow_admin_statements = ON
log_slow_slave_statements = ON
slow_query_log_always_write_time = 1
slow_query_log_use_global_control = all

# Query
join_buffer_size = 32M
sort_buffer_size = 16M
read_rnd_buffer_size = 8M
query_cache_limit = 8M
query_cache_size = 8M
query_cache_type = 1

# TCP
max_allowed_packet = 1G
0 голосов
/ 01 апреля 2011

Вставляет ли sql в дамп несколько строк?Использует ли дамп множественные вставки строк?(Или, может быть, вы можете предварительно обработать его?)

Этот парень охватывает множество основ, например:

  • Отключение индексов для импортаво много раз быстрее.
  • Отключить индексы MySQL, поэтому перед запуском импорта:

    ALTER TABLE `table_name` DISABLE KEYS;
    

    , затем после импорта измените его обратно:

    ALTER TABLE `table_name` DISABLE KEYS;
    
  • При использовании табличного типа MyISAM вместо этого используйте команду MySQL INSERT DELAYED, поэтому рекомендуется, чтобы MySQL записывал данные на диск, когда база данных простаивает.

  • Для таблиц InnoDB:используйте эти дополнительные команды, чтобы избежать большого доступа к диску:

    SET FOREIGN_KEY_CHECKS = 0;
    SET UNIQUE_CHECKS = 0;
    SET AUTOCOMMIT = 0;
    

    и в конце:

    SET UNIQUE_CHECKS = 1;
    SET FOREIGN_KEY_CHECKS = 1;
    COMMIT;
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...