Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Переключать схему RW/RO / 15 сообщений из 15, страница 1 из 1
12.05.2021, 02:26
    #40069508
Arez
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
Приложение поддерживает MySQL и Oracle (18c, standard edition). В MySQL можно выполнить "set global read_only=1" что запретит любые изменения для обычных пользователей. Хотелось бы сделать что-то похожее в Oracle, для отдельной схемы. Это нужно изредка, как часть процесса переключения на другую БД.

Что обязательно:
  • возможность читать должна остаться
  • специальные пользователи (репликация, автоматизация) должны сохранить возможность писать
  • атомарность переключения (не бегать по всем объектам, меняя права)
Желательно
  • инициация со стороны БД. Со стороны приложений не так интересно :)
  • в RO режиме DML и DDL должны возвращать свою отдельную ошибку (это нужно для приложения, чтобы замереть, а потом продолжить на новой БД)
  • не оставлять хвостов в случае сбоя.
  • если что-то помешало и вернулись в RW на той же базе, сохранить транзакцию.
Что не подошло / не нравится:
  • переключать tablespace в readonly (теряется репликация и запись для суперпользователя)
  • давать/отнимать роли (нежелательно передподключаться, также хочется сохранить транзакции если отменилось)
  • set transaction read only. Активация на стороне приложения, а значит возможен split brain.
Идеи:
  • Вместо ролей, системные привилегии. Разграничить владельца схемы и пользователя приложения (ПП). У ПП логон-триггер меняет схему на нужную. Даем/отбираем права INSERT/UPDATE/DELETE/SELECT/ALTER/CREATE/DROP ANY TABLE. Не нравится, что слишком широкие привилегии (ANY), и ошибка "insufficient privileges" не отдельная.
  • Давать/отнимать системные привилегии роли. Похоже на предыдущий способ.
  • DML триггер. На каждой таблице "before statement" триггер, проверяющий флаг из global context и выбрасывающий ошибку если не. Отдельный schema-level trigger вешает тот DML триггер на каждую создаваемую таблицу. И еще один, похожий, для DDL. Не нравится, что у каждой таблицы триггер, и (вроде бы) для RAC нужно менять режим отдельно на каждом instance.
  • Убедить Оракл сделать schema-level privileges. Понятно что не сделают, но можно уйти на пенсию, и это станет проблемой других людей. Недостатки: долго, нудно, неспортивно.
...
Рейтинг: 0 / 0
12.05.2021, 11:54
    #40069571
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
Можно попробовать Oracle RLS
...
Рейтинг: 0 / 0
12.05.2021, 11:59
    #40069574
PuM256
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
andrey_anonymous,

В SE, кажется, не поддерживается?
...
Рейтинг: 0 / 0
12.05.2021, 12:44
    #40069588
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
PuM256
В SE

Прошу прощения, был невнимателен.
...
Рейтинг: 0 / 0
12.05.2021, 14:41
    #40069629
SeaGate
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
ArezПриложение поддерживает MySQL и Oracle (18c, standard edition). В MySQL можно выполнить "set global read_only=1" что запретит любые изменения для обычных пользователей. Хотелось бы сделать что-то похожее в Oracle, для отдельной схемы. Это нужно изредка, как часть процесса переключения на другую БД.
EBR с "read-only"/"read-write" editions. "read-only" editions содержат read-only editioning views.
edition устанавливается на уровне database service.
В целом, похоже на очередную xy problem.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
SQL> conn / as sysdba
Connected.
SQL>
SQL> alter session set container=pdb1;

Session altered.

SQL>
SQL> drop edition e2_ro cascade;

Edition dropped.

SQL> drop edition e1_rw cascade;

Edition dropped.

SQL> drop user tc cascade;

User dropped.

SQL>
SQL> !srvctl modify service -db o1911a -service tc -edition ""

SQL>
SQL> grant create procedure, create session, create table, create view to tc identified by tc;

Grant succeeded.

SQL>
SQL> alter user tc enable editions;

User altered.

SQL>
SQL> alter user tc quota 100M on users;

User altered.

SQL>
SQL> create edition e1_rw;

Edition created.

SQL>
SQL> create edition e2_ro;

Edition created.

SQL>
SQL> grant use on edition e1_rw to tc;

Grant succeeded.

SQL> grant use on edition e2_ro to tc;

Grant succeeded.

SQL>
SQL> !srvctl modify service -db o1911a -service tc -edition e1_rw

SQL>
SQL> conn tc/tc@myrac-scan/tc
Connected.
SQL>
SQL> select sys_context('userenv', 'session_edition_name') from dual;

SYS_CONTEXT('USERENV','SESSION_EDITION_NAME')
--------------------------------------------------------------------------------
E1_RW

SQL>
SQL> create table t#
  2  as
  3  select *
  4    from dual;

Table created.

SQL>
SQL> create editioning view t
  2  as
  3  select *
  4    from t#;

View created.

SQL>
SQL> create or replace procedure p
  2  is
  3  begin
  4    update t set dummy='Y';
  5  end;
  6  /

Procedure created.

SQL>
SQL> alter session set edition=e2_ro;

Session altered.

SQL>
SQL> alter view t read only;

View altered.

SQL>
SQL> conn tc/tc@myrac-scan/tc
Connected.
SQL>
SQL> select sys_context('userenv', 'session_edition_name') from dual;

SYS_CONTEXT('USERENV','SESSION_EDITION_NAME')
--------------------------------------------------------------------------------
E1_RW

SQL>
SQL> select * from t;

D
-
X

SQL>
SQL> update t set dummy='Y';

1 row updated.

SQL>
SQL> exec p

PL/SQL procedure successfully completed.

SQL>
SQL> commit;

Commit complete.

SQL>
SQL> select * from t;

D
-
Y

SQL>
SQL> !srvctl modify service -db o1911a -service tc -edition e2_ro

SQL>
SQL> conn tc/tc@myrac-scan/tc
Connected.
SQL>
SQL> select sys_context('userenv', 'session_edition_name') from dual;

SYS_CONTEXT('USERENV','SESSION_EDITION_NAME')
--------------------------------------------------------------------------------
E2_RO

SQL>
SQL> select * from t;

D
-
Y

SQL>
SQL> update t set dummy='Y';
update t set dummy='Y'
       *
ERROR at line 1:
ORA-42399: cannot perform a DML operation on a read-only view


SQL>
SQL> exec p
BEGIN p; END;

*
ERROR at line 1:
ORA-42399: cannot perform a DML operation on a read-only view
ORA-06512: at "TC.P", line 4
ORA-06512: at line 1


SQL>
SQL> select * from t;

D
-
Y

SQL>
SQL> col edition_name for a12
SQL>
SQL> select edition_name, read_only
  2    from user_views_ae;

EDITION_NAME R
------------ -
E1_RW        N
E2_RO        Y

...
Рейтинг: 0 / 0
12.05.2021, 21:57
    #40069786
Arez
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
SeaGate

EBR с "read-only"/"read-write" editions. "read-only" editions содержат read-only editioning views.
edition устанавливается на уровне database service.

Интересный подход, и отдельное спасибо за демо. Вряд ли подойдет, но познавательно.
Я с editions практически не работал, поэтому два вопроса:

Код: plsql
1.
2.
SQL> !srvctl modify service -db o1911a -service tc -edition e2_ro
SQL> conn tc/tc@myrac-scan/tc

Обязательно? Т.е. edition меняется только для новых подключений?

И второй вопрос: DDL надо будет выполнять на обеих editon?

SeaGate

В целом, похоже на очередную xy problem.
Ну, первичная проблема пожалуй в split brain. Отсюда требования к атомарности, минимизации SoT, и чтобы старая БД не давала себя менять даже если какой-то заблудившийся экземпляр приложения захочет.
...
Рейтинг: 0 / 0
13.05.2021, 00:00
    #40069804
SeaGate
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
ArezОбязательно? Т.е. edition меняется только для новых подключений?
Либо srvctl, либо dbms_service.modify_service.
Да, это для новых подключений.

В похожей задаче был использован следующий подход:
1) установка новый default edition для database. Это покрывает новые соединения.
2) Для старых соединений:
запрос проверки connection pool вызывал легковесную функцию, сравнивающий edition сессии и текущий default edition для database.
Если не совпадают, вызов dbms_session.set_edition_deferred.

Это позволяло мигрировать все сессии постепенно: за 2-3 минуты. Могли быть некие длительные запросы, которые бы смигрировали через 10-15 минут, но единомоментной миграции не требовалось. Если нужно ускорять такие миграции, то можно использовать DBMS_SERVICE.DISCONNECT_SESSION.

Менять edition для БД или для service - решается в каждом конкретном случае.

ArezИ второй вопрос: DDL надо будет выполнять на обеих editon?
DDL выполняется только один раз.
Классический вариант использования editions, когда в старых editions ничего не меняется.
edition это рабочая версия приложения.
Любые изменения только в самой последней(новой) edition. Если что-то пошло не так, то на новый edition просто не выполняется переключение. Edition удаляется и приложение ничего об этом не знает, т.к. оно не переключалось на новый edition. В крайних случаях, когда переключение таки произошло, всегда можно выполнить обратное переключение и удалить edition.

ArezНу, первичная проблема пожалуй в split brain. Отсюда требования к атомарности, минимизации SoT, и чтобы старая БД не давала себя менять даже если какой-то заблудившийся экземпляр приложения захочет.
Для чего выполняется переключение на новую БД?
Если оперировать на уровне database service, то никакой split brain в принципе не возможен.
Конкретно: приложение использует конкретный service и host (это может быть пара хостов разных БД или CMAN/GDS/SCAN address). Если есть задания (dbms_scheduler) в БД, они также используют service.
Если нужно запустить этот service в другой БД, то:
1) service останавливается; - это предотвращает новые подключения;
2) завершаются транзакции/сессии; - здесь есть варианты: подождать или завершить принудительно; srvctl/dbms_service в помощь.
3) service запускается в новой БД; - здесь нет никаких "заблудившихся экземпляров приложений".
4) на этом этапе приложение полностью работает в новой БД. Со старой БД приложение не работает.

Я выполнял переключение на новую БД в схеме, где было две БД. Приложение всегда работало только с одной. Между БД была настроена bi-directional replication (BDR) с помощью GG. Любые изменения БД для приложения (новые прикладные патчи) выполнялись в той БД, с которой приложение не работало. Репликация в это время продолжала работать и приложение об изменениях ничего не знало (это накладывало ограничение на то, какие изменения можно проводить, например, поля нельзя удалять в такой схеме, если приложение в них пишет, - replicat будет abended).
В момент, когда было решено переключаться на новую версию/другую БД, это инициировалось с уровня приложения, с кратковременной заморозкой всей активности, потому переключения не проводились в час пик.
Технически, возможно, это вызывать с уровня БД с кратковременной остановкой активности.
Возможно также уменьшить паузы при подобных переключениях, но такая схема никогда не будет быстрее EBR решения по очевидным причинам.
...
Рейтинг: 0 / 0
13.05.2021, 09:05
    #40069856
Arez
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
SeaGate

Это позволяло мигрировать все сессии постепенно: за 2-3 минуты. Могли быть некие длительные запросы, которые бы смигрировали через 10-15 минут, но единомоментной миграции не требовалось.
В нашем случае важно сохранить immediate consistency. Вернее ее вариацию: в процессе переключения часть узлов может читать из старой БД, но писать нельзя.

SeaGate

ArezНу, первичная проблема пожалуй в split brain. Отсюда требования к атомарности, минимизации SoT, и чтобы старая БД не давала себя менять даже если какой-то заблудившийся экземпляр приложения захочет.
Для чего выполняется переключение на новую БД? Если оперировать на уровне database service, то никакой split brain в принципе не возможен.
Переключение нужно для своей версии switchover. Ну и попутно для failover, но с ней проще. БД в разных дата-центрах, так что сервисом не обойдешься. Более того, как правило БД принадлежат и администрируются заказчиком, поэтому желательно решение с минимальной "внешней" конфигурацией.

Сейчас сделали для MySQL: у приложения в конфиге (своем, не db url) несколько БД, оно их мониторит и переключается на (единственную) БД доступную для записи. Соответственно, автоматизация делает RW1,RO2 -> RO1 -> RW2. Там масса нюансов, но они тут не важны. Соответственно, хочется без особых изменений добавить поддержку Oracle.

А вообще в идея с сервисом привлекательная. Жаль что его можно остановить, но нельзя сделать readonly.
...
Рейтинг: 0 / 0
13.05.2021, 21:08
    #40070142
SeaGate
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
ArezБД в разных дата-центрах, так что сервисом не обойдешься.
БД может быть где угодно. Дескриптор соединения может содержать несколько endpoints.
...
Рейтинг: 0 / 0
13.05.2021, 21:11
    #40070143
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
SeaGate
ArezБД в разных дата-центрах, так что сервисом не обойдешься.

БД может быть где угодно. Дескриптор соединения может содержать несколько endpoints.
Да и с одним endpoint в дескрипторе есть варианты к разным БД подключаться.
...
Рейтинг: 0 / 0
13.05.2021, 21:29
    #40070148
SeaGate
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
andrey_anonymousДа и с одним endpoint в дескрипторе есть варианты к разным БД подключаться.
Да, верно.
...
Рейтинг: 0 / 0
13.05.2021, 23:36
    #40070166
Arez
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
SeaGate
ArezБД в разных дата-центрах, так что сервисом не обойдешься.

БД может быть где угодно. Дескриптор соединения может содержать несколько endpoints.
И выбирать гася/стартуя сервис?
...
Рейтинг: 0 / 0
13.05.2021, 23:42
    #40070167
Arez
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
andrey_anonymous
SeaGate
пропущено...

БД может быть где угодно. Дескриптор соединения может содержать несколько endpoints.

Да и с одним endpoint в дескрипторе есть варианты к разным БД подключаться.
SCAN/GNS?
Мы конечно можем высказывать пожелания, но GNS в требованиях к приложению будет слишком. SCAN - да, был у всех заказчиков что я видел.
CMAN - EE, не подходит.
...
Рейтинг: 0 / 0
14.05.2021, 00:51
    #40070178
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
Arez, можно начать с банального dns
...
Рейтинг: 0 / 0
14.05.2021, 08:20
    #40070202
Arez
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переключать схему RW/RO
andrey_anonymous
Arez, можно начать с банального dns
Можно конечно, клиентов к сервисам приложения так и перекидывают, через DNS load balancer-а.

Но ведь никогда нельзя быть уверенным, что DNS обновился на всех узлах приложения, или все они получили сообщение о переключении. Да даже в БД, если мы возьмемся отстреливать сессии (что само по себе плохо), возможны и задержки, и сбой посередине процесса; всегда есть риск, что часть узлов останется на старых соединениях. Тем более при failover, когда все априори в раздрае.

Поэтому и хотелось бы, чтобы БД сама себя защищала: не давала писать кому не надо, и переключалось атомарной операцией.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Переключать схему RW/RO / 15 сообщений из 15, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]