Резервное копирование и восстановление базы данных Oracle средствами ОС::Журнал СА 5.2007
www.samag.ru
     
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
Журнал "Системный администратор"
Журнал «БИТ»
Подписка
Архив номеров
Где купить
Наука и технологии
Авторам
Рекламодателям
Контакты
   

  Опросы
  Статьи

Событие  

В банке рассола ждет сисадмина с полей фрактал-кукумбер

Читайте впечатления о слете ДСА 2024, рассказанные волонтером и участником слета

 Читать далее...

Организация бесперебойной работы  

Бесперебойная работа ИТ-инфраструктуры в режиме 24/7 Как обеспечить ее в нынешних условиях?

Год назад ИТ-компания «Крок» провела исследование «Ключевые тренды сервисного рынка 2023». Результаты

 Читать далее...

Книжная полка  

Читайте и познавайте мир технологий!

Издательство «БХВ» продолжает радовать выпуском интересных и полезных, к тому же прекрасно

 Читать далее...

СУБД PostgreSQL  

СУБД Postgres Pro

Сертификация по новым требованиям ФСТЭК и роль администратора без доступа к данным

 Читать далее...

Критическая инфраструктура  

КИИ для оператора связи. Готовы ли компании к повышению уровня кибербезопасности?

Похоже, что провайдеры и операторы связи начали забывать о требованиях законодательства

 Читать далее...

Архитектура ПО  

Архитектурные метрики. Качество архитектуры и способность системы к эволюционированию

Обычно соответствие программного продукта требованиям мы проверяем через скоуп вполне себе понятных

 Читать далее...

Как хорошо вы это знаете  

Что вам известно о разработках компании ARinteg?

Компания ARinteg (ООО «АРинтег») – системный интегратор на российском рынке ИБ –

 Читать далее...

Графические редакторы  

Рисование абстрактных гор в стиле Paper Cut

Векторный графический редактор Inkscape – яркий представитель той прослойки open source, с

 Читать далее...

День сисадмина  

Учите матчасть! Или как стать системным администратором

Лето – время не только отпусков, но и хорошая возможность определиться с профессией

 Читать далее...

День сисадмина  

Живой айтишник – это всегда движение. Остановка смерти подобна

Наши авторы рассказывают о своем опыте и дают советы начинающим системным администраторам.

 Читать далее...

Виртуализация  

Рынок решений для виртуализации

По данным «Обзора российского рынка инфраструктурного ПО и перспектив его развития», сделанного

 Читать далее...

Книжная полка  

Как стать креативным и востребованным

Издательский дом «Питер» предлагает новинки компьютерной литературы, а также книги по бизнесу

 Читать далее...

Книжная полка  

От создания сайтов до разработки и реализации API

В издательстве «БХВ» недавно вышли книги, которые будут интересны системным администраторам, создателям

 Читать далее...

Разбор полетов  

Ошибок опыт трудный

Как часто мы легко повторяем, что не надо бояться совершать ошибки, мол,

 Читать далее...

1001 и 1 книга  
19.03.2018г.
Просмотров: 6207
Комментарии: 0
Машинное обучение с использованием библиотеки Н2О

 Читать далее...

12.03.2018г.
Просмотров: 6916
Комментарии: 0
Особенности киберпреступлений в России: инструменты нападения и защита информации

 Читать далее...

12.03.2018г.
Просмотров: 4199
Комментарии: 0
Глубокое обучение с точки зрения практика

 Читать далее...

12.03.2018г.
Просмотров: 2999
Комментарии: 0
Изучаем pandas

 Читать далее...

12.03.2018г.
Просмотров: 3801
Комментарии: 0
Программирование на языке Rust (Цветное издание)

 Читать далее...

19.12.2017г.
Просмотров: 3812
Комментарии: 0
Глубокое обучение

 Читать далее...

19.12.2017г.
Просмотров: 6308
Комментарии: 0
Анализ социальных медиа на Python

 Читать далее...

19.12.2017г.
Просмотров: 3160
Комментарии: 0
Основы блокчейна

 Читать далее...

19.12.2017г.
Просмотров: 3452
Комментарии: 0
Java 9. Полный обзор нововведений

 Читать далее...

