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

1- Я создал свой заголовочный файл mine.h, в котором я объявил свой глобальный флаг следующим образом.

extern int CMD_FLAG;
extern void init_vars();// this function to initialize CMD_FLAG

2- Я включил mine.h в pgsql/src/include/ ch, так как он виден как внешним, так и внутренним интерфейсом.

3 - в pgsql/src/port/exec.c я написал тело функции init_vars(), которая инициализирует CMD_FLAG, следующим образом:

int CMD_FLAG;

void init_vars(){
   CMD_FLAG =-1;
}

4- В pgsql/src/backend/main/main.c я позвонил

init_vars(); 

когда я скомпилировал Postgresql, я не получил никакой ошибки. Однако, когда я попытался напечатать значение флага, у него были разные значения в бэкэнде и во фронте.

Например, когда я напечатал его в функции "HandleSlashCmds", которая находится во внешнем интерфейсе, значение было 0, тогда как предполагалось, что оно будет -1.

Если я внесу какие-либо изменения в флаг в веб-интерфейсе, это изменение относится только к функциям веб-интерфейса. С другой стороны, если я сделаю какое-либо изменение в обратном флаге, это изменение относится только к внутренним функциям.

Я думаю, что как-то есть 2 копии флага по одному на каждом конце. Как сделать так, чтобы оба конца обращались к одному значению?

1 ответ1

0

Интерфейс и бэкэнд - это разные процессы, взаимодействующие по сетевому протоколу.

Самая близкая вещь к тому, что вы хотите - это переменная GUC ("великая унифицированная конфигурация"). Вы можете определить пользовательский GUC на внутреннем сервере с помощью DefineCustomIntVariable и установить для него флаг GUC_REPORT чтобы при его изменении оператором SET и т.д. Новое значение сообщалось клиенту с помощью асинхронного уведомления в проводном протоколе. Клиентское приложение может обнаружить это изменение и применить новый параметр.

Точно так же, когда переменная изменяется на клиенте, он может отправить запрос SET чтобы назначить новое значение на сервере.

Это, очевидно, связано с задержками, тем более что протокол допускает только запросы SET и ответы на уведомления в определенные моменты времени. На практике вы увидите изменения в переменных только после завершения запросов. Так что это не то же самое, что просто установить переменную в памяти.

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

Что бы вы ни пытались сделать, я сильно подозреваю, что это не способ сделать это.


Кстати, вам действительно не нужно для этого исправлять PostgreSQL. Расширение _PG_init() может работать во время запуска сервера, если оно указано в shared_preload_libraries . В это время он может выделять сегменты общей памяти, определять GUC и т.д.


Если вам действительно нужно убедиться, что между внешним интерфейсом и внутренним интерфейсом существует одинаковая переменная, и если внешний интерфейс и внутренний сервер выполняются на том же хосте, что и один и тот же пользователь, вы можете сделать что-то, используя анонимную память и атомарность mmap'd. Было бы трудно понять это правильно, и на вашем нынешнем уровне это потребует много изучения.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .