Блокировки Oracle

Блокировки Oracle DatabaseБаза данных Oracle использует блокировки (lock) для обеспечения того, что изменение указанного фрагмента данных в каждый конкретный момент времени может совершать максимум одна транзакция. По существу блокировки — это механизмы, которые разрешают параллельную обработку; без применения какой-либо модели блокировки для предотвращения, например, одновременных обновлений одной и той же строки, многопользовательский доступ к базе данных был бы невозможным.



Ниже описаны некоторые важные свойства блокировки Oracle.

  • Oracle реализует блокировки, устанавливая бит в элементе данных, подлежащем блокировке. Информация о блокировке хранится в блоке данных, где находится блокируемая строка.
  • Блокировки удерживаются на протяжении всей транзакции и освобождаются, когда выдается команда COMMIT или ROLLBACK.
  • Oracle не использует эскалацию блокировок, поскольку информация блокировки хранится в индивидуальных блоках данных. Эскалация блокировок — например, с уровня строки на уровень таблицы — сокращает степень параллелизма.
  • Oracle использует преобразование блокировки, что подразумевает изменения ограниченности блокировки при сохранении неизменной ее гранулированности. Например, разделяемая блокировка строки таблицы преобразуется в более ограниченную эксклюзивную блокировку таблицы, когда оператор SELECT FOR UPDATE начинает обновлять ранее заблокированные строки таблицы. Гранулированность блокировок и типы блокировок Oracle подробно объясняются ниже.

В следующих нескольких разделах данной статьи вы узнаете больше о методах и типах блокировки, используемой механизмом управления параллелизмом Oracle.

 

Методы блокировок Oracle

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

Гранулированностью (granularity) в контексте блокировок называется размер единицы данных, заблокированный механизмом блокировки. Oracle использует гранулированность уровня строки для блокировки объектов, которая представляет собой наиболее мелкий уровень гранулированности (наиболее крупный уровень — блокировка таблицы). Некоторые базы данных, включая Microsoft SQL Server, предлагают только блокировку уровня страницы, а не строки. Страница — это нечто похожее на блок данных Oracle, и она может хранить группу строк, поэтому блокировка уровня страницы означает, что на время обновления несколько строк будут заблокированы в дополнение к тем, что подлежат обновлению; если другим пользователям понадобятся заблокированные строки, которые не участвуют в обновлении, им придется ждать, пока блокировка страницы не будет снята. Например, если размер страницы составляет 8 Кбайт, а средняя длина строки — 100 байт, то в страницу уместится 80 строк. Если одна из них будет обновляться, то блокировка уровня страницы также распространится на остальные 79 строк. Блокировка на уровне выше строки ограничивает параллельный доступ к данным.


На заметку!


Все блокировки, полученные операторами в транзакции, удерживаются Oracle до тех пор, пока транзакция не завершится. Когда транзакция явно или неявно выдает команду COMMIT или ROLLBACK, Oracle освобождает все блокировки, которые удерживали операторы, входящие в транзакцию. Если Oracle выполняет откат к точке сохранения, то освобождаются все блокировки, установленные после этой точки.

 

Типы блокировок Oracle

Блокировки, как было показано, предотвращают деструктивное взаимодействие между транзакциями, обеспечивая последовательный доступ к ресурсам. Этими ресурсами могут быть как объекты базы данных, наподобие таблиц, так и другие разделяемые структуры базы данных, находящиеся в памяти. Блокировки Oracle могут быть приблизительно разделены на следующие типы, в соответствии с блокируемыми объектами:блокировки DML, блокировки DDL, защелки, внутренние блокировки и распределенные блокировки. Все эти типы блокировок описаны ниже.

 

Блокировки DML

Блокировки DML — это блокировки, устанавливаемые Oracle для защиты данных в таблицах и индексах. Всякий раз, когда оператор DML собирается модифицировать данные в таблице, Oracle автоматически устанавливает блокировку уровня строки на модифицируемые строки таблицы. (Это исключает, к примеру, возможность того,что группа продавцов сможет продать “последний” билет более чем одному клиенту.) Блокировки DML уровня строки гарантируют, что читатели данных не станут ожидать записи данных и наоборот. Писатели должны будут подождать только в том случае, если они хотят обновить некоторые строки, которые в данный момент модифицируются другими транзакциями.

