SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 17.10.2008 19:30:14

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

MySQL+Perl: Необходимость паузы между запросами?

Приветствую.

Ситуация:
Windows XP SP3+
MySQL: 4.1.22, 5.0.67, 5.1.28
ActivePerl: 5.8.7.815, 5.10.0.1004
DBD-mysql: 3.0002, 4.005

Скрипт многократно в цикле читает данные из таблицы (~120000 записей древовидной структуры), преобразовывает их и пишет в файл.

На компьютере 700МГц+512МБ работает штатно.
На компьютерах 2x3400МГц+1024МБ и 2x3400МГц+2048МБ:
. завершается с ошибкой выполнения селекта через несколько сотен запросов;
. если после завершения селекта по $sth -> finish() поставить:
. . sleep(1) - то же самое.
. . sleep(2) - работает, но, что очевидно, недопустимо медленно.

Сталкивался кто-нибудь с подобным?

Неактивен

 

#2 17.10.2008 19:48:34

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: MySQL+Perl: Необходимость паузы между запросами?

А какая ошибка выполнения селекта?

Полагаю, дело не в железе, а то, что в одном случае это тестовая база, а во втором - боевая.
В боевой есть еще какие-то запросы, наверняка, которые могут лочить/что-то еще.

Без текста ошибки, боюсь, не справимся smile

UPD:
Подумал, что никогда не пользуюсь finish, залез в CPAN, с интересом увидел, что не зря:
http://search.cpan.org/~timb/DBI-1.607/DBI.pm#finish

У Вас какие-то принципиальные соображения на этот счет?

Неактивен

 

#3 17.10.2008 19:58:58

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

Не знаю.

В условии if ( !$sth->execute() )

$dbh->err() и if $dbh->errstr() пустые

Неактивен

 

#4 17.10.2008 20:02:32

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

paulus написал:

Подумал, что никогда не пользуюсь finish, залез в CPAN, с интересом увидел, что не зря:
http://search.cpan.org/~timb/DBI-1.607/DBI.pm#finish

У Вас какие-то принципиальные соображения на этот счет?

Привычка закрывать сессию или объект.

Удаление finish не повлияло ни на что.

Неактивен

 

#5 17.10.2008 20:10:30

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: MySQL+Perl: Необходимость паузы между запросами?

Насколько я понимаю, нужно именно $dbh->errstr...

Насколько большие получаются выборки данных? Все 120к записей? Используете ли
mysql_use_result, если да?

Можете ли параллельно открыть отдельный коннект сразу после завершения вот этой
"подвисшей" операции и спросить "SHOW PROCESSLIST" - что будет написано для вот
этого "подвисшего" соединения?

Неактивен

 

#6 17.10.2008 20:20:39

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

Реакции никакой в:          $err.= " err:[".$dbh->errstr()."]"    if $dbh->errstr();

Сейчас вылетает на 2826 записи. Место вылета стабильное. Иногда меняется не понятно почему.

Show processlist выдаёт одну строку. Если успеть во время выполнения, то две.

Отредактированно Uniol (17.10.2008 20:37:13)

Неактивен

 

#7 17.10.2008 20:36:56

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

Как использовать mysql_use_result в DBI?

В варианте $sth = $dbh->prepare($cmd { "mysql_use_result" => 1});

получаю

Global symbol "%cmd" requires explicit package at ...

Неактивен

 

#8 17.10.2008 20:42:26

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: MySQL+Perl: Необходимость паузы между запросами?

$dbh->{'mysql_use_result'}=1;

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

А что за строки show processlist? Состояние Sleep или что-то еще?

Неактивен

 

#9 17.10.2008 20:52:53

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

С $dbh->{'mysql_use_result'}=1; вылетет на 2й строке
Без неё на 3102-й

О! Один косяк исправил.    $sth->finish() был до $dbh->errstr()
Ошибка
Commands out of sync; you can't run this command now

Неактивен

 

#10 17.10.2008 20:54:39

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

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

Неактивен

 

#11 17.10.2008 20:56:41

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

У консоли Query, у скрипта Sleep

Неактивен

 

#12 17.10.2008 23:53:50

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

С    $dbh->{'mysql_use_result'}=1 вылетет на 2й    строке с "Commands out of sync; you can't  run this command now"
Без $dbh->{'mysql_use_result'}=1 вылетет на 293й строке с "Table '' is read only"

Это косяк BDI? Как вывернуться?

Неактивен

 

#13 18.10.2008 16:15:21

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

Не могу найти, как с ->{'mysql_use_result'}=1 выполнить подряд много ->prepare c ->execute.
Во всех примерах только один раз.
Не коннектиться же заново...

Неактивен

 

#14 20.10.2008 12:59:43

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: MySQL+Perl: Необходимость паузы между запросами?

А сам сценарий секретный? Можете показать его содержимое?

Ошибка "Commands out of sync; you can't run this command now" обычно возникает тогда,
когда Вы недовытащили данные предыдущего запроса, а хотите в этом же соединении
подготовить следующий запрос.

Неактивен

 

#15 20.10.2008 23:38:24

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

