Показаны сообщения с ярлыком oracle. Показать все сообщения
Показаны сообщения с ярлыком oracle. Показать все сообщения

среда, 19 января 2011 г.

Шифрация базы в Firebird и конкурентах

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

И обычно ответы сделаны как под копирку - что мол 100%, надежного способа это обеспечить, если база доступна физически нет. Но вот что встретилось в firebird-architect:

Alex Peshkoff, Nov 10, 2010:
I've already mentioned - we have plans to implement line encryption in FB3.0 and may be page level encryption too. We have already decided that we provide interface for users' plugins to perform actual crypt operations.

Как я упоминал ранее в планах есть реализация линейного(?) шифрования в 3.0. Вероятно также шифрование на уровне страниц. Было решено, что реализовано это будет посредством плагинов с возможностью их самостоятельной реализации.


И краткий обзор, что есть у конкурентов:


MySQL
  • нет шифрования файла
  • есть защищенное соединение
http://dev.mysql.com/doc/refman/5.0/en/secure-connections.html

PostgreSQL
  • нет шифрования файла 
  • есть защищенное соединение

http://www.postgresql.org/docs/8.1/static/ssl-tcp.html
http://www.postgresql.org/docs/9.0/static/pgcrypto.html

MSSQL
  • есть шифрование файла
  • есть защищенное соединение
http://msdn.microsoft.com/en-us/library/bb934049%28v=SQL.100%29.aspx
http://msdn.microsoft.com/en-us/library/ms189067%28v=SQL.90%29.aspx

DB2
  • есть шифрование файла
  • есть защищенное соединение

http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/index.jsp?topic=/com.ibm.db2.luw.admin.sec.doc/doc/c0005815.html

Oracle
  • есть шифрование файла 
  • есть шифрование полей
  • есть защищенное соединение
http://www.oracle.com/technetwork/database/options/advanced-security/index.html

суббота, 29 сентября 2007 г.

Неоднозначность в запросах с сортировкой и distinct

Такой вот запрос, в FB2 отрабатывает, но данные возвращает в случайном порядке.
select distinct(t.f1) from table1 t order by t.id

Как подсказал Дима Кузьменко:
сначала идет distinct, потом order.
то есть. набор выливается в sort, удаляются повторы.
Затем набор сортируется по атрибуту order.
как оно этот атрибут возьмет - зависит от того, как на диске
или в индексе легло.
план в 2.0 - PLAN SORT (SORT ((table1 NATURAL)))

А вот Oracle(как выяснилось и PostgreSQL) с такими запросами посылает(после чего и поднялся вопрос).
http://ora-01791.ora-code.com/
ORA-01791: not a SELECTed expression
Cause:
There is an incorrect ORDER BY item. The query is a SELECT DISTINCT query with an ORDER BY clause. In this context, all ORDER BY items must be constants, SELECT list expressions, or expressions whose operands are constants or SELECT list expressions.
Action:
Remove the inappropriate ORDER BY item from the SELECT list and retry the statement.


Для экспериментов:
CREATE TABLE TABLE1 (
ID INTEGER NOT NULL,
F1 VARCHAR(10)
);

INSERT INTO TABLE1 (ID, F1) VALUES (1, 'q');
INSERT INTO TABLE1 (ID, F1) VALUES (2, 'w');
INSERT INTO TABLE1 (ID, F1) VALUES (3, 'e');
INSERT INTO TABLE1 (ID, F1) VALUES (4, 'r');
INSERT INTO TABLE1 (ID, F1) VALUES (5, 't');
INSERT INTO TABLE1 (ID, F1) VALUES (6, 'q');
INSERT INTO TABLE1 (ID, F1) VALUES (7, 'w');
COMMIT WORK;

воскресенье, 2 сентября 2007 г.

Мега связка Perl+Oracle

DBD-Oracle-1.19\README.win32.txt
1)...
8) Enough Downloading and installing go have a coffee.

А перед этим мы скачали все что только можно от МС(Microsoft Visual Studio 2005,Windows SDK, Microsoft .Net framework 1.1) - опенсорс, мля.

PS не нужно воспринимать сей пост серьезно
PSS хотя...

вторник, 26 июня 2007 г.

Долговременная очередь в таблице Oracle

Возникла задача организации долговременной очереди, используемой несколькими параллельными конкурирующими обработчиками, которые, в общем случае, могут находиться на разных машинах.
Доп требование к очереди - ее архивное хранение и ограничение по используемой СУБД - Oracle.

Путей решения виделось несколько:
1. Использование готового решения от Оракл - AQ
2. Создание сервера приложений - эдакого контроллера очереди, посредством которого доступ к данным будет сериализован
3. Использование механизма конкурентного доступа и блокировок самой СУБД.

По ряду обстоятельств(технические сложности работы а AQ и полнейшее с ним незнакомство, трудоемкость создания доп слоя...) был выбран третий путь(учитывая FB-шное прошлое он показался более близким, чтоль:)

Суть метода в том, что обработчик помечает пакет записей заблокированными на обработку - в это время никто не должен иметь к ним доступа, а после обработки блокировка снимается и сообщения помечается обработанным.

В FB такое можно сделать посредством подобной селективной процедуры, привычно ставя блокировку холостым апдейтом.

CREATE PROCEDURE QUERY_SEL(row_count integer) RETURNS (ID_row INTEGER)
AS
begin
for select first(:row_count) sq.id_row,
from query sq
where sq.id_send_state=1
into :id_row do
begin
update sgt_query sq set sq.id_mess_state=2
where sq.id_row=:id_row;
suspend;
when any do
begin
row_count = row_count +1;
end
end
end

Оракл оказался богаче - недокументированный for update skip locked; подходил идеально(похоже это и есть механизм реализации AQ), но слушая Кайта с негодованием отметаем подобный "ugly hack" и пытаемся сделать это вручную, посредством pipeline функции.

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

create or replace procedure sgt_queue_lock(
row_count in integer default 10,
locker_id_ in integer )
as
lockedCount integer := 0;
ERROR_LOCK EXCEPTION;
PRAGMA EXCEPTION_INIT(ERROR_LOCK, -54);
PRAGMA AUTONOMOUS_TRANSACTION;
begin
-- receive all unlocked and unsended messages and lock them
-- from competitive lockers
for r1 in (select id_mess from SGT_QUEUE t where t.ID_mess_STATE=1
for update nowait)
loop
begin
-- long time lock for processing time
update SGT_QUEUE t set t.ID_mess_STATE=2,t.LOCKER_ID=locker_id_
where t.ID_mess=r1.id_mess;
lockedCount := lockedCount+1;

if(row_count=lockedCount) then
exit;
end if;

-- if row is locked - skip it
exception when error_lock then
null;
end;
end loop;
commit;
end sgt_queue_lock;

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


create or replace function queue_get
(row_count integer, locker_id integer)
return queue_table_type PIPELINED
as
suspendedCount integer := 0;
out_rec queue_type := queue_type(null,null,null,null);
begin
-- долговременно и монопольно блокируем пакет записей для
-- обработки определенным процессом
BEGIN
-- проверяем, есть ли еще необработанные/не отосланные сообщения в очереди
-- если есть - то новых блокировать не будем
-- из-за отсутсвия exists проверям наличие записей очень извратно
select 0 into suspendedCount from SGT_QUEUE t
where t.LOCKER_ID=locker_id and
t.ID_MESS_STATE=2 and rownum=1;
EXCEPTION WHEN NO_DATA_FOUND THEN
begin
SGT_QUEUE_LOCK(row_count,locker_id);
end;
END;

-- выше использовали как временную заглушку
suspendedCount := 0;
-- выбираем записи помеченные на обработку для этого процесса
-- (не провайдера, а именно процесса)
for r1 in (select id_MESS, MESS_DATA from SGT_QUEUE t
where t.LOCKER_ID=locker_id and t.ID_MESS_STATE=2
order by t.MESS_PRIORITY DESC,t.RECEIVE_TIME ASC)
loop
out_rec.id_mess := r1.id_mess;
out_rec.mess_data := r1.mess_data;

PIPE ROW(out_rec);

suspendedCount := suspendedCount+1;
if(row_count=suspendedCount) then
exit;
end if;

end loop;
return;
end queue_get;

Из недостатков видится не максимальная скорость работы, но учитывая то, что записи на обработку будут забираться пакетно - особой проблемы это не составит.
Может кто еще какие сложности/ошбики видит?

Да, как оказалось, подобные вопросы встречаются регулярно :)

Выбрать первую незаблокированную запись из таблицы, как?
http://www.sql.ru/forum/actualthread.aspx?tid=389300&hl=aq

Таблица oracle как очередь
http://www.sql.ru/forum/actualthread.aspx?tid=309047&hl=aq

Параллельная работа с записями.
http://www.sql.ru/forum/actualthread.aspx?tid=307911&pg=-1&hl=aq

Select for update - как получить незаблокированные данные
http://www.sql.ru/forum/actualthread.aspx?tid=264566&pg=-1&hl=aq

Таблица-буфер. Уникальная выборка строк для каждого процесса.
http://www.sql.ru/forum/actualthread.aspx?tid=239337&hl=aq

четверг, 14 июня 2007 г.

Нет в Oracle exists

Нет в оракле конструкции exists в pl/sql, подобной той, что есть в Firebird/Interbase
if exists(select..) then
приходится извращаться через:
select count(1) into from table where rownum=1
EXCEPTION WHEN NO_DATA_FOUND THEN
code;

Надеюсь rownum=1 дает хоть какой-то выигрыш в скорости(exists достаточно быстрая операция, в отличии от count).

PS
Прикольно - казалось бы логичное ограничение в rownum=1, может сработать не всегда - когда таблица партиционирована, используется каунт и включен параллелизм - может идти фуллскан по всей таблице. Горе от ума, что говорится.
Правда до версии 10g r1 (Relevant for Oracle until 10g r1)
"Selecting ROWNUM = 1 with 100.000 PIO"
http://www.db-nemec.com/Selecting_ROWNUM_1.html