Архивирование таблиц списаний - кому интересно - читайте.

Технические вопросы по UTM 5.0
murano
Сообщения: 67
Зарегистрирован: Ср окт 14, 2009 06:53

Архивирование таблиц списаний - кому интересно - читайте.

Сообщение murano »

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

Код:

Код: Выделить всё


#!/usr/local/bin/perl

use DBI;

#### MySQL Connect Params. ####

$dbuser = "user";

$dbpass = "password";

$dbname = "database";

$dbhost = "localhost";

##### Set prefix for names archived tables (value prifixes the date create arhives tables) #####

$day = "20";
$month = "Oct";
$year = "2009";

$date = $day . $month . $year;


#### Set Connection with MySQL ####

$dbh = DBI->connect("DBI:mysql:$dbname:$dbhost" , "$dbuser" , "$dbpass");
die "ERROR!!! No connection with MySQL server! Check MySQL Connect Params!\n" unless (defined $dbh);
print "MySQL Connecting is COPMPLEETED! \n";

######## get end_date of period to archive ######## 

$dta = "discount_transactions_all_$date";
$dtia = "discount_transactions_iptraffic_all_$date";

print "Get start & end date of archive period \n";

$sth = $dbh->prepare("select UNIX_TIMESTAMP(concat(YEAR(now()),'-',MONTH(now()),'-1 0:0:0'));");
$sth -> execute();
$enddate=$sth->fetchrow_array;


######## Get date of discount_transactions_all ########
  print "Get date $dta \n";

  #get last archive id
  $sth = $dbh->prepare("select max(archive_id) from archives where table_type=1");
  $sth -> execute();
  $archiveid_type1=$sth->fetchrow_array;    $archiveid_type1++;
  print "Last archive id=".$archiveid_type1."\n";

  #get start date to archive
  $sth = $dbh->prepare("select min(discount_date) from discount_transactions_all");
  $sth -> execute();
  $start_date=$sth->fetchrow_array;


  print "Start date of  archive period : ".$start_date."\n";
  print "End date of  archive period : ".$enddate."\n";





######## get date of discount_transactions_iptraffic_all #######
print "Get date $dtia \n";

#get last archive id
  $sth = $dbh->prepare("select max(archive_id) from archives where table_type=2");
  $sth -> execute();
  $archiveid_type2=$sth->fetchrow_array;    $archiveid_type2++;
  print "Last archive id=".$archiveid_type2."\n";

  #get start date to archive
  $sth = $dbh->prepare("select min(discount_date) from discount_transactions_iptraffic_all");
  $sth -> execute();
  $start_date=$sth->fetchrow_array;

  print "Start date of  archive period : ".$start_date."\n";
  print "End date of  archive period : ".$enddate."\n";


######## Renamed tables ########

print "Create archive tables discount_transactions_all_$date ... Please, wait... \n";

$results = $dbh ->do ("alter table discount_transactions_all rename discount_transactions_all_$date");
print "DONE! \n";

print "Create archive tables discount_transactions_iptraffic_all_$date ... Please, wait... \n";
$results = $dbh ->do ("alter table discount_transactions_iptraffic_all rename discount_transactions_iptraffic_all_$date");
print "DONE! \n";


######## Creating new truncated tables #########

print "Create new trunkated tables discount_transactions_all... \n";
$results =  $dbh->do("CREATE TABLE discount_transactions_all (
  id int(11) NOT NULL auto_increment,
  account_id int(11) default NULL,
  incoming_rest double default NULL,
  outgoing_rest double default NULL,
  discount double default NULL,
  discount_with_tax double default NULL,
  service_id int(11) default NULL,
  service_type int(11) default NULL,
  discount_period_id int(11) default NULL,
  slink_id int(11) default NULL,
  discount_date int(11) default NULL,
  charge_type int(11) NOT NULL default '0',
  PRIMARY KEY  (id)
) ENGINE=InnoDB;");
print "DONE! \n";


  $sth =  $dbh->prepare("SELECT min(discount_date),max(discount_date) from ".$dta);
  $sth -> execute();
  ($start_date,$end_date)=$sth->fetchrow_array;
  $sth =  $dbh->prepare("INSERT INTO archives (archive_id,table_type,table_name,
                        start_date,end_date) VALUES (".$archiveid_type1.",1,'".$dta."',".$start_date.",".$end_date.");");
  $sth -> execute();



#####################################################
;

print "Create new trunkated tables discount_transactions_iptraffic_all... \n";
$results =  $dbh->do("CREATE TABLE discount_transactions_iptraffic_all (
  id int(11) NOT NULL auto_increment,
  account_id int(11) default NULL,
  discount double default NULL,
  discount_with_tax double default NULL,
  service_id int(11) default NULL,
  discount_period_id int(11) default NULL,
  slink_id int(11) default NULL,
  discount_date int(11) default NULL,
  discount_date_hour int(11) default NULL,
  discount_date_day int(11) default NULL,
  discount_date_month int(11) default NULL,
  t_class int(11) default '0',
  base_cost double default '0',
  ipid int(11) default '0',
  bytes bigint(20) default NULL,
  PRIMARY KEY  (id)
) ENGINE=InnoDB;");
print "DONE! \n";


$sth =  $dbh->prepare("SELECT min(discount_date),max(discount_date) from ".$dtia);
  $sth -> execute();
  ($start_date,$end_date)=$sth->fetchrow_array;
  #print $start_date,$end_date,"\n";
  $sth =  $dbh->prepare("INSERT INTO archives (archive_id,table_type,table_name,
                        start_date,end_date) VALUES (".$archiveid_type2.",2,'".$dtia."',".$start_date.",".$end_date.");");
  $sth -> execute();


#### End connections with MySQL ####

$sth->finish;
$dbh->disconnect;
print "Disconnect MySQL Server, Good bye! \n";


Теперь перейдем к подробностям.

В секции:

Код: Выделить всё

#### MySQL Connect Params. ####

$dbuser = "user";

$dbpass = "password";

$dbname = "database";

$dbhost = "localhost";
расположенной в начале скрипта меняем параметры подключения к MySQL заменив в кавычках параметры на свои.

В секции:

Код: Выделить всё

##### Set prefix for names archived tables (value prifixes the date create arhives tables) #####

$day = "20";
$month = "Oct";
$year = "2009";
проставляем день, месяц и год создания архива (см. пример в скрипте). Для чего это нужно? Если например у вас стоят даты как у меня в скрипте, то после завершения процесса архивирования у вас появятся две новые таблицы с префиксами даты создания, т.е.:

discount_transations_all_20Oct2009
и
discount_transations_iptraffic_all_20Oct2009

думаю дальше не нужно ничего объяснять, все предельно понятно на примере.

Так же будут очищенны таблицы:

discount_transations_all
и
discount_transations_iptraffic_all

и внесены необходимые данные в таблицу archives.

Хочу сразу обратить внимание на ряд нюансов, чтобы потом вы не задавали лишних вопросов.

1. Скрипт писался из расчета, что архивные таблицы будут храниться только за 2 предыдущих месяца, т.е, если вы к примеру сделали раз архив, потом спустя 2 месяца повторили процедуру архивации, параметры таблицы archives ссылающиеся на старый архив будут перезаписанны и будут ссылаться на свежий архив. Это сделано из соображений того, что нам нет смысла хранить таблицы, сделанные более 2 месяцев назад. Т.е. если вы произвели архивацию и решили удалить предыдущие архивы, удаляйте только архивы, в таблице archives ничего править не нужно, скрипт все сделает сам. Хочу сразу заметить, если вас такой вариант не устраивает, вы можете переписать код под свои нужды, взяв за основу мой.

2. Я бы очень порекомендовал останавливать биллинг в момент архивации, хотя это и не столь критично но все же лучше сделать именно так, хотя можно конечно дописать код так, что на момент архивации он будет лочить таблицы

discount_transations_all_20Oct2009
и
discount_transations_iptraffic_all_20Oct2009

а потом снимать лок по завершении процесса, но это не лучшее решение. Проще остановить биллинг, безопаснее будет.

4. Обязательно перед архивацией делайте резеврную копию БД!!! За ваши беды, вызванные скриптом я ответственности не несу! Ибо ваша криворукость или неопытность - сугубо ваши личные проблемы!

5. После процедуры архивации рекомендую проверить verificator.log на наличие ошибок в БД и соответственно исполнить код которые она вам пишит.

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

Сразу говорю, не нужно меня в чем-то критиковать, скрипт писал под себя, он работает на 100%, если что-то не нравится, пишите свои скрипты, я лишь поделился своим вариантом решения проблемы.

Пользуйтесь, архивируйте, наслаждайтесь:)))
Последний раз редактировалось murano Ср окт 14, 2009 13:46, всего редактировалось 3 раза.

Blackmore
Сообщения: 365
Зарегистрирован: Вс фев 06, 2005 09:24
Откуда: подмосковье

Сообщение Blackmore »

спасибо

murano
Сообщения: 67
Зарегистрирован: Ср окт 14, 2009 06:53

:)

Сообщение murano »

Всегда пожалуйста:) просто клинит то, что на форумах вчено сидят "Мегагении" а ответить по существу на вопросы никто не может, тока могут упрекаь друг друга в опыте и знаниях.

Аватара пользователя
Magnum72
Сообщения: 1947
Зарегистрирован: Чт сен 22, 2005 06:54
Контактная информация:

Сообщение Magnum72 »

испоганил рабочий скрипт только.

murano
Сообщения: 67
Зарегистрирован: Ср окт 14, 2009 06:53

Ну конечно...

Сообщение murano »

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

Аватара пользователя
Magnum72
Сообщения: 1947
Зарегистрирован: Чт сен 22, 2005 06:54
Контактная информация:

Re: Ну конечно...

Сообщение Magnum72 »

murano писал(а):Магнум, если тебе в прикол сидеть и ждать пока delete отработает на хотябы 15 гиговой базе, я тогда хз... я тебе сказал, писал под свои нужды, спасибо за фрагменты кода.
Не было у меня delete, я вообще отличий особых не вижу в коде.

murano
Сообщения: 67
Зарегистрирован: Ср окт 14, 2009 06:53

А ты скрипт хотябы на тестовой базе опробуй.

Сообщение murano »

Разницу сразу увидишь, тут во первых, изменена немного логика работы скрипта, во вторых, порядок выолнения, в третьих, внесены дополнительные переменные, некоторые на обород удалены, включая некоторые операторы, в четвертых изменена схема sql запроса для создания таблиц. Ты главное попробуй сам, тока единственное, можно дописать немного чтобы он в табличке archives не перезаписывал существующие id на новые в момент архивации, а вносил новые записи, мало ли кто будет архивировать каждый месяц и все архивы будут нужны.

serg2k
Сообщения: 28
Зарегистрирован: Пт сен 11, 2009 09:57

Сообщение serg2k »

Была подобная идея, но сразу возникает вопрос и он скорее к Нетапу:

Как это будет взаимодействовать со списанием, учитываются ли архивные таблицы в процессе списания?

еще вопрос к автору:
В какой момент запускать скрипт, 1-го числа в 0 часов или в любое время? Ответ на этот вопрос скорее всего зависит от ответа на первый вопрос.

murano
Сообщения: 67
Зарегистрирован: Ср окт 14, 2009 06:53

Сообщение murano »

serg2k писал(а):Была подобная идея, но сразу возникает вопрос и он скорее к Нетапу:

Как это будет взаимодействовать со списанием, учитываются ли архивные таблицы в процессе списания?

еще вопрос к автору:
В какой момент запускать скрипт, 1-го числа в 0 часов или в любое время? Ответ на этот вопрос скорее всего зависит от ответа на первый вопрос.
я могу ответить на оба твоих вопроса. По части взаимодействия списаний, их можешь сделать хоть в середине месяца, если есть на то необходимость. Соответственно, у тебя списания продолжат вноситься в уже новые, чистые таблицы но если ты сделаешь в конце месяца оттчет, с группировкой по дням ну или его же сделаешь в следующем месяце как отчет с группировкой по дням за предидущий месяц, увидишь что у тебя присутствует полный отчет по трафику ну или еще там по чему, например по платежам и т.д. состоящий из кусков взятых на половину из архивной таблицы и из уже новой, очищенной после архивации. Мне самому раз довелось сделать отчет 17 сентября, в результате в начале октября я получил отчет по трафику выглядящий визуально целым, но на самом деле он был взят частично с архива частично с основных таблиц. Думаю я довольно понятно ответил на оба твоих вопроса.

если есть вопросы, пишите мне на мыло: admin@triola.ru

murano
Сообщения: 67
Зарегистрирован: Ср окт 14, 2009 06:53

Ну что народ...

Сообщение murano »

Кто попробывал скрипт на практике? Что скажете? А то как то без комментариев оствили...

maxxxx
Сообщения: 59
Зарегистрирован: Вт ноя 07, 2006 18:26

Сообщение maxxxx »

спасибо, все отлично работает и без выключения биллинга...

RHAmzin
Сообщения: 72
Зарегистрирован: Чт апр 03, 2008 05:27

Сообщение RHAmzin »

Странно, но после архивации этим скриптом админка виснет через каждые 5-10 минут.

murano
Сообщения: 67
Зарегистрирован: Ср окт 14, 2009 06:53

re

Сообщение murano »

RHAmzin писал(а):Странно, но после архивации этим скриптом админка виснет через каждые 5-10 минут.
Апдейд какой? 2? 3? билд 007? я просто на 2 апдейде сижу, в третьем может таблицы чем-то отличаются.

murano
Сообщения: 67
Зарегистрирован: Ср окт 14, 2009 06:53

Решение

Сообщение murano »

Народ, надеюсь что мое новое решение для упрощения процедуры архивирования таблиц списаний поможет многоим, смотрим подробности здесь viewtopic.php?t=8312&highlight=%E0%F0%F ... 0%ED%E8%E9

eucariot
Сообщения: 3
Зарегистрирован: Ср фев 02, 2011 14:14

Сообщение eucariot »

Скрипт проверил на 007, update 12. Работает прекрасно. Спасибо. Правда мою проблему я так не решил.

Ответить