#msitconf Inside SQL Server I/O Дмитрий Артемов (консультант) dimaa@Microsoft.com Для SQL 2012+ О чем мы НЕ будем говорить NFTS allocation unit = 64Kb. Это в силе • Рекомендации о настройке дисковой подсистемы • Сетевом вводе\выводе • Best Practices – однако, понимание механизмов поможет принимать правильные решения Disk partition alignment – для старых версий Windows. • • • • Always On Availability Groups (и DBM) – но мы обсудим журнал Управление БД (Секции, число файлов,…) Нас интересуют не все пишущие операции – ERRORLOG и XEvent I/O affinity The SQL Server I/O Lifecycle Создание БД – CreateFile() FILE_FLAG_NO_BUFFERING • • • • Обходим кеширование средствами Windows (System File Cache) Нам нужно контролировать процесс средствами Buffer Pool и Log Cache Наша обязанность обеспечить IO по границам секторов Мы должны использовать scatter/gather I/O NTFS компрессия не гарантирует выравнивание секторов FILE_FLAG_WRITE_THROUGH • Указывает Windows и дискам записать изменения на стабильный носитель перед тем как рапортовать о завершении • Оборудование должно обеспечивать это. Проверьте, чтобы стойка поддерживала Force Unit Access (FUA) FILE_FLAG_OVERLAPPED • Необходим для использования асинхронного I/O, мы стараемся все вызовы выполнять в асинхронном режиме. • Используем SetFileIoOverlappedRange() для связки виртуальных адресов с указателем (handle) на файл, что не позволяет сбрасывать структуры в файл подкачки Поддерживаемые файловые системы и типы хранилищ Файловые системы ReFS поддерживается в 2014 но CHECKSUM_TYPE_NONE • NTFS • ReFS • CsvFS – Cluster Shared Volume • CDFS – read only БД Системы хранения • “Локальные диски” • SAN • iSCSI • SMB 2.0+ начиная с SQL 2012 (больше не нужен TF1807) • Azure Blob Storage The SQL Server I/O Reliability Program описывает наши требования к дисковым подсистемам SQL Server и дисковые секторы (журнал) Выравнивание секторов Почему это важно? Мы пишем журнал по секторам Поддерживаем 512, 1K, 2k, 4k, и 512e DeviceIoControl() and fsutil Мы определяем «истинный» размер сектора при открытии файла Размер сектора хранится в метаданных БД Восстановление или перемещение файлов на диск с другим размером сектора может создать проблемы (Log Ship, Availability Groups,…) Нам придется «править» журнал или переходить на синхронный ввод\вывод United States Patent 6,728,879 Создание БД – File Initialization Если нам нужно создать файл определенного размера? Instant File Initialization (IFE) • Вызываем WriteFile() и Windows заполнит его 0 • Или вызываем SetFilePointer() и SetEndOfFile() Windows заполняет его 0 по мере работы с файлом Windows разработчики представили API SetFileValidData() • Один вызов объединяет SetFilePointer() и SetEndOfFile() • Быстро работает, независимо от размера файла, только резервируем размер Вроде неплохо. Будем пользовать? Administrators default • Нужно иметь права SE_MANAGE_VOLUME («Performance Volume Maintenance Tasks») • Если читать такой файл, имея указанные привилегии, он может содержать «старые» байты • Если прав нет, будут возвращены 0. 8 К страницы имеют Авто приращение использует • Для журнала этого не делается т.к. он представляет собой строгую байтовую структуру форматированный заголовок или -T1806 отключает IFE тот же механизмвсе(ижебудет нули для соответствия WriteFileGather() Обнуление common criteria быстрее медленнее) блоками по 8Mbили – PREEMPTIVE (T3004 пишет в errolog) File Control Block (FCB) gocowboys DBTABLE size, maxsize, grow, LSNs, sector size, “I/O stats” все это мы получаем из FCB, когда опрашиваем FCB DMV – file_handle = io_handle handle хранит метаданные о файле fileid = 1 handle = CreateFile(“gocowboys.mdf”, …) Нужно записать страницу 1:100 в БД gocowboys FCB::AsyncWrite handle WriteFile(handle,…) gocowboys.mdf Асинхронный дисковый пул Создание и инициализация файла Асинхронный процесс работы с диском C: \\?\Volume{<GUID>}\ Создание и инициализация файла CREATE DATABASE…. Асинхронный процесс работы с диском sqllang!CStmtCreateDB::CreateLocalDatabaseFragment D: \\?\Volume{<GUID>}\ ASYNC_IO_COMPLETION – часто связан с CXPACKET При параллельной работе асинхронных процессов SQLOS и I/O 17883 Non yielding scheduler Мы не используем sync I/O если только поток не выходит за рамки процесса или если это особые условия (например NTFS Encryption) Мы используем FILE_FLAG_OVERLAPPED при обращении к файлу, что обязывает нас использовать ASYNC Используя async I/O как мы может отдать диспетчера другому процессу? Только один процесс занимает диспетчера в любой момент времени Нам нужно организовать ожидание на I\O, но дать другим работать Как работает система оповещения • Нам нужно выполнить запись в БД • Мы создаем SOS Event • Строим запрос на ввод вывод • Структура в памяти, содержащая информацию о событии, данные и точку входа на функцию завершения IO • Выполняем запрос • Если он не завершается немедленно, помещаем его в очередь диспетчера, выходим и ждем сигнала • Диспетчер переходит к другому процессу, который после завершения своей части проверяет статус запросов в очереди • Процесс может быть любым, пользовательским или системным • Если найдены завершенные вызовы, текущий процесс вызывает функцию завершения, что приводит к пробуждению нашего dm_io_pending_io_requests процесса Как мы читаем “Bootstrap” master прямое чтение Page 10 Чтение страниц и наложение latch Как работает Scatter Read По одной странице или с опережением Показатели работы (счетчики и пр.) Ошибки при чтении и целостность Microsoft IT Conference #MSITConf Random I/O Чтение страниц и Latch BUF Получить EX_LATCH 1:100 bpage bstat Latch Set BUF_IO Нужно взять страницу с диска Снять EX_LATCH, очистить BUF_IO, выполнить “проверки” switch Получить SH latch “Следующий” процесс switch Проверить I/O .mdf Scheduler I/O Queue HasOverlappedIo Completed() OVERLAPPED IO Comp Request ReadFile() 8K Page Comp Routine Указатель на BUF PAGE(IO)LATCH_SH по значению бита BUF_IO GetOverlappedResult() Вызов функции завершения Scatter Reads Buffer Pool Page 1 ReadFileScatter(hdl, ptrarray, …) OS читает 4Kb блоками Ptr to page1 Ptr to page1 4096 Page 4 Page 2 Ptr to page 2 Ptr to page 2 Ptr to page 3 Page 3 Ptr to page 3 Ptr to page 4 Ptr to page 4 Page 1 Page 2 Page 3 Page 4 Стараемся читать побольше (EE SKU) до 64Kb (ramp-up) Даже если нужна только IAM page, root index, PFS page, index seek Читаем, когда нужно Ищем в кеше, если нет, 8-512kbставим запрос на чтение При массивном обращении к страницам: сканирование, ghost cltanup, CHECKDB, index -T652 отключает RA На опережение Одна страница Сколько страниц? Ищем вперед, но не Power of ждем. async I/O Когда страница понадобится, она в кеше Макс outstanding страниц на чтение 5000 (EE) и 128 (Std) Возможно за раз мы не считаем столько Читаем последовательно (хотя бы 64kb - extent). Фрагментация снижает размер чтения Макс I/O на чтение 512kb (в 2014 column store может быть до 8Mb) Метрики и статистика Счетчики @@TOTAL_READ = всего чтений Запрошено чтений • Buffer Manager:Page Reads включает Buffer Manager:Readahead Pages но не наоборот XEvents Завершено чтений • file_read_completed – отслеживание чтений FCB, не только страниц. Показывает размер чтения • physical_page_read – для каждой считанной страницы. Учитывается процедурой завершения, только для страниц sql_statement_completed SET STATISTICS IO – уровень запроса суммарно чтений • physical_reads – чтений в страницах (не включая фоновое наполнения буфера) • read ahead reads – физические опережающие чтения • lob physical reads – чтения в страницах для LOB (подмножество физических чтений) • lob read ahead reads – опережающие чтения для LOB (подмножество read-ahead) dm_os_buffer_descriptors..read_microsec • Скорость чтения страницы (2012+). Используется при indirect checkpoint Метрики системы, файлов и дисков Не для dm_io_virtual_file_stats • Наилучший способ сбора данных IO по файлам • sample_ms – поможет при расчете дельт • io_stall* – суммарные ожидания read, write и total • Храним в микросек, отображаем миллисек Ожидания на I/O • dm_os_io_pending_io_requests • dm_os_schedulers • dm_os_workers/dm_os_tasks Дамп FCB I/O статистики Застрявший диспетчер может увеличить значения hekaton, fs или BPE Отслеживает для любых чтений\записи через управление FCB в коде завершения Накопление с момента старта службы Задача, запустившая I/O Windows метрики • Resource Monitor – дисковая активность по процессам и файлам Одиночная задержка • Avg Disk Sec/Transfer - Задержка может не попасть в • Avg Disk Bytes/Transfer – Размер I/O статистику • Disk Bytes/Sec – пропускная способность • Disk Transfer/Sec – IOPs Следите за split I/O Сброс только рестартом службы Какие ошибки могут быть? Том или файл недоступны при чтении Ошибка хранится в структуре запроса на IO The operating system returned error 1006(The volume for a file Msg 823 has been externally altered so that the opened file is no longer valid.) to SQL Server during a read … • Ошибка ОС при чтении. См ошибки в журнале Windows Msg 824 SQL Server detected a logical consistency-based I/O error: incorrect checksum (expected: 0xdec71ff7; actual: 0xb0499fcf). It occurred during a read of page (1:290)… • Ошибка при проверке целостности, это не ошибка Windows Msg 825 A read of the file ‘C:\SomeDB.mdf’ at offset 0x00000020e24000 succeeded after failing 1 time(s) with error: incorrect checksum (expected: 0x7532c420; actual: 0x320e4240). • Предупреждение что чтение прошло не с первого раза Только в ERRORLOG 824 – проверки целостности Windows вернула не все байты • Проверка по умолчанию, не считается ошибкой Windows • Запросили N байт, получили M байт Не сходится контрольная сумма • PAGE_VERIFY=CHECKSUM • Отличие считанного от записанного ранее? Разрыв страницы Неверный идентификатор страницы Старая страница Ошибка аудита • PAGE_VERIFY=TORN_PAGE_DETECTION • Отличие в битах четности при чтении от записанного? • Проверка по умолчанию если нет иных назначений • Pageid в заголовке соответствует смещению? • Проверка по умолчанию • Считанный LSN старше чем при записи • Аудит назначается флагом 806 (глобально) • Выполняет проверку типа DBCC по всей странице Как мы работаем с контрольной суммой Page 100 m_tornbits=0 m_flagbits=0 Предполагается PAGE_VERIFY= CHECKSUM 123456789 Abcdefghijklm Получаем Latch и Msg 824 После 4х попыток повтора BUF Page 100 berrcode=-4 bstat = BUF_IOERR(0x800) Page 100 m_tornbits= 461750136 - CRC m_flagbits=0x0200 123456789 Abcdefghijklm Mavsrule.mdf Получаем Page 100 с диска Код завершения Пересчитываем m_tornbits = 461750138 Page 100 m_tornbits= 461750136 m_flagbits=0x0200 123456789 Abcdefghijklz Другие ошибки 823, 824 и 829 -> MSDB..suspect_pages • Msg 829 • • В рамках REDO при подъеме БД возникла ошибка на странице Database ID %d, Page %S_PGID is marked RestorePending, which may indicate disk corruption. To recover from this state, perform a restore. Undo deferred tran • Msg 605 • • “Страница связана с другим объектом (Allocation unit), чем в запросе” Attempt to fetch logical page %S_PGID in database %d failed. It belongs to allocation unit %I64d not to %I64d. Resource monitor • Msg 833 – только в ERRORLOG • • Чтение заняло более 15 сек SQL Server has encountered 1 occurrence(s) of I/O requests taking longer than 15 seconds to complete… XE long_io_detected • “Фоновые попытки” • • проверяет каждые 5 сек Windows Error 1450 или 1453 Ждем 10ms и пытаемся снова “пока не пройдет” (тип ожидания - IO_RETRY) Как мы пишем в журнал Microsoft IT Conference #MSITConf WAL протокол Write-Ahead Logging: Журнал пишем первым ВСЕГДА Database Page Page 100 Журнал (кеш в памяти) LOP_BEGIN_XACT Данные в записи LOP_INSERT_ROWS Данные в записи LOP_ROLLBACK_XACT LOP_COMMIT_XACT Важен порядок записи, организованный дисковой подсистемой Cowboysno1.mdf Cowboysno1_log.ldf Log Block(s) Page 100 Запись в журнал это только COMMIT? Кеш журнала – глобальный ресурс • Ваша транзакция может быть записана до фиксации Любая запись на странице Если буфер журнала полон должна иметь заранее – мы сбрасываем его весь durability was announced late in сброшенный буфер журнала (WAL протокол) Delayed the SQL Server 2014 development cycle, but offers something НЕТ that many SQL Server professionals have wanted for years—the ability to disable transaction Есть системные транзакции Мы можем немного logging. (выделение страниц) они всегда фиксируются, ваши записи сбрасываются с ними подождать для «группировки» COMMIT, чтобы увеличить размер записи (EE SKU) Group Commit Time/Sec Delayed все равно соблюдает WAL Отложенный, это не то что можно подумать LogWriter имеет timeout для I/O даже если нет сигнала Метрики I/O журнала Задержки I/O журнала WRITELOG wait time = I/O latency + Group Commit delay (обычно мал) Perfmon User Log Writer Один групповой Log Flush Wait Time – WRITELOG wait time сброс может иметь > 1 WRITELOG Log Flush Waits/Sec – How many WRITELOG waits Log Bytes Flushed/Sec – Сколько байт записал LogWriter Log Flushes/Sec – Сколько раз LogWriter выполнил запись Log Flush Write Time (ms) – Длительность записи XEvent databases_log_flush_wait – WRITELOG ожидание (факт) log_flush_start/log_flush_complete – Число записанных блоков журнала log_flush_retry – Фоновый повтор, при ошибке типа 1450 sql_transaction_commit_single_phase – отложенная транзакция Пределы I/O журнала Мы ограничиваем LogWriter I/O Следите за I/O системы или журнала 8x увеличение 2008+ • 112 max outstanding async log I/O на запись • 3840Kb outstanding async log I/O байт • Симптомы = Длительные WRITELOG И “низкие” Log Flushes/Sec Resource Governor I/O сюда не относится Что если диск под журналом реально быстрый? • Многопроцессорные машины могут увидеть LOGCACHE_ACCESS spinlock Проверки журнала и ошибки Db offline Ошибки OS на запись видны как проблемы LogWriter Проверяем на разрыв записи XE log_flush_retry Мы пытаемся повторить операцию при ошибках OS (ожидание IO_RETRY) Msg 833 “I/O stalls” в силе • Длительные WRITELOG ожидания • LogWriter ждет на LOGMGR_QUEUE. suspect db -T815 Latch enforcement Log I/O проверяет целостность (Msg 824) spid4s Error: 17053, Severity: 16, State: 1. spid4s SQLServerLogMgr::LogWriter: Operating system error 1006(The volume for a file has been externally altered so that the opened file is no longer valid.) encountered. spid4s Write error during log flush. spid54 Error: 9001, Severity: 21, State: 4. spid54 The log for database 'usbdb_2014' is not available. Check the event log for related error messages. Resolve any errors and restart the database. • Проверка блоков журнала в памяти • Если найдена ошибка – exception (stack dump) Checksum для блоков Почему границы секторов важны Последний записанный блок 0 512 1024 4096 Последний записанный блок Выравнива Следующий тель блок журнала 0 512 1024 4096 5120 512 byte sector drive 4Kb sector drive Restore The tail of the log for database <db> is being rewritten to match the new sector size of 4096 bytes. 3584 bytes at offset <offset> in file <file> will be written Неровно There have been 25958400 misaligned log IOs which required falling back to synchronous IO. The current IO is on file <file> DBM, Log Shipping, AG random I/O Запись страниц Microsoft IT Conference #MSITConf WriteMultiple Больше-лучше • Ищем последовательность грязных страниц (до 32) рядом с нашей • Размер I/O будет от 8Kb до 256kb BPool::WriteMultiple Как писать? Что еще? “Код завершения” • WriteFileGather() похож на scatter read • Разбросаны в памяти, последовательны на диске • Async не ждет • Проверяем записанные байты GetOverlappedResult() • Latch на странице (UP/EX) • Пометки BUF_IO, checksum, torn page bits и TDE • Сброс буфера журнала (WAL) • Запись страницы и ее LSN • Очищает бит BUF_IO • Записывает ошибки в BUF • Снимает latch Page writes/sec запросы на запись XE physical_page_write и file_write_completed CHECKPOINT Определяется временем восстановления T-SQL CHECKPOINT Ищем “грязные” буферы у БД для сброса Повторяем, пока не найдем всех (кроме тех, что изменились после нашего старта) • Поддерживает duration CHECKPOINT worker по сигналу Вызываем WriteMultiple При группировании можем захватить и другие буферы • CHECKPOINT_QUEUE wait • Сигнал Log Flush Внутренний checkpoint (непосредственно с командой) “BPool::FlushCache” Адаптивный механизм • • • • • ALTER DATABASE Recovery SHRINK Backup/Restore Shutdown Indirect Checkpoint DIRTY_PAGE_POLL 2012+ Стоп, если цель достигнута Background writer pages/sec Список может превзойти диапазон WriteMultiple (32 страницы) Опрашиваем очередь (каждые 100ms) RECOVERY WRITER Проходим по списку с вызовом WriteMultiple() Строим список грязных страниц БД на базе redo target Принимаем сигнал от Log Flush BUF хранит длительность чтения Все расчеты идут от заказанного Recovery time Из реальной жизни Операции с диском гораздо плавнее • Счетчики Checkpoint pages/sec и Background writer pages/sec Eager Writes Eager? SELECT..INTO INSERT…SELECT Bulk copy Bulk с минимальным журналированием? Зачем ждать Checkpoint? Если есть незавершенные IO (BUF), мы ожидаем Не забивать checkpoint Во время выделения и подготовки Строится кольцевой массив буферов Берем буфер в массиве и вызываем WriteMultiple Возможно другие страницы в массиве также пойдут на диск PAGEIOLATCH_UP Диагностика и настройка TF 3917 и 3605 для трассировки Может помочь на медленных дисках TF 3940 для ограничения в 1024 outstanding eager writes Операции управления Microsoft IT Conference #MSITConf ALTER DATABASE и I/O Добавление файла Аналогично тому как работаетCREATE DATABASE Модификация файла FGCB_ADD_REMOVE или LOG_MANAGER latch в процессе приращения Увеличение – явное “autogrow”. Инициализация новой части файла. Требует LATCH_EX на FCB (SetFileValidData) вызывается FlushFileBuffers() для синхронизации метаданных с файловой системой Некоторые опции ALTER DATABASE включают checkpoint (добавление\удаление файла) Индексы Множественные read ahead для чтения страниц FULL Recovery предполагает полное журналирование страницы • В зависимости от размера может срабатывать checkpoint Минимальное журналирование (BULK\SIMPLE) предполагает eager write Сортировка может создавать I/O (Disk spill или SORT IN TEMPDB) Основы BACKUP/RESTORE BACKUP DATABASE Макс 1Mb I/O (16 extents) Асинхронный дисковый пул для чтения экстентов прямо из файла с использованием ожидания FCB BACKUP пока ждем завершения модификации страниц TF 3210 для наблюдения за ожиданиями Самостоятельные async потоки пишут в копию (not FCB) с учетом MAXTRANSFERSIZE STRIPED BACKUP – множественные потоки (но не для журнала) WITH CHECKSUM Верификация CRC страниц и запись CRC для всей копии По WITH SNAPSHOT умолчанию 1Mb I/O замораживается (ожидание DISKIO_SUSPEND) RESTORE DATABASE Работает вся логика CREATE DATABASE Поток читает из копии и пишет в файлы БД (по одному потоку на логический том) Попробуйте MAXTRANSFERSIZE DBCC CHECKDB Читаем из файлов БД используя Read Ahead (обычно 64kb) SQL 2012 включает оптимизацию процесса (в первую очередь для режима Physical Only, SAP БД 14 Тб за несколько часов) Worktable в tempdb для хранения “фактов” Online CHECKDB – внутренний database snapshot с именованными потоками cowboysrule.mdf_MSSQL_DBCC<n> Не в 2014 для поддержки ReFS Buffer Pool Extension Свойства файла 2014 Может замедлить начальную запись • Метка FILE_FLAG_DELETE_ON_CLOSE • Мы не проверяем SSD (учтите!!) • Устанавливаем размер, но не инициализируем (файл инициализирует OS) Чтение - 8Kb для отдельных страниц Аналог Windows Page File для SQL Buffer Pool (только чистые буферы) Память SQL Server Buf 1 Buf 2 Buf 3 Buf 4 Ожидание EC Запись • “WriteMultiple” если находим подходящий буфер (остальные 32 по номерам BUF) • Предел - 32 outstanding I/O, (сброс буфера) • Поддерживает checksum, torn, … для страниц Perfmon counters и XEvent Buf 5 Page 5 BPE.SS Page 10 Page 2 Page 300 Page 12 Tempdb Пропускаем создание и инициализацию, просто копируем model Даже для пользовательских таблиц I/O требования для tempdb – RAM диск допустим Delayed durability по умолчанию (не жалко) Minimal Logging – мы не делаем REDO “Normal” tempdb I/O Ваши временные таблицы в BPool подобно другим страницам Checkpoint (автоматический) обходит страницы TempDb, ручной - нет Resource Governor Ограничение I/O для чтений и записи от user tasks по “числу” I/O • Поддерживается MIN\MAX_IOPS_PER_VOLUME Как мы этого добиваемся? XE • Вместо немедленного исполнения I/O ставится в очередь (простая активизация RG этого не делает) file_read_equeued • При выходе, процесс смотрит в очередь, оценивает настройки RG и принимает решение исполнять-не file_read_throttled исполнять (тогда запрос перемещается в обычную очередь) file_write_enqueued file_write_throttled Что значит “user tasks” • Фоновые задачи checkpoint worker, lazywriter, logwriter, async disk pool не регулируются (Internal Pool) • Регулируется любая задача в контексте сессии пользователя (reads, eager writes, ручной CHECKPOINT, …) Метрики • • • • Счетчики в Resource Pool Stats Новые столбцы в dm_io_virtual_file_stats PAGEIOLATCH включает фактическое время I/O и время в очереди Новые данные в dm_resource_governor_resource_pools dm_io_pending_io_requests не учитывает регулирование Hybrid и Cloud I/O SQL Data Files в Azure Storage (2014) Путь к файлу - URL. Дополнительная проверка прав Azure Storage Services REST API (Page Blobs) через Win HTTP API Макс размер файла - 1TB (лимит для Page Blob) Размеры операций ввода\вывода те же для БД и журнала. “Gather Write” разбивается на группу сообщений SQL Server:HTTP Storage счетчики и XEvent (sqlserver.xfcb_*) Ожидания, как обычно, только IO_COMPLETION встречаются чаще Нет поддержки Hekaton т.к. нет поддержки Filestream TF 1816 позволяет получить больше информации об ошибках Backup to Azure Storage (2012 и 2014. Для пред. версий см “Microsoft® SQL Server® Backup to Microsoft Azure®Tool”) Backup to URL – средствами VDI приложений, выполняющих вызовы REST API Managed backups to Azure Storage – автоматически назначаемые копии в облако Performance Best Practices для SQL Server на Azure Virtual Machine: есть ограничения на IOPs Максимальное число 8 KB IOPs на диск • Basic Tier – 300 • Standard Tier - 500 In-Memory OLTP и I/O FILESTREAM только для контейнеров (папок) Сохранение данных не использует FCB I/O XE trace_checkpoint_write_io • Нет страниц в buffer pool • Данные хранятся в парных файлах (checkpoint). Размер файлов может быть больше размера в памяти • Поддерживаются “Non”-durable таблицы, они не создают файлового I/O. Хранится только схема От журнала никуда • Задержка на журнале негативно влияет на производительность • Можно использовать delayed durability • См. записи LOP_HK* в журнале Факты о файлах checkpoint -T9837 для доп. трассировки (массивный вывод) XTP_OFFLINE_CKPT • Checkpoint от “offline checkpoint worker” читает журнал для сохранения изменений в файлах • Эти файлы считываются (и сливаются вместе) на старте для заполнения таблиц в памяти, параллельные потоки для ускорения процесса • Асинхронное чтение и запись крупными (256K) блоками • Нет поддержки DBCC CHECKDB, но мы используем контрольные суммы в файлах Вопросы Дмитрий Артемов Консультант dimaa@Microsoft.com ©2015 Microsoft Corporation. All rights reserved. Microsoft, Windows, Office, Azure, System Center, Dynamics and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries. The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.