|
Ричард Дж. Нимик
20 заповедей начинающего Администратора Базы Данных (20 Tips for the
bigining DBA, by Richard J. Niemiec, “SELECT”, vol. 2, No 4, July 95)
[От редакции OM/RE: Эта статья из архива нашего журнала была опубликована лет десять назад,
еще в бумажной его версии. На мой взгляд, она сыграла большую положительную роль в становлении многих АБД Oracle
и до сих пор во многом не потеряла своей актуальности. Но все же перепубликация "20 заповедей начинающего Администратора Базы Данных"
в нынешнем выпуске журнала предпринимается главным образом с целью показать, как со временем и развитием СУБД Oracle
меняются основополагающие установки АБД. Прочитайте же публикуемую рядом статью "Пятнадцать вещей об Oracle, от которых
должны отучиться АБД".
Анатолий Бачин,
главный редактор "Oracle Magazine/Русское Издание"]
Начинающие администраторы баз данных (АБД) сталкиваются с многими проблемами,
большинство из которых имеет истоком их недостаточное знание системы. Эта статья
содержит серию указаний, которые обеспечат начальную ориентировку на ранних
этапах деятельности АБД.
Главные темы:
- Архитектура Oracle: Изучите, как работает Oracle
- Правильная установка и достаточное количество журнальных файлов
- Правильная установка и достаточное количество сегментов отката
- Наличие отдельного табличного пространства временных сегментов, где
производится пользовательская сортировка
- Наличие достаточного количества управляющих файлов
- Правильная установка значений важнейших параметров в файле INIT.ORA
- Распределение основных файлов данных между несколькими дисками
- Использование соглашений об именах и установок OFA
- Насколько велика база данных?
- Нахождение информации о таблице
- Нахождение информации об индексе
- Исключение фрагментации
- Изменение структуры таблицы (“на лету”)
- Правило 95/5 (настройка запросов)
- Использование утилиты EXPLAIN для настройки запросов
- Перенос файла данных табличного пространства
- Что такое параллельный запрос?
- Создание резервного образа базы данных
- Выбор схемы резервирования
- Участие в группах пользователей
- Архитектура Oracle: Изучайте, как работает Oracle
ЗАПОВЕДЬ_1: Изучение Oracle поможет Вам применить ОБЩИЕ указания Oracle
для Ваших УНИКАЛЬНЫХ приложений.
- Правильная установка журнальных файлов
- Журнальный файл должен быть в оперативном состоянии и доступен все
время, пока база данных функционирует, в противном случае база данных
обрушивается!!
- Журнальные файлы используются циклически.
- Неоперативные журнальные файлы - это те, что закрыты для проведения
архивации или резервирования. Файлы архивных журналов циклически не
используются.
- Минимально должно быть два оперативных журнальных файла; настоятельно
рекомендуется использовать большее число (не менее трех) журнальных файлов.
ЗАПОВЕДЬ_2: Определите размер журнальных файлов так, чтобы они
переключались каждые 30-60 минут. Когда Oracle функционирует в режиме
ARCHIVELOG, достаточное число журналов определяется так, чтобы наибольший
пакетный процесс изменения/вставки/удаления записей не переполнил (циклически)
ВСЕ журнальные файлы.
ЗАПОВЕДЬ_2а: Определите место нахождения журнальных файлов на других
устройствах, нежели там, где размещаются файлы Вашей базы данных.
- Правильная установка и достаточное количество сегментов отката
- Обычно НЕ нужно более одного сегмента отката для каждого пользователя в
каждый момент времени.
- Пакетные процессы обычно нуждаются в сегменте отката большого размера.
Пользователь должен применять команду “set transaction use
rollback segment <имя_сегмента>” с тем, чтобы большая
транзакция работала с этим большим сегментом отката: SQL> set
transaction use rollback segment rb_big;
ЗАПОВЕДЬ_3: Обеспечьте наличие одного большого сегмента отката и
добейтесь использования команды “set transaction use ...”.
- Наличие отдельного табличного пространства временных сегментов, где
производится пользовательская сортировка
- По умолчанию временные сегменты располагаются в табличном пространстве
SYSTEM. Надо ИЗГНАТЬ их из него, определив для всех пользователей
“Alter User <name> temporary tablespace TEMP;”
- Временный сегмент создается, когда не достаточно оперативной памяти
(параметр SORT_AREA_SIZE в файле INIT.ORA), чтобы обработать целиком
выбранное по запросу множество данных.
- Предложения, порождающие временные сегменты:
- Create Index
- Select .... Order By
- Select .... Distinct
- Select .... Group By
- Select .... Union
- Select .... Intersect
- Select .... Minus
- Неиндексированные соединения (Unindexed Joins)
- Некоторые соотнесенные запросы
SQL>
ALTER USER username TEMPORARY TABLESPACE temp;
ЗАПОВЕДЬ_4: Создайте специальное табличное пространство для временных
сегментов и примените команду “Alter user ...”, чтобы заставить пользователей
работать именно с этим пространством.
- Наличие достаточного количества управляющих файлов (Используем четыре -
они маленькие)
- Без наличия хотя бы одного дееспособного управляющего файла Ваша система
не работоспособна (без серьезной работы по восстановлению).
- Рекомендуется иметь минимум два управляющих файла.
- Я рекомендую держать четыре управляющих файла (на отдельных дисках и
даже на отдельных контроллерах, если возможно).
- Управляющие файлы сохраняют информацию о физической структуре базы
данных, которая используется в процессам стартирования/завершения и
архивирования.
ЗАПОВЕДЬ_5: Обеспечьте наличие четырех управляющих файлов на различных
дисках. Местоположение не менее одного управляющего файла должно быть отдельно
от других файлов базы данных.
- Правильная установка значений важнейших параметров в файле INIT.ORA
Модификация INIT.ORA
Для того, чтобы система как целое работала эффективно, должны быть
правильно установлены параметры в файле INIT.ORA. Хотя настройка запросов
является основой в достижении наивысшей производительности, система работает
медленно, если параметры в INIT.ORA установлены неправильно.
- Первое внимание - параметру DB_BLOCK_BUFFERS (Наиболее важный
параметр в Oracle!)
- если значение DB_BLOCK_BUFFERS мало, пользователи не получают
достаточно памяти для эффективного функционирования.
- Если DB_BLOCK_BUFFERS велико, система начинает свопировать (swap) и
может произойти остановка.
ЗАПОВЕДЬ_6: Установите размер DB_BLOCK_BUFFERS примерно в 25% от общего
объема памяти ЭВМ, но Ваша установка должна учитывать и число пользователей.
Замечание: Это определяется числом конкурирующих пользователей и тем,
что выделена или нет Ваша машина исключительно под Oracle.
- Определение оптимального использования и достаточного количества буферов
блоков данных
Если коэффициент попадания по чтению (read hit ratio) меньше 95%, следует
увеличить значение параметра DB_BLOCK_BUFFERS, чтобы повысить
производительность. Однако, имейте в виду, что если коэффициент близок к
100%, а число операций чтения исчисляется в миллионах, высока вероятность
того, что исполняемое предложение построено не оптимально. select name, value from v$sysstat
where name in ('db blocks get','consistent gets','phisical reads');
name value
-----------------------------------------------
db blocks get 10000
(число чтений буферов блоков)
consistent gets 90000
(число логических операций чтения
в режиме целостного чтения)
phisical reads 20000
(число операций физического чтения)
Коэффициент попадания = 1 - физические/логические чтения х 100% = 1 -
20000/(10000 + 90000) x 100% = 80%
- Следующий по значимости параметр SHARED_POOL_SIZE (только Oracle7
и далее). Он задает размер памяти для размещения библиотек и кеша словаря
данных
Определение коэффициента пропуска кеша словаря данных
Если величина коэффициента, вычисляемого по приведенному ниже запросу,
больше 15 процентов, следует увеличить значение параметра SHARED_POOL_SIZE в
файле INIT.ORA. Это - важнейшая область памяти, поскольку особенно часты
обращения к словарю по внутренним вызовам Oracle. Я никогда бы не
посоветовал уменьшать значение SHARED_POOL_SIZE, поскольку библиотечный кеш
является также частью этого разделяемого пула. select sum(gets), sum(getmisses),
sum(getmisses)/sum(gets) “Ratio of Misses” from v$rowchache;
Gets: 20000
Getmisses: 1000
Miss Ratio: 5%
Это - хорошее значение коэффициента и нет необходимости проводить
какие-либо действия с этой областью.
ЗАПОВЕДЬ_6а: Установите значение параметра SHARED_POOL_SIZE примерно
от 50% до 75% от принятого Вами значения DB_BLOCK_BUFFERS.
- Распределение основных файлов данных между несколькими дисками
- Табличное пространство SYSTEM
- Табличное пространство для временных сегментов (TEMPORARY)
- Табличное пространство для сегментов отката
- Журнальные файлы (The REDO logs)
- Диск операционной системы
- Файлы базы, содержащие интенсивно используемые таблицы
- Файлы базы, содержащие интенсивно используемые индексы
Пример распределения файлов при наличии 11-ти дисков
- Диск0: Операционная система
- Диск1: Табличное пространство для временных сегментов, управляющий файл
1
- Диск2: Табличное пространство для сегментов отката, управляющий файл 2
- Диск3: Применяется для временных или отката сегментов,”Индекс_2”
- Диск4: Табличное пространство SYSTEM
- Диск5: Табличное пространство “Данные_1”, управляющий файл 3
- Диск6: Табличное пространство “Индекс_3”, управляющий файл 4
- Диск7: Табличное пространство “Данные_2”
- Диск8: Журнальные файлы
- Диск9: Табличное пространство “Данные_3”
- Диск10: Табличное пространство “Индекс_1”
Замечание: Следует помнить, что операции ввода/вывода с индексами и
записями журналов весьма различны. Это важно, когда журнальные файлы и индексы
размещаются на одном и том же диске. Журнальные файлы записываются
последовательно относительно большими порциями. Индексы читаются и пишутся
прямым образом. Помещение индексных файлов на то же самое устройство, что и
журналов, может снизить скорость операций записей в журнал. Требуется иметь
несколько журналов (см. ЗАПОВЕДЬ_2).
Табличные пространства для таблиц и индексов
- Следует разнести таблицы и индексы на все диски для равномерного
использования дисков.
- Таблицы, которые часто работают в соединениях (Joined), должны иметь
данные и индексы раздельно, как показано в следующем примере:
select COL1, COL2 FROM CUST_HEADER, CUST_DETAIL ....;
Одно из возможных решений:
- Диск1: таблица CUST_HEADER
- Диск2: индекс CUST_HEADER
- Диск3: таблица CUST_DETAIL
- Диск4: индекс CUST_DETAIL
ЗАПОВЕДЬ_7: Разносите основные файлы Oracle и разносите файлы данных и
индексов, используемые приложением. Храните файлы данных (таблицы) на
различных дисках и управляйте размещением соответствующих файлов индексных
данных.
- Использование соглашений об именах и установок OFA
Установки OFA: Optimal Flexible Architecture - Оптимальная Гибкая
Архитектура (Замечание: OFA включает более, чем только Соглашения об именах)
- Табличное пространство SYSTEM:
- system01.dbf
- system02.dbf
- Журнальный файл группы 1: redo101.dbf
- Журнальный файл группы 1: redo102.dbf
- Журнальный файл группы 2: redo201.dbf
- Журнальный файл группы 2: redo202.dbf
- Табличное пространство RBS (сегменты отката) :
- Табличное пространство TEMP (временные сегменты) :
- Управляющий файл 1: (path)/control.dbf
- Управляющий файл 2: (path)/control.dbf
- Управляющий файл 3: (path)/control.dbf
- Табличное пространство USERS (таблицы пользователей) :
- Табличное пространство TOOLS (инструментарий Oracle):
- Табличное пространство ORD (часто читаемые таблицы (данные)):
- Табличное пространство ORX (часто читаемые таблицы (индексы)):
ЗАПОВЕДЬ_8: Используйте соглашения об именах для улучшения управления
базой данных, а также для того, чтобы файлы базы не были “случайно”
уничтожены.
- Насколько велика база данных?
Выполните приведенные запросы для получения значений распределенного
пространства и свободного объема памяти по каждому табличному пространству
Вашей базы данных. compute sum of bites on report
break on report
col bytes format 999,999,999,999
col1 tablespace_name heading 'Tablespace'
spool db_size_out
Select tablespace_name,sum(bites) bites
From dba_data_files
Group by tablespace_name;
Tablespace Bites
-----------------------------------
SYSTEM 30,000,000
ORDER_D 300,000,000
ORDER_I 150,000.000
sum 480,000,000
Скрипт spool db_free.out
Select tablespace_name,sum(bites) bites
From dba_free_space
Group by tablespace_name;
Tablespace Bites
-----------------------------------
SYSTEM 10,000,000
ORDER_D 5,000,000
ORDER_I 2,000.000
sum 17,000,000
ЗАПОВЕДЬ_9: Регулярно проверяйте размер табличных пространств и наличие
свободного пространства.
- Нахождение информации о таблице
Следующий пример показывает, как получить сведения об основных параметрах
определения отдельных таблиц. Select Table_name, Initial_Extent, Next_Extent,
Pct_Free, Pct_Increase From DBA_TABLES
Where Table_name IN ('ORDER', 'CUST');
Table Initial Next Pct_Free Pct_Inc
-------------------------------------------------------
Order 20,000,000 2,000,000 20 0
Cust 10,000,000 1,000,000 10 0
- Нахождение информации об индексе
Следующий пример показывает, как получить сведения об основных параметрах
определения отдельных индексов. Select Index_name, Initial_Extent, Next_Extent,
Pct_Free, Pct_Increase From DBA_INDEXES
Where Index_name IN ('ORDER_I', 'CUST_I');
Index Initial Next Pct_Free Pct_Inc
-------------------------------------------------
Order_I 10,000,000 5,000,000 20 0
Cust_I 5,000,000 500,000 10 0
ЗАПОВЕДЬ_10/11: Просматривайте сведения о таблицах и индексах на
предмет потенциальных проблем с памятью и/или проведением их изменений,
вызванных с фрагментацией и наличием сцеплений блоков (fragmentation or
chaining).
- Исключение фрагментации
Общие положения:
- Фрагментация таблиц имеет место, когда таблицы состоят из нескольких
экстентов (участков).
- Фрагментация строк имеет место, когда записи в таблицах обновляются, и
блоки, в которых они содержались, не имеют достаточно места, чтобы сохранить
измененные записи. Эта проблема известна, как “сцепление блоков” (block
chaining) или просто “сцепление” (chaining).
- Фрагментация словаря базы данных имеет место, когда расширяются
“Oracle-порожденные” таблицы словаря данных.
- В версии Oracle7 издержки фрагментации составляют 10-20%.
Нахождение таблиц и индексов, состоящих из пяти и более фрагментов: Select segment_name, extents, next_extent, bytes
From dba_extents where extents > 4;
Segments Extents Next Bytes
------------------------------------------------
Order 20 20,000,000 58,000,000
Исправление табличной фрагментации
Пример:
Таблица CUSTOMER в настоящее время состоит из 22 экстентов по 1М байту
каждый. (Это определено запросом к представлению DBA_EXTENTS.) Решение_1:
CREATE TABLE CUSTOMER1
TABLESPACE NEW
STORAGE (initial 30M NEXT 5M PCTINCRESE 0)
AS SELECT * FROM CUSTOMER;
DROP TABLE CUSTOMER;
RENAME CUSTOMER1 TO CUSTOMER;
Создайте индексы, привилегии,... для новой таблицы CUSTOMER.
Замечание: Этот метод требует, чтобы Вы отменили первичные (PRIME)
ограничения целостности, наложенные на эту таблицу перед ее переопределением.
После того, как таблица создана, переименована, а старая таблица уничтожена,
надо восстановить первичные ограничения целостности.
Решение_2:
- Экспорт (с компрессированием) таблицы CUSTOMER.
- Удаление (drop) таблицы CUSTOMER.
- Импорт таблицы CUSTOMER.
(Не забывайте индексы, привилегии и ограничения целостности.)
Замечание: Это решение может стать причиной фрагментации свободного
пространства. После того, как начальная таблица удалена, некоторые занимаемые
ею экстенты не будут использованы новой таблицей. Возможно они будут
перемежовываться с экстентами других таблиц.
ЗАПОВЕДЬ_12: Чаще исследуйте базу данных на предмет выявления
фрагментации. Если фрагментация больше, чем пять экстентов для одной таблицы,
выберите время, когда эту таблицу можно дефрагментировать.
- Изменение структуры таблицы (“на лету”)
Фрагментация может повредить производительности базы данных. Ключом к
исключению фрагментации является перестроение таблицы или на первых порах
определенная корректировка ее размера.
Симптомы:
- Таблица ORDER построена две недели назад со следующим определением
памяти:
- Начальный (Initial) экстент = 2М ;
- Следующий (Next) экстент = 1М ;
- Коэффициент возрастания экстентов (Pctincrease) = 0
- Таблица ORDER в настоящее время имеет четыре экстента (размером 2М, 1М,
1М, 1М), всего 5М байтов.
- Персонал ввода данных в базу помещает в таблицу ORDER значительно больше
записей, чем Вы предполагали. До конца года таблица ORDER может увеличиться
до 40М байтов.
Решение
ALTER TABLE ORDER STORAGE (NEXT 35M);
- Следующий экстент будет создан размером в 35М байтов, доведя общий
объем таблицы до 40М при общем количестве экстентов ТОЛЬКО 5.
ЗАПОВЕДЬ_13: Исправляйте размеры экстентов до того, как фрагментация
превратится в большую проблему.
- Правило 95/5 (настройка запросов)
Когда Оптимизатор, основываясь на среднем распределении записей, считает,
что по запросу будет извлечено от 5 до 6 процентов записей таблицы, он
стремится проиндексировать запрос, если индекс существует. Но несмотря на то,
что Oracle7 показывает наилучшую производительность на всех уровнях,
разработчик приложений должен знать, когда следует отвергать использование
Оптимизатора.
Пример запроса (мы заставляет оптимизатор использовать индекс): SELECT /*+ INDEX (HOME_OWNERS OWNER) / COUNT()
FROM HOME_OWNERS WHERE OWNER = 'JOE';
Время исполнения 0,6 секунды (без индекса - 6,5 секунд).
ЗАПОВЕДЬ_14: Приучайте разработчиков приложений использовать указания и
применять правило 95/5. Не предполагайте, что Оптимизатор сам примет
правильное решение.
- Использование утилиты Explain для настройки запросов
Почему Explain не использует трассировку (TRACE)?
- Предложения НЕ выполняются; Explain показывает только, как бы
получилось, если бы предложение было выполнено.
Когда использовать утилиту Explain без трассировки:
- Когда запрос выполняется исключительно долго.
Как я использую сам для себя утилиту Explain?
- Нахожу скрипт; он обычно находится в директории
$ORACKE_HOME/rdbms/admin:
- “xplainpl.sql” в Oracle версии 6
- “utlplan.sql” в Oracle версии 7
- Выполняю скрипт посредством SQL*Plus или SQLDBA:
- SQL> @xplainpl (в V6) или
- SQL> @utlplan (в V7)
Вы можете создать свою собственную plan_table, но используйте синтаксис
Oracle и ничего другого !
- Запуск Explain Plan для оптимизации запроса (в версии 7):
SQL> EXPLAIN PLAN
SET STATMENT_ID = 'CUSTOMER' FOR
SELECT CUSTOMER_NUMBER FROM CUSTOMER WHERE CUSTOMER_NUMBER = 111;
Выборка из таблицы PLAN_TABLE:
select operation, option, object_name, id, parent_id, position
from plan_table
where statment_id = 'CUSTOMER' (In V7 Only)
/
Operation Option Object_name ID Parent
------------------------------------------------------------
Select Statment 0 (In V7 Only)
Table Access By Rowid Customer 1
Index Range Scan 2 1
ЗАПОВЕДЬ_15: Используйте утилиту EXPLAIN вместо трассировки, чтобы не
ждать пока выполнится запрос. Используйте трассировку (TRACE) только для
много-запросных пакетных работ, чтобы определить, какой из запросов является
медленным.
- Перенос файла данных табличного пространства
ЗАПОВЕДЬ_16: Перемещайте файлы данных для балансировки файловых операций
ввода/вывода
- Что такое параллельный запрос и как он выполняется
- В версии Oracle7.1 можно распараллелить выполнение одного запроса между
несколькими процессорами, что обеспечит более полное использование мощности
машины.
- Используйте эту возможность посредством применения фразы PARALLEL в
определениях таблиц и индексов.
ЗАПОВЕДЬ_17: Применяйте опцию параллельного выполнения в подходящих
ситуациях, но проверяйте, насколько это Вам выгодно.
- Создание резервного образа базы данных
Исследования показывают, что эффективность деятельности Руководителя MIS
(АДМИНИСТРАТИВНОЙ ИНФОРМАЦИОННОЙ СИСТЕМЫ) оценивается процентом времени, когда
система находилась “в готовности” (is “up”) в течение рабочего времени.
Поэтому планируйте простой системы, связанный с проведением системных
действий, на “пустые” (off-hours) часы!
Файлы, которые ДОЛЖНЫ БЫТЬ резервированы на диск или ленту:
- Все файлы базы данных
- Все управляющие файлы
- Все файлы оперативных журналов (не заархивированные)
- Файл INIT.ORA (не обязательно)
*** БАЗА ДАННЫХ ДОЛЖНА БЫТЬ ОСТАНОВЛЕНА НОРМАЛЬНО ***
(За исключением режима “горячего” резервирования (hot backups))! ***
ЗАПОВЕДЬ_18: База данных должна быть ОСТАНОВЛЕНА для создания
резервного образа.
- Планирование действий по резервированию
ЗАПОВЕДЬ_19: Разработайте планы резервирования И восстановления,
которые включают, как создание резервного образа базы данных, экспорт, так и
архивирование файлов, как минимум.
- Участие в группах пользователей
Самое главное:
- Вы увидите реальную картину, а не радужные картины, которые рисуют люди,
продающие программное обеспечение/услуги/технику.
Типы групп пользователей и формы их работы
- Локальные группы пользователей - собрания, семинары
- Группы по интересам (SIG) - собрания (по платформам/по средствам
(tools)/ по приложениям).
- Региональные Группы Пользователей - мини-конференции и издание
бюллетеней
- Международная - Большие конференции и журнал Select
- Группа MOSES - опыт АБД для VLDB (Очень Большие Базы Данных)
- Группа SMTI (System Managentment Tools Initiative) - Группа по
разработке средств для управления систем (Учет мнений при планировании
развития продуктов Oracle).
Другие места получения помощи
- Oracle Business Alliance (BAP) - Объединение деловых партнеров Oracle.
- Oracle Preferred System Integrator (PSI) - Объединение Системных
Интеграторов Oracle
Где найти номера для контактов с группами:
- Журнал Select
- Журнал Oracle Magazine
- Региональные Бюллютени.
ЗАПОВЕДЬ_20: Участвуйте в собраниях групп и развивайте связи с другими
специалистами, которые делают ту же самую работу, что и Вы.
Использованная литература:
- “Perfomance Tuning; Now YOU are ther Expert” and “Undocumented Index
Suppression”, Rich Niemiec, TUSC; 1991
- “Get the most for your Money: Uttilize the V$ Tables” a presentation by
Joseph C.Trezzo; TUSC
- Database Administration, Version 7 Conversion Cources, TUSC; 1991-1994
- Version 6 & DBA, Migration and Perfomance Tuning Guide, Oracle
Corporation
- “What is a Client/Server and How tj Implement it”, 55 Mir W.Ali, First
National Bank of Chicago
- Version 7 SQL Language Manual, Oracle Corporation
- “Backup and Recovery Planning”, a presentation by Rich Niemiec, TUSC
- Walter Lindsay; EcoSystems Software; 1993 IOUW Proceedings
- Gita Kulandaiswamy; Oracle Corporation; 1993 IOUW Proceedings
- The OFA Standard; Oracle7 for Open Systems; Oracle Corp.; Cary Millsap
- Oracle7 Internal; Oracle Corp.; Craig A.Shallahamer
- Oracle 7.1 Release Features Parallel Everything; Integrator; Summer 1994
- Tuning Oracle for Batch fnd On-Line Processing; Eyal Aronoff; Select
Magazine
Благодарности:Автор особо благодарен Brad Brown, Jie Trezzo и команде
TUSC, способствовавшим в появлении этой статьи.
Об авторе:Richard J. Niemiec (Ричард Дж.Нимик) - Исполнительный
Вице-Президент компании The Ultimate Software Consaltants (TUSC), находящейся
в Lombard штат Illinois, занимающейся консалтингом в области баз данных.
Richard читал лекции и выступал с докладами по тематике Oracle на протяжении
последних семи лет, в настоящее время является Президентом MOUG. Richard
председательствовал на конференциях International Oracle Users Grooup в
1991-1994 годах. Его телефон в TUSC +1.708.960.2909.
|