Автор: Пользователь скрыл имя, 17 Декабря 2010 в 16:05, лекция
Управление распределенными базами данных. Проблемы управления распределенными данными. Уровни доступа к распределенным данным. Удаленные запросы. Удаленные транзакции. Распределенные транзакции. Распределенные запросы.
Вертикальное разделение таблиц
Другой способ распределения таблицы по сети состоит в вертикальном разделении таблицы и размещении ее столбцов в разных системах. На рис. 20.7 приведен простой пример вертикального разделения таблицы. Таблица salesreps была расширена новыми столбцами с личной информацией о служащих (номер телефона, семейное положение и т.д.) и теперь используется как отделом обработки заказов, так и отделом кадров, каждый из которых имеет свою собственную вычислительную систему и СУБД. Работа каждого отдела сфокусирована по большей части на одном или двух столбцах таблицы, однако имеется немало запросов и отчетов, в которых используются столбцы, относящиеся как к отделу кадров, так и к отделу обработки заказов.
Для хранения данных о служащих таблица salesreps разделяется вертикально на две части. Столбцы таблицы, содержащие личные данные (name, age, hire_date, phone, married), хранятся в вычислительной системе отдела кадров, имеющей свою СУБД. Другие столбцы (empl_num, quota, sales, rep_office) хранятся в вычислительной системе отдела обработки заказов, также имеющей свою СУБД. Однако таблица salesreps трактуется как одна большая таблица, к которой можно обращаться с запросами на чтение и изменение как к единому целому.
Обратите внимание: два приведенных ниже запроса к таблице salesreps выглядят очень похоже, однако для выполнения одного из них требуется локальный доступ, а для выполнения другого — удаленный:
SELECT
NAME, AGE
FROM SALESREPS
WHERE AGE > 30 •
SELECT EMPLJSIUM, SALES, QUOTA
FROM SALESREPS
WHERE REP_OFFICE = 12
Следующий запрос требует, чтобы СУБД собирала части каждой строки из двух разных систем:
SELECT NAME, SALES, QUOTA
FROM SALESREPS WHERE REP_OFFICE = 12
При вертикальном разделении СУБД не должна анализировать содержимое строк для определения их местоположения. Однако перед ней стоит другая, не менее сложная задача сохранения отношения "один-к-одному" между частями строк, расположенными в разных системах. Помимо этого, вертикально разделенные таблицы могут потребовать значительных изменений в программной логике СУБД, осуществляющей блокировку таблиц. Если программе требуется заблокировать строку, то теперь СУБД должна блокировать части строки в нескольких системах. Должна ли СУБД блокировать все части строки или только те ее части, которые действительно обновляются? В зависимости от ответа на этот вопрос СУБД, возможно, придется реализовать блокировку на уровне элементов строк.
Зеркальные таблицы
В идеально спроектированной распределенной базе данных должно соблюдаться правило 80/20: 80 процентов (или более) обращений к базе данных должно удовлетворяться локально и только 20 процентов (или менее) — посредством удаленного доступа. Однако если одна или две таблицы в распределенной базе данных интенсивно используются многими пользователями, находящимися в разных системах, то может оказаться очень трудно достичь баланса 80/20. Где бы ни находились эти таблицы, обращения к ним пользователей из других систем вызовут повышение сетевого трафика и временные задержки.
Одним из решений данной проблемы может быть использование зеркальной таблицы. В этом случае, как показано на рис. 20.8, дубликаты таблицы хранятся в нескольких системах. Когда пользователь обращается к таблице с запросом на чтение, может быть использована локальная копия таблицы; это уменьшает сетевой трафик и повышает производительность базы данных. Однако обновление всех копий зеркальной таблицы должно происходить одновременно, чтобы пользователи в разных системах не могли видеть несогласованные версии таблицы. По этой причине зеркальные таблицы имеет смысл использовать только в тех случаях, когда таблица часто читается, но редко обновляется. Хорошим кандидатом на зеркальную таблицу в учебной базе данных могла бы быть таблица customers, а вот таблица orders была бы плохим кандидатом.
Реплицированные таблицы
Затраты машинного времени, связанные с поддержанием идеальной синхронизации зеркальных таблиц, могут быть значительными, однако во многих приложениях нет абсолютной необходимости в том, чтобы копии зеркальной таблицы были точно синхронизированы друг с другом. Например, рассмотрим процедуру обработки заказов в учебной базе данных и предположим, что посредством распределенной базы данных эта процедура выполняется на пяти вычислительных системах, расположенных в разных географических точках. При поступлении заказа производится обращение к таблице products, чтобы убедиться в том, что для его выполнения в наличии имеется достаточное количество товара.
Предположим также, что компания проводит такую политику: служащий, принимающий заказ, должен безусловно гарантировать клиенту, что товар будет отгружен в течение 24 часов с момента приема заказа. В этом случае таблица products должна содержать данные, действительные буквально на текущую минуту и отражающие размещение заказов, принятых всего лишь несколько секунд назад. Существует только два возможных способа, позволяющие обеспечить это условие. Первый способ — совместное использование одной центральной копии таблицы products всеми пользователями в пяти пунктах приема заказов. Альтернативный способ — наличие зеркальной копии таблицы products в каждом из пяти пунктов. Второе решение вряд ли практично, так как частые обновления таблицы products, выполняемые для поддержания идеальной синхронизации при каждом приеме заказа, вызовут резкое возрастание сетевого трафика.
А теперь предположим, что компания решила сделать свою политику менее строгой, полагая, что она по-прежнему сможет обеспечить адекватный уровень обслуживания клиентов. Например, если заказ не может быть выполнен немедленно, компания обещает уведомить клиента об этом в течение 24 часов и дает ему возможность отменить заказ. В этом случае реплицированная таблица products будет отличным решением. Ночью все изменения, сделанные в таблице products, могут вноситься в реплицированные копии во всех пяти пунктах приема заказов. При приеме заказов в течение дня наличие товара проверяется по локальной копии таблицы products и только эта локальная копия обновляется. Это предотвращает прием заказов, для которых в начале рабочего дня отсутствовало достаточное количество товара, но не предотвращает прием в разных пунктах заказов, в которых суммарное количество заказанного товара превысит наличные запасы. Следующей ночью, когда услуги связи дешевле, чем днем, заказы из каждого пункта приема заказов передаются в центральный пункт, где происходит их обработка и обновление центральной копии таблицы products. Заказы, которые не могут быть удовлетворены из наличных запасов, отмечаются, и создается соответствующий отчет. Когда обработка завершается, обновленная таблица products вместе с "отчетом о неудовлетворенных заказах" передается назад во все пять пунктов приема заказов для использования в течение следующего рабочего дня.
Как видно из этого примера, реплицированные таблицы представляют собой компромисс по отношению к идеальной распределенной базе данных. Этот компромисс почти всегда влечет за собой снижение качества обработки данных, как и в приведенном примере. Однако очень часто он является лучшим способом решения реальных деловых проблем, учитывающим как сложность и дороговизну распределенных баз данных, так и высокую стоимость передачи данных по линиям связи в дневное время.
В
течение нескольких последних лет
новые возможности
Метод двухфазного выполнения
Если распределенная СУБД поддерживает распределенные транзакции, то она должна соблюдать правило "все или ничего", обязательное для SQL-транзакций. Пользователь распределенной СУБД ожидает, что завершенная транзакция будет завершена во всех системах, где располагаются данные, и отмененная транзакция также будет отменена во всех системах. Кроме того, неисправности в сети или в одной из систем должны приводить к тому, что СУБД прекратит выполнение транзакции и отменит ее, а не оставит транзакцию в частично завершенном состоянии.
Все коммерческие СУБД, которые поддерживают или планируют поддерживать распределенные транзакции, используют для этого специальный метод, называемый двухфазным выполнением. Чтобы применять распределенные транзакции, вам не требуется понимать работу этого метода. Цель его применения в том и состоит, чтобы поддерживать распределенные транзакции без участия пользователя. Однако знание механизма двухфазного выполнения помогает более эффективно планировать работу с базой данных.
Чтобы понять, почему необходим специальный механизм двухфазного выполнения, рассмотрим базу данных, представленную на рис. 20.9. Пользователь, находящийся в системе А, обновил одну таблицу в системе В и одну таблицу в системе С и хотел бы теперь завершить транзакцию. Предположим, что СУБД в системе А пытается завершить транзакцию, просто посылая сообщение commit в систему В и систему С, а затем ожидая подтверждающих ответов. Такой метод работает до тех пор, пока обе системы В и С успешно выполняют свои части транзакции. Но что произойдет, если, например, неисправность диска или тупиковая ситуация не позволят системе С выполнить запрашиваемые действия? Система В завершит свою часть транзакции и пошлет в систему А подтверждение, система С вследствие ошибки отменит свою часть транзакции и пошлет в систему А сообщение об ошибке, а пользователь останется с частично завершенной и частично отмененной транзакцией. Обратите внимание на то, что теперь система А не может "передумать" и дать системе В команду отменить транзакцию. Транзакция в системе В завершилась, и другие пользователи, опираясь на ее результаты, возможно, уже модифицировали какие-то данные.
Метод двухфазного выполнения позволяет избежать проблем, возникающих при использовании обычного механизма, схематически показанного на рис. 20.9. На рис. 20.10 изображены этапы, выполняемые при использовании метода двухфазного выполнения:
Данный метод защищает распределенную транзакцию от любой одиночной ошибки в системе В, системе С или сети. Два приведенных ниже примера иллюстрируют, как с помощью этого метода осуществляется восстановление после ошибки: