MySQL Socket отказывается от подключения после тысяч последовательных подключений

В настоящее время я пытаюсь заполнить базу данных MySQL5.1 на текущей машине Ubuntu с> 5 000 000 записей. Из-за архитектуры программы для каждого оператора INSERT открывается и закрывается новое соединение с базой данных. Я знаю, что это дорогостоящая операция, но для ее изменения потребуется изменить уйму кода, поэтому я бы предпочел этого избежать.

Проблема, с которой я столкнулся, заключается в том, что через некоторое время (обычно около 12 секунд, но это число увеличивается после нескольких повторных попыток) этот процесс больше не может подключиться к базе данных . Другие процессы могут подключаться к базе данных без каких-либо проблем.

Я не думаю, что это проблема MySQL, потому что ни один из журналов MySQL не сообщает об ошибках. Кроме того, одновременно открыто не более 1 соединения (что я проверил, взглянув на переменные состояния MySQL).

Вопрос. Существует ли ограничение на количество последовательных подключений к сокету, которое может быть открыто в заданный период времени?

Вот упрощенный perl-скрипт (фактическая программа на Java), который приводит к той же проблеме (переменные базы данных не включены):

# ...
my $i = 0;
my $DBH = 0;
for ($i = 0;$i < $MAX; ++$i) {
  $DBH = DBI->connect("DBI:mysql:$DBNAME:$DBHOST:$DBPORT", $DBUSER, $DBPW)
    or die ("Error - Connection to database failed: \n   $i times ok\n".DBI->errstr);

  $DBH -> disconnect;
  if ($i % 10000 == 0) {
    print $i. " ";
  }
}

Вопрос. Есть предложения/идеи?


person Tobieh    schedule 05.02.2011    source источник


Ответы (2)


попробуйте увеличить количество разрешенных подключений в /etc/mysql/my.cnf?

max_connections        = 300

если php, изменить все экземпляры mysql_connect() на mysql_pconnect()?

person Allen    schedule 08.02.2011
comment
одновременно открыто не более 1 соединения, так что это не проблема! - person Tobieh; 08.02.2011

Поскольку вы, кажется, очень быстро открываете и закрываете сокеты TCP, вы можете накапливать сокеты в состоянии TIME_WAIT (см. its-design-implications-for-protocols-and-scalable-servers.html" rel="nofollow">здесь), и в Linux это может привести к исчерпанию файловых дескрипторов процесса (тогда как в Windows это вероятно, проявляется во всех процессах в одном и том же блоке, которые не могут подключиться, а не только в одном процессе, поскольку нет ограничений на количество сокетов для каждого процесса).

Запустите netstat как на клиентской машине, на которой выполняется код вставки, так и на сервере, на котором находится база данных.

Если вы накапливаете сокеты в TIME_WAIT, то что вам нужно делать, зависит от того, где они находятся (клиент или сервер).

person Len Holgate    schedule 08.02.2011
comment
но это, скорее всего, проявляется в том, что все процессы в одном и том же компьютере не могут подключиться, а не только один процесс. Я не согласен. Процессу, вероятно, не хватает файловых дескрипторов, которые выделяются для каждого процесса отдельно. - person Lightness Races in Orbit; 08.02.2011
comment
Хорошее предложение! Однако я решил адаптировать код для использования постоянного соединения. Несмотря на то, что это было много работы, оно того стоило, потому что теперь оно работает! - person Tobieh; 08.02.2011
comment
Я уверен, что это лучшее решение. - person Len Holgate; 08.02.2011