Любой режим блокировки Oracle допускает запросы к таблице. Запрос никогда не заблокирует обновление, удаление или вставку, и наоборот. Монопольная блокировка (exclusive lock) разрешает только запросы к таблице, но предотвращает любую другую активность пользователей, подобную обновлению или удалению данных. Монопольная блокировка строки, с другой стороны, допускает параллельный доступ к таблице для обновления, удаления и вставки данных, но предотвращает блокировку всей таблицы любым пользователем в монопольном режиме. Существуют и другие режимы блокировки, но для наших целей достаточно будет сосредоточиться на двух базовых режимах блокировки Oracle.

Любой запрос, выданный транзакцией, не будет пересекаться ни с какой другой транзакцией, поскольку все, что они делают — это чтение данных, и никакой модификации. Запросы включают транзакции, использующие оператор SELECT, а также такие транзакции, как INSERT, UPDATE и DELETE, если случается так, что последние используют явный оператор SELECT. Запросы никогда не нуждаются в блокировках, и им никогда не приходится ждать снятия какой-то чужой блокировки. Поэтому оператор SELECT,который читает данные из таблицы, никогда не ожидает захвата блокировки.

Любые операторы INSERT, DELETE, UPDATE или SELECT FOR UPDATE автоматически устанавливают монопольную блокировку уровня строки на строки, затронутые транзакцией. Такая блокировка уровня строки означает, что другие транзакции не могут модифицировать затронутые строки до тех пор, пока исходная транзакция не зафиксирует или откатит изменения, тем самым освобождая монопольные блокировки.Синхронные блокировки DDL таблиц удерживаются для операций, которые включают DML-операторы INSERT, UPDATE, DELETE и SELECT FOR UPDATE. Операции DML нуждаются в DDL-блокировках таблиц для гарантии того, что какая-то другая транзакция не изменит определение таблицы при модификации данных. Это значит, что таблица не может быть изменена или уничтожена, пока автоматическая транзакция удерживает блокировку таблицы.

Блокировки таблицы могут варьироваться от сильно ограничивающих до ограничивающих в минимальной степени. Oracle устанавливает монопольную блокировку строки таблицы; это указывает на то, что транзакция, удерживающая блокировку, выполнила обновление одной или более строк таблицы. Другим транзакциям разрешено параллельно выбирать, вставлять, обновлять, удалять или блокировать строки в той же таблице. Однако другие транзакции не могут установить монопольную блокировку всей таблицы для выполнения собственных операций чтения и записи. Все операторы INSERT, UPDATE и DELETE устанавливают неявные монопольные блокировки строк.

В таблице ниже подведен итог DML-блокировок уровня строки и таблицы, которые устанавливаются наиболее часто используемыми операциями базы данных.

Операция Блокировка уровня строки Блокировка уровня таблицы
SELECT...FROM таблица Нет Нет
INSERT INTO таблица Монопольная Монопольная для строки
UPDATE таблица Монопольная Монопольная для строки
INSERT INTO таблица Монопольная Монопольная для строки
DELETE FROM таблица Монопольная Монопольная для строки

Подведем краткий итог наиболее частого использования транзакциями Oracle средств блокировки Oracle.

  • Транзакции, содержащие операторы DML, устанавливают монопольную блокировку строки на строках, модифицируемых им в этой транзакции. Пока эта транзакция не будет зафиксирована или откатана, другие транзакции не смогут обновить или удалить эти строки.
  • Запрос в транзакции может видеть только зафиксированные изменения, проведенные ранее запущенными операторами той же транзакции, но не могут видеть данные, зафиксированные другими транзакциями после ее запуска.
  • В дополнение к монопольным блокировкам строк, транзакция, содержащая оператор DML, устанавливает, как минимум, монопольную блокировку строк таблицы, которая хранит эти строки. Если она уже удерживает более ограничительную блокировку DML уровня таблицы, эта блокировка остается в силе.

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

 

Блокировки DDL

Как уже было показано, Oracle автоматически устанавливает блокировки DML на таблицы, которые находятся в процессе модификации их строк со стороны транзакции. В дополнение такая транзакция одновременно удерживает DDL-блокировку уровня таблицы, что предотвращает изменение или удаление этой таблицы другими DML-транзакциями, которые еще не завершены.

Блокировки DDL можно также поместить на таблицы при выполнении простых операций DDL вне какой-либо сопровождающей транзакции DML.

Установка ожидания блокировок DML для блокировок DDL

По умолчанию запрос блокировки DDL не ожидает блокировки DML. То есть запрос блокировки DDL автоматически получает отказ, если не может немедленно установить блокировку DML на таблице. Однако с помощью параметра инициализации ddl_lock_timeout можно задать период времени, в течение которого оператор DDL будет ожидать блокировки DML.

Поскольку значение параметра ddl_lock_timeout по умолчанию равно 0, операторы DDL вообще не ожидают блокировки DML. Вы можете установить значение этого параметра вплоть до максимальной величины в 1000000 секунд, что соответствует примерно 11 с половиной дням. Ниже приведен пример, демонстрирующий установку этого параметра в пределах сеанса: 

ALTER SESSION SET ddl_lock_timeout = 30;
Session altered.
SQL>

Блокировки в базе данных Oracle Database 

Явное блокирование таблицы

Каждый раз, когда вы добавляете столбец к таблице, база данных должна установить монопольную DML-блокировку на этой таблице. Можно указать, что команда DDL должна ожидать определенный период времени перед отказом, когда не удается установить блокировку DML. Оператор LOCK TABLE позволяет специфицировать максимальный период времени, который оператор DDL может ожидать возможности захвата DML-блокировки таблицы. Применяйте это средство при добавлении столбца, часто обновляемого пользователями.

Ниже приведен синтаксис оператора LOCK TABLE

LOCK TABLE ... IN режим_блокировки MODE [NOWAIT | WAIT целое]

В операторе LOCK TABLE значения NOWAIT и WAIT параметр MODE означают следующее.

  • Если вы хотите, чтобы база данных вернула управления немедленно, обнаружив,что требуемая таблица уже заблокирована другим пользователем, укажите опцию NOWAIT.
  • С помощью параметра WAIT можно задать количество секунд, в течение которых оператор LOCK TABLE может ожидать возможности установки DML-блокировки. Значение этого параметра является целочисленным и на него не накладывается никаких ограничений.
  • Если не указано ни WAIT, ни NOWAIT, база данных будет ожидать до тех пор, пока заблокированная таблица не станет доступной, и затем заблокирует ее перед возвратом управления.

 

Защелки, внутренние и распределенные блокировки

Защелки (latch) — это внутренние механизмы, которые защищают разделяемые структуры данных в SGA. Например, вхождения словаря данных доступны в буфере для многих целей, и защелки контролируют процессы доступа к этим структурам памяти. Структуры данных, которые перечисляют блоки, находящиеся в данный момент в памяти, также часто читаются во время работы экземпляра Oracle, и серверные и фоновые процессы, которые нуждаются в изменении или чтении критичных структур данных вроде этих, должны устанавливать на них очень кратковременные блокировки (именуемые защелками). Реализация защелок, включая спецификацию длительности ожидания их, обычно специфична для операционной системы.

Блокировки словаря данных используются Oracle при каждой модификации объектов словаря. Распределенные защелки представляют собой специализированные механизмы блокировки, используемые в распределенной системе базы данных или среде Oracle Real Application Clusters (RAC). Внутренние блокировки используются Oracle для защиты доступа к таким структурам, как файлы данных, табличные пространства и сегменты отката.

 

Явное блокирование в Oracle

Oracle автоматически применяет необходимые блокировки к таблицам и другим объектам на основе транзакций, закодированных в приложениях. Механизм блокирования Oracle работает автоматически, гарантируя согласованность чтения на уровне оператора и параллелизм. В большинстве случаев стандартного скрытого механизма блокировок Oracle вполне достаточно, но иногда бывают ситуации, когда разработчику приложения лучше вручную блокировать таблицы. Иногда, когда транзакции нужно видеть согласованные данные между несколькими соединенными таблицами, разработчик приложения может прибегнуть к явному блокированию. Вдобавок, когда не нужно,чтобы значения данных изменялись на протяжении длительной транзакции, иногда разработчику приложения бывает необходимо установить явные блокировки.