16.02.2017г.
Просмотров: 7271
Комментарии: 0
Опоздавших не бывает, или книга о стеке

 Читать далее...

17.05.2016г.
Просмотров: 10636
Комментарии: 0
Теория вычислений для программистов

 Читать далее...

30.03.2015г.
Просмотров: 12358
Комментарии: 0
От математики к обобщенному программированию

 Читать далее...

18.02.2014г.
Просмотров: 13993
Комментарии: 0
Рецензия на книгу «Читаем Тьюринга»

 Читать далее...

13.02.2014г.
Просмотров: 9118
Комментарии: 0
Читайте, размышляйте, действуйте

 Читать далее...

12.02.2014г.
Просмотров: 7072
Комментарии: 0
Рисуем наши мысли

 Читать далее...

10.02.2014г.
Просмотров: 5382
Комментарии: 3
Страна в цифрах

 Читать далее...

18.12.2013г.
Просмотров: 4612
Комментарии: 0
Большие данные меняют нашу жизнь

 Читать далее...

18.12.2013г.
Просмотров: 3421
Комментарии: 0
Компьютерные технологии – корень зла для точки роста

 Читать далее...

04.12.2013г.
Просмотров: 3151
Комментарии: 0
Паутина в облаках

 Читать далее...

03.12.2013г.
Просмотров: 3398
Комментарии: 0
Рецензия на книгу «MongoDB в действии»

 Читать далее...

02.12.2013г.
Просмотров: 3021
Комментарии: 0
Не думай о минутах свысока

 Читать далее...

Друзья сайта  

 Резервное копирование и восстановление базы данных Oracle средствами ОС

Архив номеров / 2007 / Выпуск №5 (54) / Резервное копирование и восстановление базы данных Oracle средствами ОС

Рубрика: Администрирование /  Резервное копирование

Сергей Косько

Резервное копирование и восстановление базы данных Oracle средствами ОС

Мы установили какое-либо приложение, хранилищем данных в котором служит СУБД Oracle. Но вводить систему в производственную эксплуатацию ещё рано. Предварительно необходимо создать надёжную методику резервного копирования и восстановления базы данных.

Одним из самых функциональных средств резервного копирования от Oracle является утилита RMAN. Однако использовать столь сложную систему для резервного копирования зачастую избыточно (если эксплуатируется одна-две базы данных). Кроме того, RMAN, как правило, использует отдельную базу в качестве хранилища своей собственной информации. Чтобы избежать ситуации, когда данные, необходимые для восстановления базы, хранятся в этой же базе, для резервного копирования собственно каталога RMAN необходимо использовать другие средства. Различные универсальные программы резервного копирования, которые могут работать с базами данных Oracle, тоже избыточны или небесплатны. Что же выбрать? Самый простой и экономный способ – решить эту задачу с помощью обычных скриптов и стандартных системных утилит.

Основным критерием качества методов восстановления данных является их адекватность, способность восстановить необходимые данные при любом возможном сбое. Предлагаю вам свой способ решения этой задачи для СУБД Oracle.

Рассмотрим несколько примеров резервного копирования-восстановления без использования RMAN или других утилит.

Возьмём в качестве исходной следующую информацию:

  • В тестах будем использовать СУБД Oracle версии 10.2. для ОС Solaris.
  • СУБД настроена на работу в режиме АRCHIVELOG.
  • Рассмотрим 2 сценария восстановления: полного и неполного.
  • Будем исходить из того предположения, что мы восстанавливаем данные на тот же самый сервер (или точную копию рабочего сервера БД, на котором уже установлена ОС, ПО СУБД Oracle, все необходимые исправления и создана необходимая структура каталогов).
  • Для наглядности создадим отдельные архивы для файлов данных, управляющих файлов, файлов инициализации и паролей.
  • Выполним полную копию базы данных двумя способами:
    • с остановкой экземпляра (холодная копия);
    • без остановки работы экземпляра (горячая копия).
  • Расположение файлов базы данных имеет следующую структуру:
    • /ora/oracle/oradata/ORCL – файлы данных;
    • /ora/oracle/oradata/Redo-Ctrl/replica0 – первая копия управляющих и журнальных файлов;
    • /ora/oracle/oradata/Redo-Ctrl/replica1 – вторая копия управляющих и журнальных файлов;
    • /ora/oracle/oradata/log – файлы архивных журналов.

