AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Администрирование
DAX
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 16.02.2017, 11:00   #1  
Ivanhoe is offline
Ivanhoe
Участник
Аватар для Ivanhoe
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
4,143 / 2155 (80) +++++++++
Регистрация: 29.09.2005
Адрес: Санкт-Петербург
Перенос доработок на Prod
AX 2012. Какие способы сократить downtime вы используете? На практике.
__________________
Ivanhoe as is..
За это сообщение автора поблагодарили: macklakov (5).
Старый 16.02.2017, 11:27   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
отделить и распаралелить процессы синхронизации базы и накатывания доработок.
За это сообщение автора поблагодарили: Ivanhoe (2).
Старый 16.02.2017, 11:43   #3  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
870 / 637 (23) +++++++
Регистрация: 14.10.2004
И у меня вопрос: почему один и тот же код начинает работать по-разному со включенным и отключенным CIL? Я всегда делаю инкрементный CIL после накатывания доработок. Или этого мало?
Старый 16.02.2017, 11:54   #4  
Ivanhoe is offline
Ivanhoe
Участник
Аватар для Ivanhoe
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
4,143 / 2155 (80) +++++++++
Регистрация: 29.09.2005
Адрес: Санкт-Петербург
В CIL реально есть вещи, которые работают по другому, при чем как by design, так и в следствие ошибок.

Про синхронизацию БД - есть ли какие-то варианты ее сократить? Как глобальная корпорация с офисами по миру (да и просто с отгрузками 24х7) может выделить 20-30 минут для синхронизации базы? Я уже молчу про ТБ базы.
__________________
Ivanhoe as is..
Старый 16.02.2017, 12:05   #5  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Ivanhoe Посмотреть сообщение
Про синхронизацию БД - есть ли какие-то варианты ее сократить? Как глобальная корпорация с офисами по миру (да и просто с отгрузками 24х7) может выделить 20-30 минут для синхронизации базы? Я уже молчу про ТБ базы.
20-30 минут - не реально.
в Дикси было минимум ночь. база там была 30-40Тб.

сократить время синхронизации можно.
но за счет того, что изменение схемы делается ТОЛЬКО админскими скриптами, а не из аксапты.
это очень сложно. но можно. и не каждому стоит советовать такое.

например, в той же Дикси, создание/изменение/удаление индексов со стороны аксапты было запрещено админами.

тут очень много клиентской специфики.
попробуй таки поговорить с людьми из Дикси. они вменяемые.

на самом верхнем логическом уровне - распараллеливать операции.
со всеми вытекающими последствиями работы с паралелльными потоками.
За это сообщение автора поблагодарили: alex55 (1).
Старый 16.02.2017, 12:07   #6  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,890 / 5647 (194) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Я все-таки наивно спрошу - а как вы обновление делаете ? Весь modelstore переливаете, ставите свою model или просто проект перекидываете ? Просто по моим наблюдениям, если у вас уже все в production достаточно давно (раз база данных большая), вероятность конфликта обновлений не высока, и в 99% случаев можно тупо перекидывать XPO и потом делать Incremental CIL...
За это сообщение автора поблагодарили: Ace of Database (2).
Старый 16.02.2017, 12:23   #7  
Ivanhoe is offline
Ivanhoe
Участник
Аватар для Ivanhoe
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
4,143 / 2155 (80) +++++++++
Регистрация: 29.09.2005
Адрес: Санкт-Петербург
Про Дикси понятно. Скрипты мы тоже писали на больших проектах еще для 3.0. Но это действительно хакерство и не для всех.