В Oracle предусмотрены средства явного блокирования, переопределяющие блокирование неявное, устанавливаемое Oracle от имени транзакции. Переопределить стандартный (неявный) механизм блокирования Oracle можно на уровне транзакции или на уровне сеанса. Если необходимо переопределить механизмы блокирования Oracle по умолчанию, это можно сделать с помощью оператора SET TRANSACTION LEVEL SERIALIZABLE на уровне сеанса. Тот же оператор также перепишет режимы блокирования по умолчанию на уровне транзакции. Вдобавок можно вручную блокировать таблицу, явно выдавая команду SELECT FOR UPDATE.

 

Блокирующие замки

Блокирующий замок (blocking lock) возникает, когда блокировка, установленная на объект пользователем, предотвращает или блокирует другим пользователям доступ к тому же объекту или объектам. Таблица DBA_BLOCKERS удобна для получения этой информации — она сообщает, какие сеансы в данный момент удерживают блокировки на объектах, доступа к которым ждет какой-то другой объект. Информацию из таблицы DBA_BLOCKERS можно комбинировать с информацией из таблицы V$SESSION, что позволит узнать, кому принадлежит блокирующий сеанс. Ниже показан соответствующий оператор SQL: 

SELECT a.username, a.program, a.sid, a.serial#
2 FROM v$session a, dba_blockers b
3 WHERE a.sid = b.holding_session;
SQL>

Далее приведен простой пример блокирующего сеанса: пользователь Nick Alapati издает следующий оператор DML, но не фиксирует его:

DELETE FROM emp
WHERE name='samalapati';
1 row deleted.
SQL>

Пользователь Nina Alapati, между тем, выдает аналогичный оператор, который при выполнении зависает:

DELETE FROM emp
WHERE name='samalapati';

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

С помощью представления V$SESSION можно узнать, какие сеансы блокируют другие сеансы. Вот простой запрос, использующий это представление, который показывает блокирующий замок, вызванный предыдущими двумя операторами SQL: 

SELECT username, blocking_session
blocking_session_status
FROM V$SESSION WHERE blocking_session_status='VALID';

В случае обнаружения блокирующего сеанса, который мешает другому сеансу выполнить свою работу, можно прервать его, используя команду ALTER SYSTEM KILL SESSION. Если процесс сеанса все равно продолжается, перейдите на уровень операционной системы и уничтожьте тот процесс или поток, который обслуживает блокирующий сеанс Oracle.

 

Взаимные блокировки (взаимоблокировки)

Взаимные блокировки (deadlock) возникают в любой СУБД, когда два сеанса блокируют друг друга, ожидая от противоположного сеанса освобождения некоторого ресурса. Это ситуация из произведения “Уловка 22” (ссылка на роман Джозефа Хеллера под названием “Catch-22”), потому что данная патовая ситуация не может быть разрешена ни одним из сеансов в одностороннем порядке. В таких условиях Oracle прерывает один из сеансов и откатывает его операцию. Oracle быстро распознает возникновение взаимоблокировки между двумя сеансами и прерывает тот сеанс, который последним запросил блокировку. Это освобождает блокировку, снятия которой ждет другой сеанс. Фактически в случае возникновения взаимоблокировки ничего не нужно делать, хотя в каталоге дампа появится сообщения о наличии взаимоблокировки в базе данных.

Когда Oracle сталкивается с взаимоблокировкой между транзакциями, он записывает в файл трассировки идентификаторы участвующих сеансов, операторы SQL, выданные в транзакциях, а также имя конкретного объекта и строки, на которых удерживаются блокировки в каждом сеансе, принимающем участие в блокировке. Далее Oracle информирует, что взаимоблокировка не вызвана ошибкой Oracle, а вызвана ошибками в дизайне приложения или стала результатом определенных операторов SQL. Проектировщики приложений должны писать в своем коде обработчики исключений,чтобы откатывать прерванные транзакции и перезапускать их. Избежать взаимоблокировок можно, уделив этому вопросу внимание на фазе проектирования и определив правильную последовательность блокировки объектов.

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

 