Сделаем полную копию БД двумя вышеуказанными способами:

  1. Холодная копия (cм. листинг 1). Это самый простой пример, он применяется редко. Мы рассмотрим его в целях сравнения с более сложными примерами.
  2. $backuponl.sh ORCL /backup/hot

  3. Горячая копия (см. листинг 2). Создаёт практически аналогичный набор файлов данных, за исключением того, что копии активных журналов redo делать не нужно. Сохраним в архиве одну копию управляющего файла и скрипт control.sql для его пересоздания.
  4. $backup.sh ORCL /backup/cold

Сценарии восстановления

Будем имитировать сбой носителя в некоторый момент времени после выполненного резервного копирования, выполняя несколько принудительных переключений активных журналов командой:

SQL> alter system switch logfile;

Затем будем стирать и восстанавливать из архива файлы, принадлежащие БД. Предполагаем, что архивные журналы имеются и доступны для восстановления в каталоге, указанном в параметрах db_recovery_file_dest/log_archive_dest.

Сценарий 1.  Клонирование БД из холодной копии

Допустим, нам необходимо запустить базу данных на компьютере с аналогичным программным обеспечением и дисками. Сделаем это с помощью холодной копии. Удалим все файлы базы данных:

testcase$cd /ora/oracle/oradata/ORCL;find . -type f -exec rm -f {} \;

testcase$cd /ora/oracle/oradata/Redo-Ctrl;find . -type f -exec rm -f {} \;

Проведём восстановление:

testcase$cd /backup/cold

testcase$tar xvf control.tar

testcase$tar xvf data.tar

testcase$tar xvf dbs.tar

testcase$tar xvf redo.tar

testcase$dbstart

Это практически единственный случай, когда могут пригодиться копии активных (не путать с архивными) журналов базы данных. Во всех остальных случаях необходимо восстановление БД, и устаревшие копии уже не содержат актуальной информации. Гораздо важнее иметь полный (без пропусков) набор архивных журналов. На самом деле в данном случае активные журналы тоже не обязательны.

Часто при создании копии рабочей базы нет необходимости запускать базу именно с опцией NORESETLOGS. Если есть холодная копия, но без копии журналов (файл redo.tar), после восстановления файлов из архива нужно сделать следующее:

testcase$sqlplus "/ as sysdba"

SQL>startup mount

Database mounted.

SQL> recover database using backup controlfile until cancel;

ORA-00279: change 817959 generated at 05/04/2007 09:15:19 needed for thread 1

ORA-00289: suggestion :

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}

cancel

Media recovery cancelled.

SQL>alter database open resetlogs;

Database altered.

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

Сценарий 2. Полное восстановление из горячей резервной копии

Смоделируем потерю файлов данных БД. Удалим файлы данных, но не управляющие и журнальные файлы:

testcase$cd /ora/oracle/oradata/ORCL;find . -type f -exec rm -f {} \;

Проведём восстановление только файлов данных из горячей резервной копии (см. листинг 3):

testcase$cd /backup/hot

testcase$tar xvf data.tar

testcase$recover.sh ORCL

В зависимости от версии базы данных и операционной системы может понадобиться пересоздать временный файл – это можно сделать, например, скриптом (см. листинг 4):

testcase$tmprecov.sh ORCL

Сценарий 3. Восстановление файлов управления

Если мы потеряли часть наших управляющих файлов, но сохранилась хотя бы одна копия из указанных в файле init.ora/spfile.ora, нужно скопировать эту копию во все указанные местоположения (например, если пропали файлы в каталоге replica0, нужно скопировать их из каталога replica1). Если пропали все копии управляющих файлов, и только они, необходимо отредактировать файл control.sql (полученный при выполнении горячей копии БД, листинг 2) и выполнить пересоздание управляющего файла. Если такого скрипта мы заранее не создали, тогда нам остаётся только воспользоваться сделанными ранее копиями управляющих файлов:

testcase$tar xvf control.tar