Как MS официально предполагает делать синхронизацию? Кроме скриптов больше никак не ускорить?
__________________
Ivanhoe as is..
Старый 16.02.2017, 12:28   #8  
Ivanhoe is offline
Ivanhoe
Участник
Аватар для Ivanhoe
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
4,143 / 2155 (80) +++++++++
Регистрация: 29.09.2005
Адрес: Санкт-Петербург
Цитата:
Сообщение от fed Посмотреть сообщение
Я все-таки наивно спрошу - а как вы обновление делаете ? Весь modelstore переливаете, ставите свою model или просто проект перекидываете ? Просто по моим наблюдениям, если у вас уже все в production достаточно давно (раз база данных большая), вероятность конфликта обновлений не высока, и в 99% случаев можно тупо перекидывать XPO и потом делать Incremental CIL...
Мы используем все три варианта: проекты, модель, БД. На разных проектах могут быть разные подходы, в т.ч. из-за:
1. допустимый downtime
2. необходимость делать копию данных -1 день на тестовом приложении
3. скорость исправления ошибки на prod
4. количество изменений

Я про большую БД не говорил - это mazzy

У меня даже на запускаемых проектах, где БД не сильно большая всё упирается в синхронизацию. Т.е. перенести теми же проектами + компиляция я могу за 15 минут на выделенный AOS, потом перезапуск всех AOS, тут даже днем на большом предприятии можно найти время. А вот сделать синхронизацию - минут 20. А если пользователи должны работать - то не прогнозируемо, т.к. блокировки начинаются.
__________________
Ivanhoe as is..
Старый 16.02.2017, 13:06   #9  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,867 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
А на что у вас тратится время при синхронизации ?
Можно выделить несколько причин замедления :
1. Медленное обращение к метаданным SQL сервера - когда долго идет сканирование каие таблички
есть в наличии и.т.п.
2. Долгое создание индексов
3. Долгое создание полей.
4. Долгое пересоздание табличек при изменении длины строковых полей.

Предлагаю рассмотреть каждый фактор и дальше уже решать что делать.
По п.1 - можно пошаманить с SQL - как ускорить процесс. Например, на форуме была тема где это обсуждалось применительно к ораклу - там шаманили с материализованными вьюхами и.т.п.
Долгая синхронизация
Возможно для SQL тоже можно что-то такое применить. Или иной способ. Мне тоже не нравится как долго он делает сканирование - сравниваю скорость синхронизации на 2009-й под Ораклом и на 2012 R3 под SQL - намного дольше начитывает данные о табличках. Т.е. явно подтормаживает обращение в системным вьюхам содержащим инфу а табличках, их полях и индексах. Наверняка этот процесс можно ускорить - надо покопать соответствующие ресурсы по SQL серверу.

По п.2 можно индексы отдельно создавать - онлайн. Если база большая то БД скорее всего в Enterprise версии, так что позволит это сделать.

По п.3 надо смотреть - не готов что-то советовать.

По п.4 Тоже решаемо. Описывал способ решения тут:
Длина номера фактуры, накладной больше 20 символов.
делается несложно.
Джоб для правки SQLDictionary :
X++:
static void SQLDictionaryFix(Args _args)
{
    int                         strSize = 20; //pkoz 28.10.2013
    AsciiIo                     Source;
    dialog                      dialog = new dialog("");
    dialogfield                 fileName;
    filenameopen                _fileName;
    container                   OneRec;
    InvoiceId                   invoiceID;
    container                   con;
  // pkoz 15.06.2006 -->
    custTable                   custTable;
    custSettlement              _custSettlement;
  // pkoz 15.06.2006 <--

    identifiername              tableName;
    identifiername              fieldName;

    TableId                     TableId;
    FieldId                     FieldId;

    SQLDictionary               SQLDictionary;
    SQLDictionary               SQLDictionary2;
    ;
//    appl.setDefaultCompany("904");
//    appl.setDefaultCompany("905");
    fileName            = dialog.addFieldValue(typeId(filenameopen),_filename,"Файл с данными");
//    fileName.value(@"c:\_\Estate.csv");
//    fileName.value(@"c:\_\SQLDictionaryFix.csv"); //pkoz 28.10.2013
//    fileName.value(@"c:\_\FK2.csv"); //pkoz 28.10.2013
    fileName.value(@"c:\_\FK_126468_myach.csv"); //pkoz 21.09.2015
    dialog.run();
    if ( dialog.closedOk())
    {
        _filename = filename.value();

        // pkoz, 11.04.2014 -->
        if ( Box::yesNo_Net(strFMT("Длина %1 ?", strSize), DialogButton::No) != DialogButton::Yes)
        {
            return;
        }
        // pkoz, 11.04.2014 <--

        Source = SysDataIntegration::openFile(_filename,"R",";");
        if ( source)
        {
            ttsBegin;
            while(source.status() == IO_status::Ok)
            {
                // [invoiceID] = source.read();
                con = source.read();
                if (con)
                {
                    tableName = GRD_ConPeekStr( con, 1);
                    fieldName = GRD_ConPeekStr( con, 2);
                    TableId = tablename2Id( tableName );
                    if ( !TableId )
                    {
                        warning(strFMT("Не определили TableId по %1 и %2", tableName, fieldName ));
                        continue;
                    }

                    fieldId = fieldName2id( TableId, fieldName );
                    if ( !fieldId )
                    {
                        warning(strFMT("Не определили fieldId по %1 и %2", tableName, fieldName ));
                        continue;
                    }


                    SQLDictionary = null;
                    select forUpdate SQLDictionary
                    where
                        SQLDictionary.name    == fieldName &&
                        SQLDictionary.tabId   == TableId &&
                        SQLDictionary.fieldId == fieldId
                    ;
                    if ( !SQLDictionary )
                    {
                        warning(strFMT("Не определили SQLDictionary по %1 и %2", tableName, fieldName ));
                        continue;
                    }

                    if ( SQLDictionary.fieldType != Types::RString &&
                         SQLDictionary.fieldType != Types::String &&
                         SQLDictionary.fieldType != Types::VarString
                       )
                    {
                        warning(strFMT("Поле в SQLDictionary не строковое по %1 и %2", tableName, fieldName ));
                        continue;
                    }

                    if ( SQLDictionary.strSize > strSize )
                    {
                        warning(strFMT("Поле в SQLDictionary уже длиннее по %1 и %2", tableName, fieldName ));
                        continue;
                    }

                    SQLDictionary.strSize = strSize;
                    SQLDictionary.update();
                    info(strFMT("Обновили по %1 и %2", tableName, fieldName ));

                }
            }
            ttsCommit;
        }
    }

    info( "ок" );

}
Скрипты для SQL тоже легко генерятся если удалось составить перечень табличек и полей.

Еще как вариант, если много модификаций переносится, то может имеет смысл не скопом все накатывать а разбить процесс на несколько обновлений - чтобы каждый раз небольшие изменения в БД вносились. Можно ведь сперва БД изменять пошагово, а потом уже накатить/включить бизнеслогику.

Последний раз редактировалось Logger; 16.02.2017 в 13:50.
За это сообщение автора поблагодарили: mazzy (2), macklakov (5), trud (1), Ace of Database (3), Ivanhoe (5), Товарищ ♂uatr (1).
Старый 16.02.2017, 13:09   #10  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,867 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Ivanhoe Посмотреть сообщение
А если пользователи должны работать - то не прогнозируемо, т.к. блокировки начинаются.
А в 2012-ю версию вообще не проектировали на обновление по-живой.
Иначе бы не было вот такого
Ax 2012 R2. Поле "не извлечено"

В общем все грустно.
Старый 16.02.2017, 13:32   #11  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Ivanhoe Посмотреть сообщение
Как MS официально предполагает делать синхронизацию? Кроме скриптов больше никак не ускорить?
как это написано сейчас - последовательно, таблица за таблицей.
что, может быть, и оправдано в общем случае, когда все таблицы на одном диске в одном сегменте.

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

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

но тут начинаются: вопросы логической целостности при параллельных заданиях, вопросы как разбито на физические устройства, deadlock и прочее.

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

примерно так.
Старый 19.02.2017, 14:25   #12  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,038 / 1629 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от mazzy Посмотреть сообщение
но тут начинаются: вопросы логической целостности при параллельных заданиях, вопросы как разбито на физические устройства, deadlock и прочее.
Все же думаю алгоритм немного кривоват, а не "физические диски". т.е. самый простой случай - запускаем синхронизацию без каких то изменений в структуре данных. она работает минут 20
Кстати в АХ7 реализована наконец-то параллельная синхронизация, т.е. выполняется побыстрее при 100% загрузке процессора
Документ "Microsoft Dynamics AX 2012 White Paper: Deploying Customizations Across Microsoft Dynamics AX 2012 Environments" описывает довольно экзотические способы снижения downtime "Import a model store with minimal downtime", интерестно так кто нибудь делает?
Цитата:
To reduce downtime, we recommend that you import the metadata into a new schema next to the old one, and then switch to the active schema. This methodology lets users continue using the system until the AOS instance needs to be restarted so that the new schema can be applied.
Ну и развертывание всех отчетов - тоже по времени сравнимо с полной синхронизацией, думаю очевидным решением будет развертывать и синхронизировать только то что менялось

Последний раз редактировалось trud; 19.02.2017 в 14:31.
За это сообщение автора поблагодарили: Logger (1).
Старый 19.02.2017, 15:00   #13  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от trud Посмотреть сообщение
Все же думаю алгоритм немного кривоват, а не "физические диски". т.е. самый простой случай - запускаем синхронизацию без каких то изменений в структуре данных. она работает минут 20
Кстати в АХ7 реализована наконец-то параллельная синхронизация, т.е. выполняется побыстрее при 100% загрузке процессора
возможно. для синхронизации в общем случае узким местом является не процессор.
а можно подробнее про параллельную синхронизацию в акс7 или ссылку? похоже, я пропустил.
Старый 19.02.2017, 15:50   #14  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,038 / 1629 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от mazzy Посмотреть сообщение
а можно подробнее про параллельную синхронизацию в акс7 или ссылку? похоже, я пропустил.
Было в каком-то whats new. В принципе достаточно просто запустить, и увидеть что грузятся все ядра, а не одно как было в 2012
Старый 19.02.2017, 17:48   #15  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от trud Посмотреть сообщение
Документ "Microsoft Dynamics AX 2012 White Paper: Deploying Customizations Across Microsoft Dynamics AX 2012 Environments" описывает довольно экзотические способы снижения downtime "Import a model store with minimal downtime", интерестно так кто нибудь делает?
А что там экзотичного ? Когда время ограничено - я так делал. Импортнули modelstore во временную схему "на ходу" (не останавливая работу), остановили AOS-ы, переключили схему, запустились на выделенном AOS, синхронизация - и можно запускать остальных и деплоить отчеты
P.S. Ждать пока задеплоятся все отчеты - совсем необязательно
__________________
-ТСЯ или -ТЬСЯ ?