Управление блокировками Oracle

Как упоминалось вsit, блокировки в Oracle обычно устанавливаются самим Oracle неявно, и на наименее ограничивающем уровне. Пользователи могут переопределить механизм блокирования Oracle по умолчанию, но вы не так часто столкнетесь с ситуациями, когда это может понадобиться. Большая часть управления блокировками в реальной базе данных сводится к проверке того, есть ли какие-то активные блокировки, которые мешают пользователям выполнять их операции DML. Для анализа блокировок в экземпляре можно использовать либо подход на основе сценариев, либо Oracle Enterprise Manager.

 

Использование SQL для анализа блокировок

Текущую ситуацию с блокировками в экземпляре можно проверять с помощью сценариев SQL. Прежде чем впервые выполнить в базе данных любой относящийся к блокировкам сценарий, может понадобиться сначала запустить сценарий catblock.sql, находящийся в каталоге $ORACLE_HOME/rdbms/admin. Этот сценарий создаст несколько важных представлений, относящихся к блокировкам, таких как DBA_LOCKS,DBA_WAITERS и DBA_BLOCKERS.

Oracle поставляет сценарий по имени utllockt.sql, строящий древовидный граф блокирующих сеансов, которые удерживают блокировки, затрагивающие другие сеансы. Используя этот сценарий, можно посмотреть, освобождения какой блокировки может ожидать сеанс, и какой сеанс удерживает эту блокировку. Этот сценарий находится в каталоге $ORACLE_HOME/rdbms/admin. Ниже приведен пример выполнения сценария utllockt.sql

@$ORACLE_HOME/rdbmsa/admin/utllockt.sql
Waiting session   Type   Mode requested      Mode Held            Lock Id1
Ожидающий сеанс   Тип    Запрошенный режим   Удерживаемый режим   Идентификатор
---------------   ----   -----------------   ------------------   -------------
682               None   None                None                 0
363               TX     Share (S)           Exclusive (X)

На заметку!


В предыдущем примере идентификатор сеанса слева, равный 682, указывает на сеанс, которого ждет сеанс 363. Информация, выводимая справа от каждого сеанса,описывает блокировку, снятия которой он ожидает. Таким образом, сеанс 682, хотя и удерживающий блокировку, не показывает ничего (None) в столбцах, описывающих блокировки, потому что он никого не ждет. Однако строка сеанса 363 говорит о том, что этот сеанс запросил разделяемую (S) блокировку и ожидает от сеанса 682 освобождения его монопольной (X) блокировки строки таблицы.

В следующем примере из сценария utllockt.sql сеанс 9 ожидает сеанса 8, сеанс 7 ждет сеанса 9, а сеанс 10 ждет сеанса 9. 

* WAITING SESSION   TYPE   MODE REQUESTED   MODE HELD       LOCK ID1   LOCK ID2
* ---------------   ----   --------------   -------------   --------   --------
* 8                 NONE   None             None            0          0
* 9                 TX     Share (S)        Exclusive (X)   65547      16
* 7                 RW     Exclusive (X)    S/Row-X (SSX)   33554440   2 
* 10                RW     Exclusive (X)    S/Row-X (SSX)   33554440   2

Информация блокировки справа от идентификатора сеанса описывает блокировку,освобождения которой ждет сеанс (а не которую удерживает он сам).

Представления V$LOCK и V$LOCK_HOLDERS очень полезны для анализа блокировок в экземпляре, но иногда запросы к ним требуют длительного времени. Представление V$SESSION может быстро дать информацию для идентификации пользователя, удерживающего блокировку. Столбец blocking_session_status представления V$SESSION указывает на то, действительны ли данные blocking_session_status. Например,наличие значения VALID в столбце blocking_session_status означает, что в столбце blocking_session находится системный идентификатор (SID) блокирующего пользователя.

Рассмотрим пример простого запроса, который продемонстрирует использование представления V$SESSION для определения того, кто блокирует определенный сеанс:

SELECT sid, blocking_session, username, event
2 FROM v$session
3* WHERE blocking_session_status = 'VALID';
SID   BLOCKING_SESSION   USERNAME   EVENT
---   ----------------   --------   --------------------------------
24           32          SALAPATI   enq: TX - row lock contention
SQL> 

Приведенный выше запрос показывает, что пользователь с SID 24 заблокирован пользователем с SID 32. Столбец EVENT указывает тип блокировки, которую удерживает блокирующий сеанс.


На заметку! Таблицы словаря данных, которые следует проверить, чтобы найти информацию о блокировках — это представления DBA_LOCKS, DBA_BLOCKERS и DBA_WAITERS. Если по какой-то причине вы не видите представления DBA_BLOCKERS, запустите сценарий catblock.sql,находящийся в каталоге $ORACLE_HOME/rdbms/admin, чтобы создать его.


Использование интерфейса Database Control для управления блокировками сеансов

Наиболее эффективный способ увидеть, какие блокировки в данный момент существуют в экземпляре, заключается в использовании инструмента Oracle Enterprise Manager (OEM) Database Control (или Grid Control). Попасть на эту страницу можно через Database Control Home Page -> Performance -> Additional Monitoring Links -> Instance Locks (Домашняя страница Database Control -> Производительность -> Дополнительные ссылки мониторинга -> Блокировки экземпляра). На странице Instance Locks (Блокировки экземпляра) отображаются все замки — как блокирующие, так и не блокирующие.Большинство замков, которые вы увидите, безвредны; это стандартные неблокирующие замки, которые Oracle использует для поддержки параллелизма.

Чтобы увидеть замки, которые вызывают соперничество между сеансами в системе, выберите элемент Blocking Sessions (Заблокированные сеансы) из раскрывающегося списка на странице Instance Locks. На странице Blocking Sessions (Заблокированные сеансы) отображаются все сеансы, которые в данный момент блокируют другие сеансы. Перейти непосредственно на страницу Blocking Sessions можно также по маршруту Database Control Home Page -> Performance -> Additional Monitoring Links -> Blocking Sessions (Домашняя страница Database Control -> Производительность -> Дополнительные ссылки мониторинга -> Заблокированные сеансы).

На странице Blocking Sessions отображаются идентификаторы блокирующих и блокируемых сеансов (рис. 1). Блокирующий сеанс можно прервать, выбрав его и щелкнув на кнопке Kill Session (Уничтожит сеанс).

На рис. ниже видно, что пользователь nick_alapathi удерживает монопольную блокировку (на определенной строке таблицы test01, которую можно видеть на рисунке),тем самым блокируя попытки пользователя nina_alapathi получить монопольную блокировку той же строки. Блокирующий сеанс идентифицируется значением 1 или выше в столбце Sessions Blocked (Заблокированные сеансы) на странице Blocking Sessions (см. рис. 1.). Блокируемый сеанс обозначается значением 0.

Страница Blocking Sessions

Узнать в точности состояние ожидания блокирующих и ожидающих сеансов можно на OEM-странице Hang Analysis (Анализ зависаний), которая доступна по маршруту Database Control Home Page -> Performance -> Additional Monitoring Links -> Hang Analysis (Домашняя страница Database Control - Производительность - Дополнительные ссылки мониторинга - Анализ зависаний). На странице Hang Analysis отображается следующая информация:

  • мгновенно заблокированные сеансы;
  • сеансы, находящиеся в продолжительном ожидании;
  • зависшие сеансы.

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


На заметку!

Вас заинтересует / Intresting for you:

Oracle Personal Edition
Oracle Personal Edition 5204 просмотров Надин Tue, 21 Nov 2017, 13:32:12
Oracle alerts: генерируемые се...
Oracle alerts: генерируемые се... 4491 просмотров Алексей Вятский Tue, 21 Nov 2017, 13:18:05
Установка Oracle 11g на Linux
Установка Oracle 11g на Linux 15082 просмотров Илья Дергунов Tue, 21 Nov 2017, 13:18:05
Основные функций СУБД Oracle (...
Основные функций СУБД Oracle (... 2884 просмотров Stas Belkov Tue, 21 Nov 2017, 13:19:55
Войдите чтобы комментировать