Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> работа с mySQL, обработка ошибок, реконект 
V
    Опции темы
Secandr
Дата 24.2.2015, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 1
Всего: 39



Добрый день,

у меня есть пара простеньких демонов на perl. Основная их задача - сбор статистики с оборудование и запись данных в БД. Есть несколько САР на perl.

Столкнулся с тем, что демоны и САР периодически дохнут при работе с БД. Превышение интервала ожидания, потеря конекта к БД, рестарт БД, ошибки в запросах,... приводят к смерти софтины.

Перепускать скотинку приходится руками, что доставляет определённые неудобства.
Написать ревайвел слишком просто, хотелось бы решить проблему средствами perl.

В голову приходит - обернуть DBI своим классом и переназначить часть функционала DBI. Проверять адекватность коннекта, запускать функционал DBI в eval, анализировать коды ошибок, переконекчиваться, перезаливать данные в БД. После некоторого числа попыток или таймаута в несколько минут, тихо и мирно умирать, удаляя за собой pid файл, освобождая разделяемую память и закрывая коннекты ко всем БД.

Может уже кто-то написал такой модуль?

Подскажите пожалуйста.


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
Bulat
Дата 24.2.2015, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: 5
Всего: 57



Цитата(Secandr @  24.2.2015,  14:57 Найти цитируемый пост)
Может уже кто-то написал такой модуль?

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


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
Secandr
Дата 25.2.2015, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 1
Всего: 39



Ну я думаю так.
Делаем класс, который просто переназначает соответствующие методы класса DBI и делов-то.
Там нужно переписать connect, disconnect, prepare, execute, do, fetchrow_array
В основной же библиотеке просто мнеяем use DBI на use myDBI и создание объекта. Всего 4 строчки.

В своём модуле уже проверять состояние линка каждый раз при вызове родной функции DBI, реконектиться по необходимости, обрабатывать ошибки.

На первом этапе просто подменить класс и посмотреть как оно будет работать.

А дальше уже можно добавить доп. логику. Ввести несколько механизмов поведения.

Например для селекта пытаться несколько раз выполнить запрос, пока не будет получен результат.

Для важных update и insert ввести проверку на выполнение
Там где проверка затруднена или требует много ресурсов научить при ошибке выходить, закрывая за собой всё что надо. Как вариант, не делать exit, а посылать самому себе сигнал kill, что бы его перехватил соответствующий блок основной программы и вышел как полагается.

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

P.S. Вопрос только в том, не буду ли я изобретать велосипед. И будет ли мой велосипед достойнее тех, что уже сделаны.

Это сообщение отредактировал(а) Secandr - 25.2.2015, 10:41


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
Bulat
Дата 25.2.2015, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: 5
Всего: 57



Цитата(Secandr @  25.2.2015,  10:38 Найти цитируемый пост)
Вопрос только в том, не буду ли я изобретать велосипед.

если ты собираешься делать все это :
Цитата(Secandr @  25.2.2015,  10:38 Найти цитируемый пост)
Там нужно переписать connect, disconnect, prepare, execute, do, fetchrow_array


то потянет на велик.  smile 

Все что тебе требуется, в принципе, хорошо уложиться в новую функцию без создания своего класса, ну максимум две функции, если еще кошерное логирование прикрутить. 

Есть нормальный коннект - заливаем данные, нет - пробуем два-три раза, до удачной попытки. После двух-трех неудачных попыток, не насилуем никого и ничего, а умираем с криками и орами в лог!  smile

Добавлено через 53 секунды
Ну можешь и по своей логике идти, только смысл переписывать ряд функций из DBI, которые и так хорошо работают!  smile 


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
Secandr
Дата 25.2.2015, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 1
Всего: 39



Ну вот когда у тебя несколько десятков тысяч строк и вдруг надо поменять DBI в этом всём на что-то другое начинается веселье.

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

Проще написать скрипт, который заменит DBI на myDBI и тут же наступит счастье smile

Ну а myDBI будет делать так

Код

sub connect(){
 $class=shift @_;
 eval{
  $class->dbi->connect(@_);
 }
 # повторить попытку $class->N раз.
}


Это сообщение отредактировал(а) Secandr - 25.2.2015, 11:40


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
Bulat
Дата 25.2.2015, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: 5
Всего: 57



Если в огромном коде, глобальный хендл к бд везде вызывается напрямую, без инкапсуляций или каких-то иных функций-оберток, то myDBI - возможно и самое оптимальное решение!  smile 


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
Secandr
Дата 25.2.2015, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 1
Всего: 39



Ну там подход немного другой. БД обёрнута и работа большей части библиотеки идёт не с БД напрямую а с сущностями более конкретными, которые описывают рабочее тело. И 80% кода, работающего с БД, лежит в отдельном классе большой библиотеки.

Но есть и печаль. Часть нетипичной работы с БД ведётся напрямую из софта, вызывающего библиотеку, причём не через библиотеку, а напрямую через DBI.

В целом же, проще всё же вынести функционал работы с БД в отдельный класс и уже с ним работать и из основной библиотеки и из софта.

Попутно перетащив часть рутинных операций в этот класс.

P.S. С каждым годом переписывать код становится всё тяжелее smile


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
tzirechnoy
Дата 25.2.2015, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: нет
Всего: 16



Хотите, чтобы иногда ->fetchall_arrayref вызывался по три раза? Ну, сделайте обёртку вида fetchall_arrayref_hard(dbh, ..., 3).

А вообще -- задача правильной обработки ошыбок и корректного преобразования мира при их наличии -- это именно прикладная задача. Она каждый раз будет решаться на основе вашэго прикладного кода, потому внутри DBD этому дажэ помочь особенно нечему.

Ну и, конечно -- сделайте, наконец, так, чтобы mysql не дох. Я дажэ не предлагаю перейти на postgres (хотя это, конечно, стоило бы сделать, но не по этой причине) -- но, знаете, почему-то у сотен тысяч человек mysql работает и не дохнет.
PM MAIL   Вверх
Сумасшедший
Дата 26.2.2015, 08:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чилавек-Каропка
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 15.8.2004
Где: Москва

Репутация: 1
Всего: 107



Приношу извинения что не про перл, но почему бы в данном случае не воспользоваться mysql-proxy?


--------------------
Однажды ты спросишь, а я отвечу: "Время ожидания специалиста - 10 минут". Ты бросишь трубку, так и не узнав, что Ваш звонок очень важен для нас!
PM MAIL WWW Jabber   Вверх
Secandr
Дата 26.2.2015, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 1
Всего: 39



tzirechnoy, если руки дойдут переписать класс, я его потом покажу. Там задача немного более широкая. Но в целом вы правы, не имея понятия о бизнеслогике, нет возможности как-то повысить надёжность.

По поводу "что бы mySQL не дох" могу сказать следующее. Проект управляет сетью размером в 3 города, не считая мелких узлов по области и в столице. Есть несколько серверных ферм. Есть исторически сложившаяся инфраструктура: системы учёта сети, система электронного документооборота, системы мониторинга, технического аудита,... Каждая из систем работает со своей БД. Это и mySQL и postgresql и mssql и тот же битрикс на файликах.

Мой софт работает с этим со всем, собирает данные, анализирует это всё и по заданному шаблону применяет настройки к железу.

Задача - добиться стабильной и предсказуемой работы софта в аварийные периоды. С одной стороны - обеспечить адекватность при потере большей части инфраструктуры. В этом случае лучше умереть и ничего не делать. С другой стороны обеспечить надёжность при мелких авариях. Софт должен подождать спада пиковой нагрузки на сервере БД или спокойно перенести его перезагрузку. Иначе будет большой лаг от желания изменить настройки оборудования до их применения.

Сумасшедший, в свете вышеперечисленого mysql-proxy - дополнительная точка отказа. Мы сейчас кластеры стали делать из mysql и postgresql во избежание.


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
Pfailed
Дата 28.2.2015, 09:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 22
Всего: 39



https://metacpan.org/pod/DBD::mysql#mysql_auto_reconnect
Ну а ошибки обрабатывать естественно надо. Я обычно устанавливаю RaiseError =>1, PrintError => 0 и ловлю ошибки через eval.


--------------------
PM MAIL   Вверх
Secandr
Дата 4.3.2015, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 1
Всего: 39



Натыкался в документации на такое, попробую на днях.


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
Secandr
Дата 6.3.2015, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 1
Всего: 39



Не успел ничего путного сделать за неделю.
Добавил 
Код

$name{'db'}= DBI->connect("DBI:----------", "------", "-------"
        , {
            mysql_auto_reconnect => 1,
        mysql_init_command    => q{SET CHARACTER SET 'utf8';SET NAMES 'utf8';}
          }        
        ) or die "could not connect to HD";



--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
Secandr
Дата 10.3.2015, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 1
Всего: 39



Не помогло.
Теперь вылетает без ошибок :(


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
noize
Дата 10.3.2015, 23:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


5.18.2
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 10.7.2010
Где: СПб

Репутация: 3
Всего: 3



простенький пример из жизни:

Код

my $DBH;

sub dbh {
    unless ( $DBH || $DBH->ping ) {
        $DBH = DBI->connect();
        croak "Can't connect to database: " . $DBH->err if $DBH->err;
    }

    return $DBH;
}

print dbh->selectrow_array( qq/ SELECT NOW() / );


Т.е. суть работы - обернуть обращение к бд в один метод и вызывать его из всех своих скриптов. А в самом методе проверять подключение, делать реконнект и пр.
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1393 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.