Обновить

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

Очень неплохо.

Процессы в вашей организации, конечно, грустные, git должен быть первичен, а база вторична. Но вообще такое, чтобы все на живой базе жили - не редкость.

Насчёт чтения метаданных в транзакции read commited не понял: чем snapshot не подошёл? Вроде бы можно читать, не блокируя никаких других читателей и писателей.

И ещё хотел спросить: из полученных скриптов можно создать новую базу? Если да, то как в этом случае определяется порядок накатки для таблиц, чтобы можно было foreigh key ограничения накатывать.

К сожалению это частая ситуация, у меня тоже ночью бежит GitHub action который через power shell создаёт отдельный файл для каждого объекта, и комитит изменения. Azure SQL Server. Много раз пригодилось, а потом я нашел этому интересное применение, наверно надо отдельным постом, если кому-то интересно.

Спасибо большое за Ваш комментарий, мне очень приятно, что именно Вы мне написали, автор статей про внутренности Firebird, которые я читал, и было очень интересно. Тысячекратно благодарен вашим трудам!

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

Про изоляцию — замечание по делу. Snapshot concurrency, не table stability действительно ничего не блокирует и дал бы согласованный слепок, а мне он для дампа схемы нужнее, чем текущее поведение. Read committed достался инструменту от общего правила внутри комманды: у нас все транзакции идут read committed + rec version + no wait.

Про создание базы из дерева — здесь слабовато у меня получилось, и я его в статье обозначил слишком вскользь наверное или мягко. Простой склейкой файлов базу не поднять, и как раз из-за foreign key: ограничения лежат внутри файла своей таблицы (это осознанный размен — нужен был для того чтобы разработчику который смотрит файл имел сразу все зависимости, вообщем так у нас опять согласовалось), поэтому при алфавитной склейке ALTER TABLE … ADD CONSTRAINT … REFERENCES может встретиться раньше, чем создана таблица, на которую он ссылается. То же самое с представлениями поверх представлений.

Порядок накатки — это скорее задача отдельного инструмента, который раскладывает дерево по фазам: сначала домены и генераторы, потом таблицы без ограничений, потом ограничения, потом индексы, потом представления и PSQL, в конце права и комментарии. Внутри фазы ограничений порядок уже не важен, а внутри PSQL цикличные зависимости снимаются тем, что процедуры и функции создаются через CREATE OR ALTER: сначала все заголовки, потом все тела. Дампер сознательно об этом не знает: он описывает состояние, а не порядок применения.

В организации, в которой я работаю, технологий много и процессы неоднородные.

В Firebird много хранимок, и они продолжают плодиться, а разработчики следуют такому процессу: для каждого релиза создаётся git-ветка, и туда добавляют меняющие скрипты. С хранимками и функциями проще, там всегда CREATE OR ALTER PROCEDURE, с таблицами - там ALTER TABLE, для данных тоже изменяющие скрипты. Отслеживать зависимости между этими сложно, разработчик должен это хорошо понимать. Если решили, что какой-то функционал нужно в следующий релиз подвинуть - это очень больно. Но зато сразу есть скрипты, которые будут менять прод базу в процессе релиза.

А разработчики, использующие Postgres, пошли по-другому: не пишут alter-скрипты, только создание базы с нуля. Структура такая: для каждой таблицы каталог, там скрипт создания таблицы, скрипт ограничений и скрипт грантов. Коллега написал инструмент на python, который сначала накатывает таблицы, потом ограничения, и в конце гранты. Это не один файл, как у вас, но хоть файлы, относящиеся к одной таблице, рядом лежат. У инструмента есть киллер-фича: он умеет, как ваш, создавать файлы из базы, а ещё умеет alter-скрипты создавать, имея старую базу и файлы для новой базы. В open source выложить не дадут, а жаль. Python для таких задач хорош, коллега, как вы, сначала пользовался isql/psql, но плюнул.

А насчёт того, как жить разработчику, который очень привык сначала экспериментировать с базой, а потом в git коммитить. Есть две вещи, которые могут помочь понять, что разработчик делал. Во-первых, можно писать историю запросов из инструментария. Вроде бы это умеет DBeaver Pro, возможно это умеет IBExpert. Во-вторых, можно в firebird на сервере настроить трассировку, и все запросы будут в файл попадать.

CREATE TABLE ZAKAZ_SPEC ( DAT_ BAS$DATE NOT NULL, CARDINDEX BAS$ID, QUANTITY BAS$SUMMA NOT NULL, WEEK_NUMBERS BAS$VAR_255, INROAD BAS$SUMMA ); ALTER TABLE ZAKAZ_SPEC ADD CONSTRAINT U_ZAKAZ_SPEC_DAT_CARDINDEX UNIQUE (DAT_,CARDINDEX) USING ASCENDING INDEX U_ZAKAZ_SPEC_DAT_CARDINDEX; COMMENT ON COLUMN ZAKAZ_SPEC.DAT_ IS 'date_type=timestamp'; GRANT SELECT ON ZAKAZ_SPEC TO USER AA;

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

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

Первое что бросается в глаза - оператор CREATE TABLE в одну строку. Человеку читать неудобно, и результаты diff так же будут неудобочитаемые. Но наверное причина в том что бы "выигрыш в отсутствии парсера текста". Выглядит достаточно логично. Читаем построчно, в одной строке - один sql-оператор, выполняем, и все Ок. Процедуры - отдельными файлами, там (наверное) один файл - одна процедура, один оператор CREATE PROCEDURE. Правда, тут же возникает вопрос - а каменты к процедуре в том же файле? Это же будет отдельный оператор...

Ну и собственно вопрос. А как быть с построчным чтением COMMENT ON ..., ведь внутри камента переносы строк допустимы, и например я этим активно пользуюсь. В IBexpert в инспекторе объектов, в табичной части видно первую строку камента, а если навести мышку, то в хинте будет весь камент. Ну или открыть нужный объект в виде отдельного окна и там посмотреть описание полностью. Соответственно, из-за возможных переносов строк внутри камента, возможность построчно, без парсинга, читать операторы - она как минимум весьма рискована, и если парсинг все-таки имеет место быть, тогда зачем страдать читая CREATE TABLE одной строкой, или почему бы не пойти дальше (для отказа от sql-парсинга) - каждый оператор отдельным файлом, что бы многострочность не требовала парсить sql-текст?

Спасибо за комментарий! На счет вашего создание в строку , это я накосячил ужасно с форматирование текста статьи, слишком много написал и некоторые разделы раздуты наверное, стараюсь больше такого не повторять

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

Публикации