testcase$cp control01.ctl  /ora/oracle/oradata/Redo-Ctrl/replica0/control01.ctl

testcase$cp control01.ctl  /ora/oracle/oradata/Redo-Ctrl/replica1/control03.ctl

testcase$sqlplus "/ as sysdba"

SQL>startup mount

SQL> alter database backup controlfile to trace as 'control.sql' ;

SQL>shutdown

SQL>exit

Затем отредактировать и выполнить скрипт. Существует ещё один способ: скопировать текущий активный журнал в местоположение log_archive_dest в формате log_archive_format, выполнить неполное восстановление и открыть базу с опцией RESETLOGS (потери зафиксированных транзакций при этом не произойдёт, но нумерация архивных журналов начнётся сначала).

Сценарий 4. Восстановление БД при утере копии добавленного файла

После выполнения резервного копирования был добавлен один файл базы данных (см. листинг 5), и впоследствии произошла поломка жесткого диска. А копии управляющего файла и нового файла данных мы сделать не успели. Если попытаться провести восстановление базы из существующих резервных копий, восстановление будет идти только до момента создания нового файла, после чего возникнет ошибка:

SQL> alter database recover automatic using backup controlfile;

alter database recover automatic using backup controlfile

*

ERROR at line 1:

ORA-00283: recovery session canceled due to errors

ORA-01244: unnamed datafile(s) added to control file by media recovery

Я думаю, самым надёжным способом избежать подобной ситуации будет иметь достаточное количество реплик файла управления и всегда делать резервную копию добавляемых файлов. Если же такая ситуация произошла, можно воспользоваться последовательностью команд, представленной в листинге 6. Отмечу, что это не готовый скрипт, а лишь примерная последовательность команд с комментариями, поскольку невозможно заранее предугадать номера и названия файлов данных.

Сценарий 5. Восстановление при потере активных журналов БД

Если потеряны не все группы REDO, а только какая-то одна реплика REDO файлов БД, то остановки базы при этом не происходит. В этом случае журналы можно пересоздать или при перезагрузке скопировать файлы из одного каталога в другой. Если же мы потеряли все файлы REDO (или хотя бы как минимум активную группу), полное восстановление невозможно. Остаётся вариант неполного восстановления и последующий запуск БД с опцией RESETLOGS. В этом случае возможна потеря зафиксированных транзакций, и произойдёт сброс последовательности архивных журналов.

Смоделируем ситуацию:

testcase$dbshut

testcase$cd /ora/oracle/oradata/Redo-Ctrl

testcase$find . –type f -name \*.log –exec rm –f  {}  \;

testcase$sqlpplus "/ as sysdba"

SQL>startup mount

SQL>recover database until cancel

...

cancel

SQL> alter database open resetlogs;

SQL>exit

Из этого примера видно, как важно иметь хотя бы две реплики активных журналов базы данных (redo log). В случае их уничтожения – потеря информации (пусть иногда и допустимая) неизбежна. Её можно лишь минимизировать, например установив параметр archive_lag_target (его минимальное значение – 60 секунд).

Сценарий 6. Восстановление только по резервной копии и архивным журналам

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

testcase$tar xvf data.tar

testcase$tar xvf control.tar

testcase$tar xvf dbs.tar

Потом, поскольку активные журналы потеряны, производится неполное восстановление (см. листинг 7). БД открывается с опцией RESTLOGS.

testcase$recovincomplett.sh ORCL

Итоги

Подводя итоги рассмотренных сценариев, хотелось бы отметить основные моменты:

  • Резервная копия должна быть обязательно полной (все файлы данных, все архивные журналы, файлы управления, инициализации и пароли).
  • При восстановлении производственной базы нужно стараться не допустить случая неполного восстановления (с опцией RESETLOGS), поскольку это изменяет последовательную нумерацию журналов и есть риск потери данных. Вариант восстановления БД с переходом через точку RESETLOGS вообще-то существует, но он довольно громоздкий. Не стоит усложнять самому себе жизнь. Описание этого метода приводится, например, в книге «Oracle Backup & Recovery Handbook» [2, глава 10].
  • Чтобы избежать случая неполного восстановления, следует беречь активные журналы. В большинстве случаев их резервная копия невозможна, необходимо иметь несколько реплик, размещать их на RAID1 и т. п.
  • Копировать активные журналы REDO, можно только при холодной копии, и нужны они только для создания клона БД.
  • Не менее важно беречь и управляющие файлы. Их можно, как правило, пересоздать, но это требует времени, потеря хотя бы одной копии управляющего файла делает невозможным старт БД.
  • Для восстановления необходимо иметь архивные журналы, их тоже желательно включать в резервную копию, или настроить файл параметров так, чтобы журналы архивировались в несколько мест сразу, например, на локальный диск и на сетевой. (Параметр LOG_ARCHIVE_DEST_N.)
  • Холодная и горячая резервные копии БД для восстановления пригодны одинаково, нельзя сказать, что горячая копия не позволяет сделать то, что позволяет холодная. За исключением случая клонирования. Горячая копия всегда нуждается в применении впоследствии команды «recover». Для этого не обязательно, но полезно после завершения копии принудительно переключить активный журнал, чтобы не ждать, когда он переключится сам, а сразу приступать к клонированию базы данных.
  • Ну и напоследок, моё трепетное отношение к полному восстановлению относится в основном к производственным базам. Если необходимо восстаноить БД на какой-то момент времени в прошлом, то такой сценарий предусматривает именно неполное восстановление.

Приложение

Листинг 1. Холодная копия БД (файл backup.sh)

#!/bin/sh

#

if [ $# -ne 2 ]

then echo "script needs two parameters: \${ORACLE_SID} <dest dir>"

exit;

fi

#

ORACLE_SID=${1};export ORACLE_SID

copydir=${2};export copydir

#Create lists of files.

#Regular database files

datalist=`sqlplus -s "/ as sysdba" <<EOF

set heading off

set pagesize 0

set linesize 300

set feed off

select file_name from dba_data_files ;

exit ;

EOF`

#Temporary files

templist=`sqlplus -s "/ as sysdba" <<EOF

set heading off

set pagesize 0

set linesize 300

set feed off

select file_name from dba_temp_files;

exit;

EOF`

#Control files ( copy all )

controlist=`sqlplus -s "/ as sysdba" <<EOF

set heading off

set pagesize 0

set linesize 300

set feed off

select name from v\\$controlfile ;

exit ;

EOF`

#Online Redo logs.

redolist=`sqlplus -s "/ as sysdba" <<EOF

set heading off

set pagesize 0

set linesize 300

set feed off

select member from v\\$logfile ;

exit ;

EOF`

#

sqlplus "/ as sysdba" <<EOF

shutdown immediate

exit;

EOF

cd ${copydir}

tar cvf data.tar ${datalist} ${templist}

tar cvf control.tar ${controlist}

tar cvf redo.tar ${redolist}

tar cvf dbs.tar ${ORACLE_HOME}/dbs/init${ORACLE_SID}.ora \

${ORACLE_HOME}/dbs/spfile${ORACLE_SID}.ora               \

${ORACLE_HOME}/dbs/orapw${ORACLE_SID}

sqlplus "/ as sysdba" <<EOF

startup

exit;

EOF

#

 

Листинг 2. Горячая копия БД (файл backuponl.sh)

#!/bin/sh

#

if [ $# -ne 2 ]

then echo "script needs two parameters: \${ORACLE_SID} <dest dir>"

exit;

fi

#

ORACLE_SID=${1};export ORACLE_SID

copydir=${2};export copydir

#Make lists of files for backup.

#data files

datalist=`sqlplus -s "/ as sysdba" <<EOF

set heading off

set pagesize 0

set linesize 300

set feed off

select file_name from dba_data_files ;

exit ;

EOF`

#Controlfile make one copy and one trace

controlist=`sqlplus -s "/ as sysdba" <<EOF

set heading off

set pagesize 0

set linesize 300

set feed off

select name from v\\$controlfile

where rownum=1;

exit ;

EOF`

controldir=`dirname $controlist`

#

sqlplus "/ as sysdba" <<EOF

alter database begin backup;

exit;

EOF

cd ${copydir}

tar cvf data.tar ${datalist}

# Init & passwd files

tar cvf dbs.tar ${ORACLE_HOME}/dbs/init${ORACLE_SID}.ora \

${ORACLE_HOME}/dbs/spfile${ORACLE_SID}.ora               \

${ORACLE_HOME}/dbs/orapw${ORACLE_SID}

sqlplus "/ as sysdba" <<EOF

alter database end backup;

alter database backup controlfile to '$controldir/conbackup.ctl' reuse ;

alter database backup controlfile to trace as '$controldir/control.sql';

alter system archive log current ;

exit;

EOF

#

for i in ${controlist}

    do

#    cp /tmp/conbackup.ctl ${copydir}/`basename ${i}`

    tar cvf control.tar $controldir/conbackup.ctl $controldir/control.sql

    rm -f $controldir/conbackup.ctl

    rm -f $controldir/control.sql

    done

#

 

Листинг 3. Полное восстановление БД (файл recover.sh)

#!/bin/sh

#

if [ $# -ne 1 ]

then echo "script needs one parameter: \${ORACLE_SID}"

exit;

fi

#

ORACLE_SID=${1};export ORACLE_SID

sqlplus "/ as sysdba" <<EOF

startup mount;

alter database recover automatic ;

alter database open;

exit;

EOF

 

Листинг 4. Добавление к БД нового временного файла (файл tmprecov.sh)

#!/bin/sh

#

if [ $# -ne 1 ]

   then echo "script needs one parameter: \${ORACLE_SID}"

   exit;

fi

#

ORACLE_SID=${1};export ORACLE_SID

#

#Temporary files

templist=`sqlplus -s "/ as sysdba" <<EOF

set heading off

set pagesize 0

set linesize 300

set feed off

select file_name from dba_temp_files;

exit;

EOF`

for i in ${templist}

    do

sqlplus "/ as sysdba" <<EOF

alter database tempfile '$i' drop INCLUDING DATAFILES;

ALTER TABLESPACE "TEMP" ADD TEMPFILE '$i'  size 25M autoextend on;

exit;

EOF

done

 

Листинг 5. Восстановление БД при утере копии вновь добавленного файла и файлов управления (файл addfile.sh)

#!/bin/sh

#

#Script for adding new dstsfile

sqlplus "/ as sysdba" <<EOF

alter tablespace users add datafile

'/ora/oracle/oradata/ORCL/users02.dbf' size 20M;

exit

EOF

 

Листинг 6. Неполное восстановление при потере активных журналов (файл nofile.sql)

connect / as sysdba

startup mount

alter database recover automatic using backup controlfile

--

--ERROR at line 1:

--ORA-00283: recovery session canceled due to errors

--ORA-01244: unnamed datafile(s) added to control file by media recovery

--ORA-01110: data file 5: '/ora/oracle/oradata/ORCL/users02.dbf'

--

alter database backup controlfile to trace as

'dmpctl.sql';

select name from v$datafile where file#=5;

--NAME

------------------------------------------------

--/ora/oracle/dbs/UNNAMED00005

--

alter database create datafile

'/ora/oracle/dbs/UNNAMED00005'

as '/ora/oracle/oradata/ORCL/users02.dbf';

-- Make changes in scripts for recreate controlfile.

host vi dmpctl.sql

--

shutdown

@dmpctl.sq

 

Листинг 7. Неполное восстановление при потере активных журналов (файл recovincomplett.sh)

#!/bin/sh

#

if [ $# -ne 1 ]

then echo "script needs one parameter: \${ORACLE_SID}"

exit;

fi

sqlplus "/ as sysdba" <<EOF

startup mount;

alter database recover automatic using backup controlfile;

alter database open resetlogs;

exit;

EOF

  1. Oracle Database Backup and Recovery Advanced User's Guide 10g Release 2 (10.2) Part Number B14191-02 – http://download-uk.oracle.com/docs/cd/B19306_01/backup.102/b14191/toc.htm.
  2. Oracle8i Backup & Recovery Handbook, Rama Velpuri and Anand Adkoli.McGraw-Hill/OsborneMedia; 4Rev Ed edition (November 14, 2000).

Комментарии отсутствуют

Добавить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-45
E-mail: sa@samag.ru