Последний раз редактировалось Vadik; 19.02.2017 в 17:51.
Старый 19.02.2017, 17:50   #16  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от trud Посмотреть сообщение
Было в каком-то whats new. В принципе достаточно просто запустить, и увидеть что грузятся все ядра, а не одно как было в 2012
А толку с нее ? В продуктиве MS сам деплоит, и резервирует на все про все 5 часов. По факту - последнее время управляются за 2.5-3
__________________
-ТСЯ или -ТЬСЯ ?
За это сообщение автора поблагодарили: trud (1).
Старый 19.02.2017, 18:11   #17  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от Ivanhoe Посмотреть сообщение
Как глобальная корпорация с офисами по миру (да и просто с отгрузками 24х7) может выделить 20-30 минут для синхронизации базы?
Ну в каком-то формате (или гарантированный даунтайм или временная ограниченная работоспособность) - пострадать придется. Полчаса-час простоя раз в неделю или месяц корпорация допускает?
__________________
-ТСЯ или -ТЬСЯ ?
Старый 19.02.2017, 22:26   #18  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
699 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
Цитата:
Сообщение от trud Посмотреть сообщение
Документ "Microsoft Dynamics AX 2012 White Paper: Deploying Customizations Across Microsoft Dynamics AX 2012 Environments" описывает довольно экзотические способы снижения downtime "Import a model store with minimal downtime", интерестно так кто нибудь делает?
Мы так делаем, в итоге downtime упирается в те же 20 мин синхронизации. Потому что компилить ничего не надо только AOSы перегрузить, а компиляцию и CIL делаем на отдельной машине. В итоге подготовленный modelsore можно накатить на "PreProd" и потестить перед накаткой на PROD, а то бывает кто-то криво код сведет или чего забудет...
По поводу 7ки на яммере МС писали что и сейчас весь downtime уходит на синхронизацию, мол они работают над этим но пока ничего не придумали
За это сообщение автора поблагодарили: Logger (1).
Старый 20.02.2017, 03:47   #19  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,038 / 1629 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от Vadik Посмотреть сообщение
А толку с нее ? В продуктиве MS сам деплоит, и резервирует на все про все 5 часов. По факту - последнее время управляются за 2.5-3
О..
Кстати вчера вышел Update4, теперь обещают greatly reduced

Цитата:
Apply deployable packages with reduced downtime.
Currently, the average downtime needed to apply a single package in an environment deployed through LCS is 5 hours. With this feature, the package application is optimized so that the downtime is greatly reduced.
Кстати а вот вопрос - если после обновления надо что-нибудь поотлаживать на копии текущей рабочей БД, сколько времени по факту занимает получение такой копии? я так понимаю создается запрос в поддержку на получение копии БД, который может выполняться 1 бизнес день?, потом еще сколько то на развертывание этой копии.. и т.д. Как вы решаете такое?
Старый 20.02.2017, 08:15   #20  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от trud Посмотреть сообщение
О..
Кстати вчера вышел Update4, теперь обещают greatly reduced
Таки там с двух сторон пилят - и платформу, и LCS (в январе кажется начали независимые шаги типа накатывания бинарных обновлений на AOS-ы исполнять параллельно). У нас и на Update 2 процесс ускорился с 5 до 3 часов
Цитата:
Кстати а вот вопрос - если после обновления надо что-нибудь поотлаживать на копии текущей рабочей БД, сколько времени по факту занимает получение такой копии? я так понимаю создается запрос в поддержку на получение копии БД, который может выполняться 1 бизнес день?, потом еще сколько то на развертывание этой копии.. и т.д. Как вы решаете такое?
Service request на LCS, указываем откуда, куда и когда восстанавливать (не менее чем за 5 часов). Собственно восстановление где-то за час делают (почему-то руками / скриптами)
Миниатюры
Нажмите на изображение для увеличения
Название: snip_20170220081214.png
Просмотров: 399
Размер:	28.2 Кб
ID:	11220  
Изображения
 
__________________
-ТСЯ или -ТЬСЯ ?
Теги
ax2012, как правильно, обновление, синхронизация

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Перенос пакета и Перекрытие neopl DAX: Функционал 7 15.03.2012 23:12
Финансовые проводки по журналу "Перенос" (AX 2009) MrVlasoff DAX: Функционал 16 22.03.2010 11:32
Перенос конфигурации без данных rwx DAX: Администрирование 9 01.10.2009 10:15
Перенос переменной в конфигураторе продукции Serg DAX: Функционал 0 09.12.2005 13:43
Перенос номенклатуры со склада на склад efim DAX: Функционал 4 04.04.2003 13:56
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 18:32.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.