Как стать автором
Обновить

Комментарии 18

Сколько стоит или будет стоить этот EE?
Насчет цен пишите на info@postgrespro.ru
Три фичи за реализацию которых хочется спросить «с какого бодуна?»
1. Mars несколько активных датаридеров. Просто не поддерживает протокол! И в итоге приходится в память считывать курсоры. О обработки каких больших таблиц речь идет?
2. Таймзоны таймстампов. Определяются не настройками сессии а настройками на клиентском (по отношению к пг) приложении. Это уже косяк драйверов но нафига так то? Про сервера приложений не слышали?
3. RLS клево, что сделали, но почему не как в оракле? Ведь никак не влияет ни на производительность ни на что. Ничем не лучше.
1. Не вполне понял, курсоры можно получать вообще частями, хоть по одной строчке. Если у Mars (это MultipleActiveResultSets?), то про него прямо написано: «Multiple Active Result Sets (MARS) is a feature that works with SQL Server to allow the execution of multiple batches on a single connection.» Т.е. MARS — это про SQL Server.
В постгресе Вам никто не мешает иметь одновременно несколько открытых курсоров в сессии.
2. «Таймзоны таймстампов» — как я понимаю, имеется в виду timestamp wih time zone; не совсем понятно что имеется в виду под словами «Определяются не настройками сессии а настройками на клиентском (по отношению к пг) приложении.»
В самом деле,
localhost postgres@work=# show timezone;
 TimeZone 
----------
 W-SU
(1 строка)

Время: 207,356 мс
localhost postgres@work=# set timezone='UTC';
SET
Время: 43,762 мс
localhost postgres@work=# select now();
              now              
-------------------------------
 2017-05-17 10:39:30.185535+00
(1 строка)

Время: 51,239 мс
localhost postgres@work=# set timezone='Europe/Moscow';
SET
Время: 12,238 мс
localhost postgres@work=# select now();
              now              
-------------------------------
 2017-05-17 13:39:46.049811+03
(1 строка)

Время: 0,508 мс



3. Если очень хочется, то можно сделать себе схему DBMS_RLS и написать соответствующие функции.
1. Нет, мешает протокол. Нельзя открыть курсор, делать из него фетч и на (допустим) каждую строку выполнять выполнять еще один запрос в этом же соединении. Посмотрите протокол постгреса.
2. Все замечательно, а теперь попробуйте сделать это в клиенте для .NET
3. Нет, даже если очень хочется, то проблема не в отсутствии функций из пакета DBMS_RLS а в том, как формулируются предикаты. В оракле полиси это функция, которая возвращает предикат, в пг это сам предикат. Не могу я написать функцию в пг, которая в зависимости от условий каких-либо возвращает предикат.

Есть странное поведение — pg_variables сбрасываются при коммите. Короче писать сервер приложений не очень удобно.
3… В оракле полиси это функция, которая возвращает предикат, в пг это сам предикат.

Постгрес не позволяет вставить политику, если в предикате ошибка, к примеру указано несуществующее имя поля. В оракле RLS (на зуб) не пробовал, но так понимаю он проверку не делает, а ошибки, если есть, выдает уже после обращения к данным.

Такими мелочами постгрес выглядит на голову продуманней оракла. Этим же он уступает конкуренту в скорости развития функционала.

Вообще интересно посмотреть живой проект, в котором RLS руками пишется. Я RLS рассматриваю тока как сгенерированный из какой-нибудь вспомогательной таблички.
Постгрес не позволяет вставить политику, если в предикате ошибка, к примеру указано несуществующее имя поля…
Такими мелочами постгрес выглядит на голову продуманней оракла. Этим же он уступает конкуренту в скорости развития функционала


Это конечно замечательно, что он проверит синтаксис в предикате.
Но тогда почему на голову продуманный постгрес не проверяет синтаксис и ссылки на поля в процедурах ??? Можно любую ересь написать там. А в непродуманном оракле при сохранении процедуры проверяется и наличие и правильность типов всех ссылаемых объектов.

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

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

1:1 ;-)

Именно так (генерация предикатов в рантайм) и сделано у нас в версии для оракла. И именно по указанным причинам пришлось отказаться от поддержки в версии для постгреса.


Если нужен предикат в рантайме для конкретного пользователя, могу посоветовать решение из собственного опыта. В постгресе есть CREATE TEMP VIEW… Перед INSERT, UPDATE, DELETE или SELECT генерите временное представление с добавленным предикатом и работайте с ним, при этом сама таблица может быть недоступна пользователю, а во временном представлении будут доступны только нужные записи.
Если нужен предикат в рантайме для конкретного пользователя, могу посоветовать решение из собственного опыта. В постгресе есть CREATE TEMP VIEW… Перед INSERT, UPDATE, DELETE или SELECT генерите временное представление с добавленным предикатом и работайте с ним, при этом сама таблица может быть недоступна пользователю, а во временном представлении будут доступны только нужные записи.

Это очевидное решение, однако недопустимо снижает производительность.
Пока нам проще подождать, может кто-то сделает это. Либо, если проект будет пользоваться интересом сделать самим.
Пока нам проще подождать, может кто-то сделает это.


Тут наверное стоит задать обоюдный вопрос к разработчикам PostgreSQL.

1. Существует ли реальная задача под которую создавался RLS, или статистика с практикой применения и администрирования?
2. Реализованный RLS действительно неудобен и не отвечает реальным потребностям в прикладных задачах, какие есть планы по доработке?

Пока нам проще подождать

Не, если ждать то ничего не будет, надо в хакерс написать предложение и usecase. Без этого, процесс вообще не пойдёт.

  1. Нет, мешает протокол. Нельзя открыть курсор, делать из него фетч и на (допустим) каждую строку выполнять выполнять еще один запрос в этом же соединении. Посмотрите протокол постгреса.

протокол строго однопоточный… а курсор это часть единого pipline который разорвать нельзя :(

1) смотри в чем прикол. Тут не марс виноват, марс это просто ну условный ограничитель параллельных ридеров, ну типа ReadersPerConnection = 1 или ReadersPerConnection = 30. Вне зависимости от марса, MS SQL Server, если тебе нужно, дает взять хоть даже одну первую строку из миллиона строк результатов и закрыть ридер, и общее время исполнения кода будет условно = <время исполнения запроса> + <время чтения одной записи из ридера>.

Постгре делает иначе, по крайней мере у меня на версии Npgsql 4.x (не обновляюсь пока потому что эти редиски не дают нормальных типов да хоть чтобы децималы читать в нативном виде и их уже потом в .NETовские пихать как вздумается, опять же MS SQL дает читать весь спектр decimal который можно сформировать на стороне базы данных ; )). Так вот, допустим у тебя есть в базе 200 млн строк, и вот ты написал запрос который из них по какой-то случайности выбрал 100к записей, ну бывает, мож у тебя пользователь натыкал настройки дат и вот получилось столько, не суть. И вот этот запрос полетел в базу, база сформировала тебе на выдачу эти 100к записей и отдала управление в библиотеку Npgsql читать их через NpgsqlDataReader.ReadNext(). Так вот эта библиотека, прежде чем отдать тебе первую строчку результата "всосет" во внутренний буфер все результаты, то есть разбухнет по памяти и сделает задержку огромную!

Вот у меня сейчас, чисто случайно есть таблица с 30 млн записей, и я спецом делаю OrderBy по всем записям, индекс срабатывает и данные на сторне сервера готовы за 36 милисекунд, а потом еще 4 минуты жду чтобы получить первую запись. Прикинь!!

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

2) таймзоны это отдельная боль. Какого черта экономить на байтах и резать ее если вы уже задекларировали второй тип с пометкой WITH TIMEZONE? Накой черт жать данные с потерей, а? Если пользователь захочет, он не будет использовать тип WITH TIMEZONE, а если захотел, то наверное, ОНА ЕМУ НУЖНА :). Таймзона это такие же данные, по ним, ну вот так с потолка, можно разделять источники данных, ну вот есть у тебя инстанс приложения в европе и есть инстанс приложения в америке, и оба они чет там добавляют в общую базку (как так случилось опустим) с датой создания не заморачиваясь с переводом в UTC и ты можешь просто взяв таймзону и узнать откуда что пришло. Может для мелких стран с ОДНОЙ таймзоной это не важно, но у нас есть как бы всякие регионы, и даже у того же сбербанка процессинговые центры есть в каждом регионе. Но этим редискам видимо 4-5 байтов важнее функциональности и они возомнили себя дофига важными решать за пользователя ужимать ему данные или нет. Я хочу решать что мне хранить и как мне хранить МОИ! данные, а не какой-то рак с заморской кудыкиной горы! ;)

Кажется я все же должен себя поправить и сказать, что по первому пункту я не прав. В MS SQL тоже есть задержка на первую запись, сравнимая с PostgreSQL

Мультимастер, конечно, вещь интересная, но почему бы сначала не подумать о реализации кластеризации «из коробки» хотя бы с одним мастером? Мне кажется, что подобный кейс для бизнеса более популярен
Обратите внимание на синхронную репликацию.
Все же репликация != кластеризация

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

Зарегистрируйтесь на Хабре, чтобы оставить комментарий