Скрипт вовсе не секретный. См: http://forum.ixbt.com/topic.cgi?id=24:41199
По-хорошему, его надо почистить от мусора... Но проблема не в нём.
Как я понял, ->{'mysql_use_result'}=1 можно использовать, если в скрипте один проход по таблицам, а в моём случае их много.
Насколько я понимаю, это глюк интерфейса в чистом виде.

Неактивен

 

#16 21.10.2008 22:37:34

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: MySQL+Perl: Необходимость паузы между запросами?

А что за модуль dbase? Какая-то надстройка над DBI?

Я не уверен, что закрывать надо sth->finish. Скорее всего, в обертке есть
своя функция закрытия, которую надо использовать.

Мой совет - переписать, используя DBI. Будет и проще, и работать будет.

Неактивен

 

#17 22.10.2008 11:14:05

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

Закрывать объёкты лучше в явном виде и не полагаться на сборщики мусора. sth->finish - корректное закрытие запроса.

dbase - "надстройка" над DBI.

пример функции go из пакета dbase:

sub go
{
  my ($this, $cmd, $label) = @_;

  my $dbh = $this->{_}{dbh};

  my $sth;

  return    if !$cmd;
  $label = ""    if !$label;

  if ( !$this->{_}{error} )
  {
    if ( !$dbh ) { print "dbase.pm:go:dbh:'$cmd'<br>"; }
    else
    {
      if ( $sth = $dbh->prepare($cmd) )
      {
    if ( !$sth->execute() )
    {
      $this->error("'$label'::[".$dbh->err()."]".$dbh->errstr().": [$cmd]");

      $sth->finish(); undef $sth;
    }
      }
      else
      {
    $label = ""    if !defined($label);

    $this->error("Cannot prepare in '$label'.[$cmd]");
      }
    }
  }

  return $sth;
}

Каждый раз писать это в явном виде, полагаю, не правильно.

ЗЫ

На MySQL 6 alpha+ActivePerl-5.10.0.1004+DBI 4.005 работает со sleep(1).

Точно косяк. Было бы время, покопался бы с исходниками DBI.

Отредактированно Uniol (22.10.2008 13:11:35)

Неактивен

 

#18 22.10.2008 15:54:16

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

Кстати. MySQL 6.0 при {'mysql_use_result'}=0 выдаёт при вылете ошибку: File: 'C:\WINDOWS\TEMP\#sql_c32_0.MAD' is read only

Количество селектов до вылета не постоянно.

Антивирусы и пр. отключал. На результат не влияет.

Неактивен

 

#19 22.10.2008 18:50:52

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: MySQL+Perl: Необходимость паузы между запросами?

Закрывать объёкты лучше в явном виде и не полагаться на сборщики мусора.
sth->finish - корректное закрытие запроса.

Будьте последовательны. Или пользуйтесь "высокими" технологиями типа крутых (?)
библиотек и используйте их способы доступа к БД, или используйте то, чем пользуется
весь остальной мир - DBI - и тогда закрывайте запросы правильно.

Неактивен

 

#20 22.10.2008 19:41:51

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

DBI устраивало, пока работало.

Как правильно закрывать в DBI, если не по $sth->finish()?

Отредактированно Uniol (22.10.2008 19:45:47)

Неактивен

 

#21 24.10.2008 03:24:34

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: MySQL+Perl: Необходимость паузы между запросами?

То, что является надстройкой над DBI, все-таки, его использует. Поэтому не надо
надеяться, что надстройка будет работать при том, что не работает базовое.

Другое дело, что базовое оттачивалось годами, и используется тысячами программистов
по всему миру. Вероятность того, что оно не работает - очень мала. Хотя, конечно,
опять-таки зависит от реализации.

Я бы на Вашем месте переписал всё на чистом DBI, причем с нормальными
плейсхолдерами, то, что называется "by the book".

Альтернативный вариант - попробовать другую сборку perl (можно и самому собрать,
кстати). Что ActivePerl меняет в исходниках - никому не известно.

Неактивен

 

#22 27.10.2008 11:28:11

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

Я так понимаю, тема себя исчерпала.
Предлагаются удары в бубен и камлание. А так же вера в непогрешимость тыщ программистов, годами оттачивавших DBI, который не смотря на все усилия не имеет ни средств трассировки, ни нормальных сообщений об ошибках.

Ладно. Благодарю Вас, коллега, за консультации.

Кстати, камлание выявило забавное свойство.
При последовательных запусках скрипта количество обрабатываемых записей увеличивается. То есть, запрашивается некий страничный ресурс, при нехватке которого происходит дополнительное его выделение, но система возвращает ошибку. Именно в момент выделения в папке для временных файов появляются два файла по 8К с расширениями MAD и MAI.

Отредактированно Uniol (27.10.2008 12:15:37)

Неактивен

 

#23 06.11.2008 13:13:13

Uniol
Участник
Зарегистрирован: 17.10.2008
Сообщений: 16

Re: MySQL+Perl: Необходимость паузы между запросами?

Проблема решилась после замены типа данных для одного из полей таблицы с text на varchar(512).

Данный скрипт писался давно для mysql 3.х у которого тип varchar был не длиннее 255 и данные в нем не помещались.

В общем, как и ожидалось, причина - кривой интерфейс.

Отредактированно Uniol (06.11.2008 13:13:38)

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson