Код:
Код: Выделить всё
#!/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";
В секции:
Код: Выделить всё
##### 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%, если что-то не нравится, пишите свои скрипты, я лишь поделился своим вариантом решения проблемы.
Пользуйтесь, архивируйте, наслаждайтесь:)))