Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Постоянное выпадение в лог, ошибки DBD driver...


Автор: Grond 21.5.2013, 07:17
Периодически падает мускул.
В лог выдает такие ошибки:

[Fri May 17 08:06:30 2013] [error] RAC=1, DB=DBI:: db=HASH(0x7fc8f2439420) in DBD driver has not implemented the AutoCommit attribute at /home/dnc/pm/DC_DB.pm line 31.

по указанному месту в файле такой кусок прописан:

Код

$DataBase->{'AutoCommit'}=1;
  };
  if($@){
   die "$@" if $RepeatInit;
   $RepeatInit=1;
   warn '['.localtime()."] [error] RAC=$RollbackAndContinue, DB=${$DataBaseVarRef} in $@";
   undef $RollbackAndContinue;
   undef ${$DataBaseVarRef};
   redo ReInit;


Что это может быть и как исправить?

Автор: arto 21.5.2013, 07:44
perldoc DBD::mysql

...
    *   Switching AutoCommit mode from on to off or vice versa may fail. You should always check for errors,
        when changing AutoCommit mode. The suggested way of doing so is using the DBI flag RaiseError. If
        you don't like RaiseError, you have to use code like the following:

          $dbh->{'AutoCommit'} = 0;
          if ($dbh->{'AutoCommit'}) {
            # An error occurred!
          }

    *   If you detect an error while changing the AutoCommit mode, you should no longer use the database
        handle. In other words, you should disconnect and reconnect again, because the transaction mode is
        unpredictable. Alternatively you may verify the transaction mode by checking the value of the server
        variable autocommit. However, such behaviour isn't portable.
...

Автор: Grond 21.5.2013, 08:47
У нас ситуация обратная - сбой происходит не при отключении, а при включении автокоммита. Кроме того, при сбое происходит закрытие перлового потока, и база отсоединяется, потом создаётся новое подключение, и на нём снова происходит сбой установки автокоммита.

Автор: arto 21.5.2013, 09:13
попробуйте устанавливать AutoCommit при коннекте к базе.

Автор: Grond 21.5.2013, 11:03
 При коннекте у нас и так он выставляется, но периодически его надо снимать для проведения нескольких запросов единой транзакцией и, соответственно, восстанавливать после проведения транзакции перед продолжением работы. По идее, в случае успешного завершения транзакции, это делает DBI, а вот в случае ошибки восстановление делается нами вручную - в этот-то момент и возникает периодический сбой. Вообще, код у нас немножко кривоват в этом плане - он пытается восстанавливать автокоммит всегда, независимо от его состояния. Однако это всегда работало без проблем, да и должно работать без проблем, если не сломался объект обращения к БД.

Автор: arto 21.5.2013, 12:21
Я не понял вашей логики -- после падения коннекта, кто восстанавливает его?
mysql_auto_reconnect или вы сами?

А вообще, ошибка может говорить, это у вас DBD::mysql старый.

Автор: Grond 21.5.2013, 12:24
восстанавливает mysql_auto_reconnect

Автор: arto 21.5.2013, 15:31
а как mysql_auto_reconnect может восстанавливать, если вы говорите, что AutoCommit => 0?

    mysql_auto_reconnect
        This attribute determines whether DBD::mysql will automatically reconnect to mysql if the connection
        be lost. This feature defaults to off; however, if either the GATEWAY_INTERFACE or MOD_PERL
        envionment variable is set, DBD::mysql will turn mysql_auto_reconnect on. Setting
        mysql_auto_reconnect to on is not advised if 'lock tables' is used because if DBD::mysql reconnect
        to mysql all table locks will be lost. This attribute is ignored when AutoCommit is turned off, and
        when AutoCommit is turned off, DBD::mysql will not automatically reconnect to the server.

        It is also possible to set the default value of the "mysql_auto_reconnect" attribute for the $dbh by
        passing it in the "\%attr" hash for "DBI-"connect>.

        Note that if you are using a module or framework that performs reconnections for you (for example
        DBIx::Connector in fixup mode), this value must be set to 0.

Автор: Grond 22.5.2013, 00:19
кусок кода на самом  верху топика.

$DataBase->{'AutoCommit'}=1;

Автор: arto 23.5.2013, 08:18
если я правильно понял, у вас отваливается во время транзакции, когда $DataBase->{'AutoCommit'} == 0?
или всё не так?

Автор: Grond 23.5.2013, 10:05
Отваливается, когда, по идее, не было запросов, требующих выключения автокоммита. Сейчас на сервере вообще единственная нагрузка - это попытки горе-хакеров подобрать http-запросы типа "/php-admin". При таковых запросах в цикле mod_perl проходит стадия проверки базы на подключённость и либо производится подключение (с включённым по умолчанию автокоммитом), либо следует проверка на отсутствие открытой транзакции (с целью сделать rollback в случае незавершённого действия). Далее в любом случае делается попытка установить автокоммит в 1, и как раз в этом месте в некоторые моменты времени начинается сбой, идентифицируемый как "отсутствие аргумента AutoCommit у объекта DBD". Возникновение таких сбоев продолжается некоторое время, после чего так же самопроизвольно прекращается.

Автор: ginnie 23.5.2013, 19:07
Grond, а не пробовали включить http://search.cpan.org/~timb/DBI-1.627/DBI.pm#TRACING, чтобы посмотреть, что происходит, гадать тут сложновато.

Автор: Grond 6.6.2013, 08:55
вот результат трассировки:


Код

mysql.xs do() use_server_side_prepare 0
mysql_st_internal_execute MYSQL_VERSION_ID 50148
>parse_params statement SET NAMES 'utf8'
    <- do= '0E0' at DC_DB.pm line 29 via  at DC_DB.pm line 58
    -> STORE for DBD::mysql::Db (DBI::Db=HASH(0x7f91b1de18f8)~INNER 'AutoCommit' 1) thr#7f91b146b1c0
    <- STORE= 1 at DC_DB.pm line 32 via  at DC_DB.pm line 31
    -> FETCH for DBD::mysql::Db (DBI::Db=HASH(0x7f91b1de1e20)~INNER 'AutoCommit') thr#7f91b146b1c0
    <- FETCH= 1 at DC_DB.pm line 21 via  at DC_DB.pm line 64
    -> STORE for DBD::mysql::Db (DBI::Db=HASH(0x7f91b1de1e20)~INNER 'AutoCommit' 1) thr#7f91b146b1c0
  --> do_error
Turning on AutoCommit failed error 21 recorded: Turning on AutoCommit failed
  <-- do_error
    STORE DBI::Db=HASH(0x7f91b1de1e20) 'AutoCommit' => 1
AutoCommit crashed



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

какие идеи это исправить есть? Подскажите!

Автор: Grond 20.6.2013, 10:56
Что? Никто не знает никакого способа поправить?

Автор: Pilat66 4.7.2013, 19:30
Мне кажется, у Вас идеологически неправильно построено. Если работают транзакции, то надо отключать mysql_auto_reconnect , если AutoCommit=1, то так и надо всё время работать, не переключаясь в AutoCommit=0; "происходит закрытие перлового потока" - а это что вообще? У Вас многопоточное приложение? 

Автор: Grond 8.7.2013, 06:16
Цитата(Pilat66 @  4.7.2013,  19:30 Найти цитируемый пост)
Если работают транзакции, то надо отключать mysql_auto_reconnect

Какая связь?

Цитата(Pilat66 @  4.7.2013,  19:30 Найти цитируемый пост)
если AutoCommit=1, то так и надо всё время работать, не переключаясь в AutoCommit=0

Не в курсе, что при общем построении работы на AutoCommit=1 иногда необходимо собирать несколько запросов в неделимую транзакцию?


Цитата(Pilat66 @  4.7.2013,  19:30 Найти цитируемый пост)
У Вас многопоточное приложение?

апачёвые mod_perl потоки. Впрочем, и у нас при пересчёте используются явные форки.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)