Блокировка обновлений postgresql ubuntu

Обновлено: 04.07.2024

Я хочу сделать большое обновление таблицы в PostgreSQL, но мне не нужно поддерживать целостность транзакций на протяжении всей операции, потому что я знаю, что столбец, который я изменяю, не будет записываться или считываться во время обновление. Я хочу знать, есть ли простой способ в консоли psql, чтобы сделать эти типы операций быстрее.

Например, предположим, у меня есть таблица с именем "orders" с 35 миллионами строк, и я хочу сделать это:

Чтобы не отвлекаться на обсуждение вне форума, давайте предположим, что все значения статуса для 35 миллионов столбцов в настоящее время установлены на одно и то же (ненулевое) значение, что делает индекс бесполезным.

Проблема с этим утверждением состоит в том, что для вступления в силу требуется очень много времени (исключительно из-за блокировки), и все измененные строки блокируются до полного обновления. Это обновление может занять 5 часов, а что-то вроде

может занять 1 минуту. Более 35 миллионов строк, выполнение вышеизложенного и разбивка на 35 частей займет 35 минут и сэкономит мне 4 часа 25 минут.

Я мог бы разбить его еще дальше с помощью скрипта (используя псевдокод здесь):

Эта операция может завершиться всего за несколько минут, а не через 35.

Так что это сводится к тому, что я действительно спрашиваю. Я не хочу писать офигенный сценарий, чтобы ломать операции каждый раз, когда я хочу сделать одноразовое большое обновление, подобное этому. Есть ли способ выполнить то, что я хочу полностью в SQL?

Колонка ряд

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

Любое UPDATE в модель MVCC в PostgreSQL записывает новую версию всей строки . Если параллельные транзакции изменяют какой-либо столбец той же строки, возникают проблемы с параллелизмом, отнимающие много времени. Подробности в руководстве. Знание того же столбца не будет затронуто одновременными транзакциями, избегающими some возможные осложнения, но не другие.

Индекс

Чтобы не отвлекаться на обсуждение вне форума, давайте предположим, что все значения статуса для 35 миллионов столбцов в настоящее время установлены на одно и то же (ненулевое) значение, что делает индекс бесполезным.

При обновлении всей таблицы (или ее основных частей) Postgres никогда не использует индекс . Последовательное сканирование выполняется быстрее, когда необходимо прочитать все или большинство строк. Напротив: поддержка индекса означает дополнительную стоимость для UPDATE .

Спектакль

Например, предположим, у меня есть таблица с именем "orders" с 35 миллионами строк, и я хочу сделать это:

Я понимаю, что вы стремитесь к более общему решению (см. Ниже). Но чтобы ответить на реальный вопрос , задаваемый: это можно решить в без учета миллисекунд независимо от размера таблицы:

Когда столбец добавляется с помощью ADD COLUMN , все существующие строки в таблице инициализируются значением столбца по умолчанию ( NULL , если не указано предложение DEFAULT ). Если предложение DEFAULT отсутствует, это просто изменение метаданных .

Форма DROP COLUMN физически не удаляет столбец, а просто делает его невидимым для операций SQL. Последующие операции вставки и обновления в таблицу сохранят нулевое значение для столбца. Таким образом, удаление столбца происходит быстро, но это не приведет к немедленному уменьшению размера таблицы на диске, поскольку пространство, занимаемое удаленным столбцом, не освобождается. Пространство будет восстановлено с течением времени по мере обновления существующих строк. (Эти операторы не применяются при удалении столбца oid системы; это делается с немедленной перезаписью.)

Убедитесь, что у вас нет объектов в зависимости от столбца (ограничения внешнего ключа, индексы, представления, . ). Вы должны были бы удалить/воссоздать их. За исключением этого, крошечные операции над таблицей системного каталога pg_attribute выполняют свою работу. Требуется эксклюзивная блокировка на столе, что может быть проблемой при большой одновременной нагрузке. Так как это займет всего несколько миллисекунд, у вас все должно быть в порядке.

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

Общее решение

dblink было упомянуто в другом ответе. Это позволяет получить доступ к "удаленным" базам данных Postgres в неявных отдельных подключениях. "Удаленная" база данных может быть текущей, тем самым достигая "автономных транзакций" : то, что записывает функция в "удаленной" БД, фиксируется и не может быть откатано.

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

Если у вас нет одновременного доступа, это вряд ли полезно - за исключением исключения ROLLBACK после исключения. Также рассмотрите SAVEPOINT для этого случая.

Отказ

Во-первых, множество мелких транзакций на самом деле дороже. Это имеет смысл только для больших таблиц . Сладость зависит от многих факторов.

Если вы не уверены в том, что вы делаете: , безопасным методом является одна транзакция . Чтобы это работало должным образом, параллельные операции на столе должны совпадать. Например: concurrent write может переместить строку в раздел, который предположительно уже обработан. Или одновременное чтение может увидеть противоречивые промежуточные состояния. Вы были предупреждены.

Пошаговые инструкции

Сначала необходимо установить дополнительный модуль dblink:

Настройка соединения с dblink очень сильно зависит от настройки кластера БД и действующих политик безопасности. Это может быть сложно. Связанный позже ответ с более , как связаться с dblink :

Создайте FOREIGN SERVER и USER MAPPING в соответствии с инструкциями, чтобы упростить и упростить соединение (если у вас его нет).
Предполагая serial PRIMARY KEY с или без некоторых пробелов.

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

PostgreSQL, как сказано на её официальном сайте, это самая продвинутая в мире реляционная база данных с открытым исходным кодом.

Использование PostgreSQL

Как запустить службу PostgreSQL. Как управлять службой PostgreSQL

Запуск службы PostgreSQL:

Остановка службы PostgreSQL:

Добавление службы PostgreSQL в автозагрузку:

Удаление службы PostgreSQL из автозагрузки:

Для просмотра состояния процесса PostgreSQL:

Альтернативный вариант запуска службы для работы с определённой базой данных следующий:

Как узнать, какая версия PostgreSQL запущена

Версию запущенной PostgreSQL не всегда можно определить по установленным пакетам. Например, во время обновления PostgreSQL на некоторых дистрибутивах не заменяет предыдущую версию, а устанавливает новую в дополнении к имеющейся. Иногда у пользователя в корпоративной среде есть доступ через Navicat или phpPgAdmin, но нет доступа к консоли сервера, на котором работает база данных.

Для определения версии сервера выполните команду:


Для определения версии клиента:


Ещё один вариант определения версии PostgreSQL:


Если вам нужен только номер версии (например, для скрипта), то используйте следующую команду:

Хотя вместо postgres можно использовать postmaster, использование postgres предпочтительнее, поскольку postmaster это устаревший псевдоним для postgres.

Если вы предпочитаете вариант с SQL, то подключитесь к интерактивному терминалу:

Также вам может пригодиться один из следующих вариантов


Как инициализировать базу данных PostgreSQL

Остановите службу, если она запущена:

Директория /var/lib/postgres/ должна принадлежать пользователю postgres:

Смените пользователя на postgres:

Выполните инициализацию БД:

Если вы столкнулись с ошибкой:

То найдите расположение файла initdb:

И укажите до него полный путь в команде инициализации:

Нажмите CTRL+D

Запустите службу PostgreSQL:

Создайте нового пользователя (например, user):

При желании, вы можете установить пароль для пользователя, это делается командой с ключом -W:

Создайте базу данных (например, my-first-db):

Как подключиться к локальному серверу PostgreSQL

Для подключения к интерактивному терминалу PostgreSQL используется команда psql.

Примеры синтаксиса команд:

Для psql требуется указать имя пользователя и если он не указан, то пересылается имя текущего пользователя системы, который скорее всего отсутствует в базе данных PostgreSQL, что вызывает ошибку. По умолчанию создаётся пользователь postgres, поэтому без дополнительной настройке вы можете подключиться к серверу PostgreSQL следующим образом:

Какой конфигурационный файл использует PostgreSQL

Конфигурационный файл PostgreSQL носит имя postgresql.conf.

В системе может быть несколько конфигурационных файлов PostgreSQL. Вы можете найти их командой:

Что особенно важно, systemd может использовать свои собственные конфигурационные файлы, например:

  • /usr/lib/systemd/system/postgresql@.service.d/kali_postgresql.conf (путь в Kali Linux)
  • /usr/lib/sysusers.d/postgresql.conf (путь в Arch Linux)

Если вы настраиваете PostgreSQL, но после перезапуска службы с помощью systemd (systemctl) изменения не применяются, возможно, вы просто редактируете неверный файл.

Также конфигурационный файл имеется в директории с базой данных, например:

  • /var/lib/postgres/data/postgresql.conf

С пакетом PostgreSQL могут поставляться образцы конфигурационных файлов, например:

  • /usr/share/postgresql/14/postgresql.conf.sample
  • /usr/share/postgresql/postgresql.conf.sample

Как обновить базу данных PostgreSQL при переходе на новую версию


Оно означает, что в системе 2 установленные версии PostgreSQL:

Если запустить службу PostgreSQL командой:

И проверить версию командой:

То будет выведено следующее:


То есть по умолчанию используется 13, устаревшая версия.

Удаление старых версий пакетов, например, командой:

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

Последующие действия подразумевают, что вы

1) установили новую версию PostgreSQL, но ещё не использовали её, то есть не сохраняли базы данных, поскольку файлы новой версии будут удалены.

2) хотите перенести старые база данных в новый формат

С помощью следующей команды просмотрите доступные кластеры:


На скриншоте только один из них online (я успел удалить пакет postgresql-13), но у вас оба должны быть online, иначе перенос базы данных не удастся.

Пример правильного вывода:

Как можно увидеть, обе версии 13 и 14 в настоящее время установлены и запущены. Держите в уме, что при переносе старой базы данных в новый формат вам понадобиться двойной объём места на диске, поскольку pg_upgradecluster копирует данные.

Процедура обновления включает в себя следующее:

1. Удаляем данные новой версии:

2. Запускаем процедуру обновления кластера:


3. Когда операция будет завершена, дважды проверьте, что всё работает

4. Удалите старую версию

Это показывает суть обновления кластера. Конечно, в конкретной вашей ситуации могут быть нюансы: другие номера версий, либо другое расположение файлов с базами данных.

Вновь проверяем версию:


Теперь используется 14, то есть самая последняя версия.

В чём разница между postgres и psql

postgres

postgres - это сервер базы данных PostgreSQL. Чтобы клиентское приложение могло получить доступ к базе данных, оно подключается (по сети или локально) к работающему экземпляру postgres. Затем экземпляр postgres запускает отдельный серверный процесс для обработки соединения.

Один экземпляр postgres всегда управляет данными только одного кластера базы данных. Кластер базы данных — это набор баз данных, который хранится в общей папке файловой системы («область данных»). В системе может работать более одного экземпляра postgres одновременно, если они используют разные области данных и разные порты связи. Когда postgres запускается, ему необходимо знать расположение области данных. Местоположение должно быть указано параметром -D или переменной среды PGDATA; по умолчанию это значение не установлено. Обычно -D или PGDATA указывает непосредственно на каталог области данных, созданный initdb.

Чтобы запустить сервер в однопользовательском режиме, используйте такую команду, как

Чтобы запустить postgres в фоновом режиме со значениями по умолчанию, введите:

Чтобы запустить postgres с определенным портом, например, 1234:

Чтобы подключиться к этому серверу с помощью psql, укажите этот порт с параметром -p:

или установите переменную окружения PGPORT:

psql

psql — это интерфейс для PostgreSQL на основе терминала. Он позволяет вам вводить запросы в интерактивном режиме, отправлять их в PostgreSQL и просматривать результаты запросов. В качестве альтернативы ввод может быть из файла или из аргументов командной строки. Кроме того, psql предоставляет ряд мета-команд и различных функций, подобных оболочке, для облегчения написания сценариев и автоматизации широкого спектра задач.

Пример запуска psql:

Запуск psql от пользователя postgres, который создаётся по умолчанию:

Ошибки PostgreSQL

psql: error: не удалось подключиться к серверу: Нет такого файла или каталога

При попытке подключиться к серверу PostgreSQL или выполнить запрос на сервере PostgreSQL, например:

вы можете столкнуться с ошибкой:

В англоязычной версии эта ошибка выглядит так:

Эта ошибка означает, что служба PostgreSQL не запущена, для её запуска выполните команду:

Альтернативный вариант запуска службы следующий:

Другой возможной причиной ошибки может быть то, что psql ищет файл сокета в неверной директории: например, файл сокета помещён в /tmp, а psql ищет его в /run/postgresql/. В этом случае вы можете с помощью опции --host явно указать директорию, в которой находится сокет:

FATAL: не удалось создать файл блокировки "/run/postgresql/.s.PGSQL.5432.lock": Нет такого файла или каталога

При запуске системы БД, например, следующей командой:

Вы можете столкнуться с ошибкой:


В англоязычной версии ошибка выглядит так:

  1. Создать данную директорию (если она отсутствует) и сделать её владельцем пользователя postgres
  2. Отредактировать конфигурационный файл так, чтобы служба пыталась создавать файл блокировки в директории /tmp, на которую у всех пользователей есть право записи

Первый вариант — создаём директорию /run/postgresql/ и назначаем её владельцем пользователя postgres:

Второй вариант — открываем конфигурационный файл postgresql.conf (у вас может быть другое расположение)

И добавляем туда следующую запись:

sudo: postgres: command not found

Если при использовании postgres вы столкнулись с ошибкой:

то у этой проблемы может быть две возможных причины:

1. Не установлен пакет postgresql.

Установите его одной из следующих команд.

В Debian, Kali Linux, Linux Mint, Ubuntu и их производных:

В Arch Linux, Manjaro, BlackArch и их производных:

2. Исполнимый файл postgres находится за пределами $PATH

Это необязательно говорит о проблеме — такой подход может использоваться для возможности иметь на одном компьютере сразу несколько серверов PostgreSQL.

Найдите исполнимый файл


Как можно видеть на скриншоте, исполнимый файл присутствует для двух версий сервера:

  • /usr/lib/postgresql/13/bin/postgres
  • /usr/lib/postgresql/14/bin/postgres

Теперь вместо postgres используйте полный путь в команде запуска, например:

psql: ошибка: ВАЖНО: роль "" не существует

При попытке запуска интерактивного терминала PostgreSQL

Вы можете столкнуться с ошибкой:

Имя пользователя может быть другим — там будет показано имя того пользователя, котоырй пытается выполнить вход.

В англоязычной версии ошибка выглядит так:


Для psql необходимо имя пользователя и если оно не указано явно, то передаётся имя пользователя системы. Но поскольку данный пользователь не существует на сервере PostgreSQL, то возникает указанная выше ошибка.

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

По умолчанию присутствует пользователь postgres, поэтому вы можете подключиться от его имени:

Вы должны указать его расположение в параметре --config-file или -D, либо установить переменную окружения PGDATA

При запуске postgres вы можете столкнуться с ошибкой:


В англоязычной версии:

Суть ошибки в том, что необходимо указать конфигурационный файл в опции командной строки или в переменной окружения. Как вариант — можно указать путь до базы данных, содержащий конфигурационный файл. Например:

Конфигурационный файл называется postgresql.conf, но нужно указать не его, а директорию, в которой он содержится. Например:


initdb: command not found

Смотрите объяснение данной проблемы, а также дополнительные пути устранения в описании аналогичной ошибки: sudo: postgres: command not found

Найдите initdb с помощью:

  • /usr/lib/postgresql/13/bin/initdb
  • /usr/lib/postgresql/14/bin/initdb

И используйте в ваших командах абсолютный путь до файла initdb нужной вам версии, например:

Можно значительно сократить затраты на программное обеспечение, установив сервер 1С на Linux. В данной инструкции мы рассмотрим процесс настройки сервера 1C 8.3 на Ubuntu 18.04 или 20.04 с сервером баз данных (не файловый вариант). В качестве СУБД мы будем использовать PostgreSQL (на примере версий 9.6, 10, 12 и 13).

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

Подготовка системы

Задаем имя сервера

Чтобы сервер 1С мог запуститься без ошибки, необходимо ему задать корректное имя:

Настройка брандмауэра

Для корректной работы сервера, необходимо открыть порты:

  • 1540 и 1541 для сервера 1С.
  • 1560 — запросы к базе данных.

По умолчанию, в Ubuntu действует разрешающая политика и настройка брандмауэра не требуется. В противном случае, вводим команды:

iptables -I INPUT 1 -p tcp --dport 1540:1541 -j ACCEPT

iptables -I INPUT 1 -p tcp --dport 1560 -j ACCEPT

И сохраняем правила с помощью iptables-persistent:

apt-get install iptables-persistent

Установка PostgreSQL

Как было сказано выше, мы задействуем СУБД PostgreSQL. Для 1С требуется специальная сборка postgresql, которая может быть установлена из специального дистрибутива или от поставщика 1С. Рассмотрим установку как версии 9.6, так и 10.

Подготовка к установке СУБД

Настраиваем локаль, введя команду:

В открывшемся окне выбираем локаль ru_RU.UTF-8 UTF-8:

Настройка локали в Ubuntu

Нажимаем OK. В следующем окне также выбираем ru_RU.UTF-8:

Настройка локали в Ubuntu

. и нажимаем OK.

* Если мы устанавливали русскую версию Linux, возможно, данные настройки уже будут выставлены. Так или иначе, стоит в этом убедиться.

Установка PostgreSQL 9.6 из репозитория

PostgreSQL 9.6 для 1С можно установить из репозитория. Для начала, добавим его:

Установим цифровую подпись для репозитория:

Обновляем списки пакетов:

Устанавливаем библиотеку libpq5 версии 9.6, собранной для postgresql под 1С:

apt-get install libpq5=9.6.*.1C.bionic

Выполняем установку самого PostgreSQL:

apt-get install postgresql-pro-1c-9.6

Установка PostgreSQL 10 от 1С

Сначала устанавливаем компоненты, необходимые для установки СУБД из пакетов.

dpkg -i libicu55_55.1-7_amd64.deb

* libicu55 — Unicode-компоненты для интернационализации.

Теперь устанавливаем postgresql-common:

apt-get install postgresql-common

* postgresql-common позволяет одновременную установку нескольких версий PostgreSQL.

Устанавим пакет libssl:

* если команда вернет ошибку, точное название для новой версии libssl смотрим, перейдя по ссылке.

dpkg -i libssl1.0.0_1.0.2n-1ubuntu5.4_amd64.deb

Переходим к установки самой СУБД. 10-я версия PostgreSQL может быть установлена из дистрибутива, полученного от 1С (в личном кабинете или от поставщика). Архив с дистрибутивом postgresql, в свою очередь, содержит архивы под различные операционные системы — нам нужен файл с окончанием в названии . amd64_deb.tar.bz2

* в данном примере взят файл для 64-х разрядной версии операционной системы. Пакет deb (для систем на базе Debian).

Копируем данный файл на сервер (например, с помощью программы WinSCP) и распаковываем его:

tar jxvf PostgreSQL_10.*.1C_postgresql_10.*.1C_amd64_deb.tar.bz2

Выполним установку пакетов из папки . amd64_deb.

dpkg -i postgresql-10.*.1C_amd64_deb/*.deb

sudo -u postgres /usr/lib/postgresql/10/bin/initdb -D /var/lib/postgresql/10/main --locale=ru_RU.UTF-8

* при инициализации для нас важно задать русскую локаль. В противном случае мы можем получить ошибку «Порядок сортировки не поддерживается базой данных».

Установка PostgreSQL 12 от 1С

Устанавим пакет libssl:

* если команда вернет ошибку, точное название для новой версии libssl смотрим, перейдя по ссылке.

dpkg -i libssl1.0.0_1.0.2n-1ubuntu5.4_amd64.deb

apt-get install libllvm6.0

Распаковываем архив с postgresql:

tar jxvf postgresql_12.*.1C_amd64_deb.tar.bz2

Устанавливаем по очереди

dpkg -i postgresql-12.*.1C_amd64_deb/libpq5_12.*.1C_amd64.deb

dpkg -i postgresql-12.*.1C_amd64_deb/postgresql-client-12_12.*.1C_amd64.deb

dpkg -i postgresql-12.*.1C_amd64_deb/postgresql-12_12.*.1C_amd64.deb

sudo -u postgres /usr/lib/postgresql/12/bin/initdb -D /var/lib/postgresql/12/main --locale=ru_RU.UTF-8

* при инициализации для нас важно задать русскую локаль. В противном случае мы можем получить ошибку «Порядок сортировки не поддерживается базой данных».

PostgreSQL Pro для 1С

Для работы 1С рекомендуется установить специальный выпуск PostgreSQL Pro. Она также может быть загружена и установлена бесплатно.

Мастер для скачивания Postgresql Pro для 1С

После заполняем форму для получения инструкции по установке СУБД:

Заполняем форму для получения Postgresql

На указанную почту придет инструкция по установке PostgreSQL.

Пример установки PostgreSQL Pro 13. Скачиваем скрипт для установки репозитория:

apt-get install gnupg2

* без данного пакета при попытке установить репозиторий мы получим ошибку:
E: gnupg, gnupg2 and gnupg1 do not seem to be installed, but one of them is required for this operation
Error adding key.

Запускаем скачанный скрипт:

Запускаем установку СУБД:

apt-get install postgrespro-1c-13

systemctl enable postgrespro-1c-13

systemctl stop postgrespro-1c-13

Удаляем содержимое каталога data:

rm -rf /var/lib/pgpro/1c-13/data/*

* в противном случае, при попытке инициализировать базу мы получим ошибку Data directory /var/lib/pgpro/1c-13/data is not empty!

/opt/pgpro/1c-13/bin/pg-setup initdb --tune=1c --locale=ru_RU.UTF-8

Запускаем сервис postgrespro:

systemctl start postgrespro-1c-13

Действия после установки postgres

Если мы установили PostgreSQL Pro версию, выполним только первую настройку.

Пароль для пользователя postgres

Задаем пароль для пользователя postgres:

* данную команду мы запускаем под пользователем postgres; мы задаем пароль password для postgresql-пользователя postgres. Дополнительная команда history -d $((HISTCMD-1)) удалить из истории строку с паролем.

Остальные настройки выполняем для PostgreSQL не Pro версии.

Автозапуск

Разрешаем автозапуск сервиса баз данных и стартуем его:

systemctl enable postgresql --now

Блокировка обновлений PostgreSQL

Так как для 1С устанавливается специальная сборка СУБД, необходимо запретить ее обновление. В противном случае будет установлен обычныйpostgresql, что приведет к потери работоспособности сервера.

Смотрим версию установленного сервера баз данных:

dpkg -l | grep postgresql

ii postgresql-10 10.10-4.1C .
ii postgresql-client-10 10.10-4.1C .
.

И так, у нас установлена версия 10.10-4.1C. Вводим:

* где 10.10-4.1C — версия установленного PostgreSQL. Команда apt-mark hold блокируем установку обновлений для пакетов версии 10.10-4.1C.

apt-mark hold postgresql-common postgresql-client-common

Установка сервера 1С

Для установки сервера 1С необходимо сначала установить вспомогательные пакеты, затем сам сервис. Дистрибутив необходимо скачать с сайта 1С — личного кабинета, доступного по подписке.

И так, выполним установку следующих пакетов:

apt-get install imagemagick unixodbc ttf-mscorefonts-installer

  • imagemagick — набор программ для чтения и редактирования графических файлов.
  • unixodbc — диспетчер драйверов для ODBC.
  • ttf-mscorefonts-installer — набор шрифтов Microsoft.

В процессе установки система запросит принять лицензионное соглашение — выбираем Yes.

Копируем на сервер архив с дистрибутивом для 1С, который был загружен с сайта 1С или получен от поставщика. Распаковываем архив командой:

tar zxvf 8.3.16.1148_deb64.tar.gz

* где 8.3.16.1148_deb64.tar.gz — имя архива с 1С версии 8.3.16. В архиве пакеты deb (для Linux на основе Debian) для 64-х разрядной системы.

Устанавливаем все пакеты, которые находились в архиве командой:

dpkg -i 1c-enterprise*.deb

Разрешаем автозапуск сервиса 1С и стартуем его:

systemctl enable srv1cv83

systemctl start srv1cv83

Необходимо убедиться, что сервис запустился:

systemctl status srv1cv83

Если мы получим ошибку «srv1cv83.service not found», находим исполняемый файл srv1cv83:

find /opt -name srv1cv83

В моем случае он был по пути:

Делаем симлинк в каталоге /etc/init.d на найденный файл:

ln -s /opt/1cv8/x86_64/8.3.16.1148/srv1cv83 /etc/init.d/srv1cv83

Снова запускаем сервис:

systemctl start srv1cv83

Настройка кластера и клиента

На любой компьютер в сети установим толстый клиент 1С:Предприятие той же версии, что и сервер. Во время установки обязательно выбираем компонент Администрирование сервера 1С:Предприятие:

Выбираем компонент Администрирование сервера 1С:Предприятие

Запуск регистрации утилиты администрирования серверов

Теперь запускаем утилиту Администрирование серверов 1С Предприятия:

Запуск регистрации утилиты администрирование серверов 1С Предприятия

В открывшемся окне кликаем правой кнопкой мыши по Central 1C:Enterprise 8.3 servers - выбираем Создать - Центральный сервер 1С:Предприятие 8.3:

Подключаемся к серверу 1С в консоли управления сервером 1С

Пишем имя сервера 1С или его IP-адрес:

Прописываем настройки для подключения к серверу 1С

. и нажимаем OK. В панели управления появится подключение — переходим в раздел Кластеры - Локальный кластер - кликаем правой кнопкой по Информационные базы - выбираем Создать - Информационная база:

Создание новой информационной базы

Заполняем параметры для создания новой базы:

Заполняем настройки для создания информационной базы

* в данном примере нами были заполнены:

  • Имя — задаем произвольное имя для подключения к базе.
  • Сервер баз данных — имя или IP-адрес базы. Задаем localhost, так как в нашем случае сервер 1С и сервер баз данных находятся на одном сервере.
  • Тип СУБД — выбираем PostgreSQL.
  • База данных — имя базы данных.
  • Пользователь сервера БД — пользователь, под которым будет выполняться подключение к базе. В нашем примере postgres.
  • Пароль пользователя БД — пароль для базы, который мы задали после установки СУБД.
  • Создать базу данных в случае ее отсутствия — ставим галочку, чтобы база была создана.

Если мы получим ошибку Этот хост неизвестен:

Ошибка «Этот хост неизвестен»

. необходимо убедиться, что имя сервера разрешается в IP-адрес. Для этого необходимо его добавить в локальную DNS или файл hosts.

База должна создастся. Теперь запускаем 1С клиент и добавляем новую базу - при добавлении выбираем Добавление в список существующей информационной базы:

Добавляем существующую базу в 1С

Указываем произвольное имя информационной базы, а также выбираем тип расположения базы На сервере 1С:Предприятия:

Задаем настройки при создании новой информационной базы в 1С

Нажимаем Далее и Готово. Запускаем конфигуратор, загружаем базу и пользуемся.

HASP Licence manager

Если в сервер вставлен аппаратный ключ, необходимо установить HASP Licence manager, чтобы лицензии могли получать компьютеры по сети.

Проверяем, что наш сервер видит ключ:

lsusb | grep -i hasp

Мы должны увидеть что-то на подобие:

Bus 001 Device 003: ID 0529:0001 Aladdin Knowledge Systems HASP copy protection dongle
Bus 001 Device 002: ID 0529:0001 Aladdin Knowledge Systems HASP copy protection dongle

Устанавливаем необходимые пакеты:

apt-get install make libc6-i386

  • make — утилите, которая в нашем случае используется для компиляция исходного кода.
  • libc6-i386 — набор стандартных библиотек для С и математических вычислений.

Создадим каталог для загрузки пакетов и перейдем в него:

mkdir /tmp/hasp ; cd /tmp/hasp

Переходим на страницу загрузки HASP для Ubuntu. Выбираем необходимую версию и копируем ссылки на 2 файла — haspd-modules_. и haspd_.

На момент обновления инструкции на сайте не было пакетов для Ubuntu 20, однако, для данной версии подходят пакеты под Ubuntu 18.

С помощью скопированных ссылок загружаем на сервер два файла:

* в моем примере загрузка выполнялась для Ubuntu 18.04.

Выполним установку скачанных пакетов командой:

dpkg -i haspd*.deb

Разрешим автозапуск сервиса haspd:

systemctl enable haspd

systemctl start haspd

Проверяем, что он корректно стартовал и работает:

systemctl status haspd

Готово — наши компьютеры в локальной сети смогут получить лицензию.

Миграция базы на PostgreSQL

В случае, если это не первая установка и у нас уже есть база, ее нужно перенести на новый сервер. Рассмотрим 2 варианта — база была на другом сервере PostgreSQL и универсальный (файловый вариант или другая СУБД).

С PostgreSQL на PostgreSQL

В данном случае процесс переноса заключается в создании дампа (backup) и его восстановления на новом сервере (restore). Необходимо учесть, что для корректного переноса данных, версии 1С должны совпадать.

Есть несколько инструментов по созданию резервных копий PostgreSQL и их восстановлению. Их описание выходит за рамки данной статьи — подробнее читайте инструкцию Резервное копирование PostgreSQL.

Универсальный способ миграции на PostgreSQL

Данный способ также подойдет и для миграции с PostgreSQL на PostgreSQL. Для начала, открываем нашу базу в конфигураторе на старом 1С - кликаем по Администрирование - Выгрузить информационную базу:

Выгружаем информационную базу

Выбираем путь для сохранения файла. Ждем окончания выгрузки и переносим полученный файл на компьютер с толстым клиентом 1С (если для нового сервера мы используем другой компьютер с 1С).

Открываем конфигуратор для созданной в PostgreSQL базы - кликаем Администрирование - Загрузить информационную базу:

Загружаем информационную базу

. и выбираем выгруженный ранее файл. Дожидаемся его загрузки - система потребует перезапустить 1С - соглашаемся. Ждем новой загрузки. После можно пользоваться базой 1С на новом сервере.

Веб-публикации

Сервер 1С поддерживает возможность веб-публикаций баз 1С. Это дает возможность открывать программу в браузере или мобильном приложении. В Linux данные публикации осуществляются с помощью Apache.

Установка и запуск Apache

Первым делом, устанавливаем веб-сервер apache:

apt-get install apache2

Разрешаем автозапуск веб-сервера и стартуем сам сервис:

systemctl enable apache2

systemctl start apache2

Стартовая страница Apache

Публикация 1С на веб-сервере

Публикация базы выполняется с помощью скрипта webinst, который устанавливается с сервером. Для простоты, мы опубликуем базу в корневую директорию /var/www/html, но при желании, можно настроить виртуальные домены.

И так, создадим каталог, в который опубликуем нашу базу:

Переходим в каталог с установленным 1С:

* где 8.3.16.1148 — версия установленной платформы.

Заускаем скрипт для публикации базы:

./webinst -apache24 -wsdir test -dir /var/www/html/test -connstr "Srvr=192.168.1.11;Ref=test;" -confPath /etc/apache2/apache2.conf

* где apache24 — версия установленного apache; test — имя нашей базы, которую мы создали ранее; /var/www/html/test — путь до каталога на сервере, в котором будет опубликована база; 192.168.1.11 — IP-адрес сервера 1С; Ref=test — имя базы в СУБД; /etc/apache2/apache2.conf — путь до конфигурационного файла apache.

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

В этом цикле мы поговорим о блокировках (locks). Я буду придерживаться этого термина, но в литературе может встретиться и другой: замóк.

Цикл будет состоять из четырех частей:

  1. Блокировки отношений (эта статья); ; и предикатные блокировки; .
    , как ее понимают стандарт и PostgreSQL; — что творится на физическом уровне; ; ; ; (vacuum); (autovacuum); .
    ; — как устроен и как используется при восстановлении; и фоновая запись — зачем нужны и как настраиваются; — уровни и решаемые задачи, надежность и производительность.



В PostgreSQL используется множество самых разных механизмов, которые служат для блокировки чего-либо (или по крайней мере так называются). Я поэтому начну с самых общих слов о том, зачем вообще нужны блокировки, какие они бывают и чем отличаются друг от друга. Затем мы посмотрим, что из этого разнообразия встречается в PostgreSQL и только после этого начнем разбираться с разными видами блокировок подробно.

Блокировки используются, чтобы упорядочить конкурентный доступ к разделяемым ресурсам.

Под конкурентным доступом понимается одновременный доступ нескольких процессов. Сами процессы могут при этом выполняться как параллельно (если позволяет аппаратура), так и последовательно в режиме разделения времени — это не важно.

Если нет конкуренции, то нет нужды и в блокировках (например, общий буферный кеш требует блокировок, а локальный – нет).

Перед тем, как обратиться к ресурсу, процесс обязан захватить (acquire) блокировку, ассоциированную с этим ресурсом. То есть речь идет об определенной дисциплине: все работает до тех пор, пока все процессы выполняют установленные правила обращения к разделяемому ресурсу. Если блокировками управляет СУБД, то она сама следит за порядком; если блокировки устанавливает приложение, то эта обязанность ложится на него.

На низком уровне блокировка представляется участком разделяемой памяти, в котором некоторым образом отмечается, свободна ли блокировка или захвачена (и, возможно, записывается дополнительная информация: номер процесса, время захвата и т. п.).

Можно заметить, что такой участок разделяемой памяти сам по себе является ресурсом, к которому возможен конкурентный доступ. Если спуститься на уровень ниже, мы увидим, что для упорядочения доступа используются специальные примитивы синхронизации (такие, как семафоры или мьютексы), предоставляемые ОС. Смысл их в том, чтобы код, обращающийся к разделяемому ресурсу, одновременно выполнялся только в одном процессе. На самом низком уровне эти примитивы реализуются на основе атомарных инструкций процессора (таких, как test-and-set или compare-and-swap).

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

Конечно, захват блокировки возможен не всегда: ресурс может оказаться уже занятым кем-то другим. Тогда процесс либо встает в очередь ожидания (если механизм блокировки дает такую возможность), либо повторяет попытку захвата блокировки через определенное время. Так или иначе это приводит к тому, что процесс вынужден простаивать в ожидании освобождения ресурса.

Иногда удается применить другие, неблокирующие, стратегии. Например, механизм многоверсионности позволяет нескольким процессам в ряде случаев работать одновременно с разными версиями данных, не блокируя друг друга.

Защищаемым ресурсом в принципе может быть все, что угодно, лишь бы этот ресурс можно было однозначно идентифицировать и сопоставить ему адрес блокировки.

Например, ресурсом может быть объект, с которым работает СУБД, такой как страница данных (идентифицируется именем файла и позицией внутри файла), таблица (oid в системном каталоге), табличная строка (страница и смещение внутри страницы). Ресурсом может быть структура в памяти, такая как хеш-таблица, буфер и т. п. (идентифицируется заранее присвоенным номером). Иногда даже бывает удобно использовать абстрактные ресурсы, не имеющие никакого физического смысла (идентифицируются просто уникальным числом).

На эффективность блокировок оказывают влияние много факторов, из которых выделим два.

    Гранулярность (степень детализации) важна, если ресурсы образуют иерархию.

Например, таблица состоит из страниц, которые содержат табличные строки. Все эти объекты могут выступать в качестве ресурсов. Если процессы обычно заинтересованы всего в нескольких строках, а блокировка устанавливается на уровне таблицы, то другие процессы не смогут одновременно работать с разными строками. Поэтому чем выше гранулярность, тем лучше для возможности распараллеливания.

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

Блокировки на уровне объектов относятся к длительным, «тяжеловесным». В качестве ресурсов здесь выступают отношения и другие объекты. Если слово блокировка встречается в тексте без уточнений, то оно обозначает именно такую, «обычную» блокировку.

Среди длительных блокировок отдельно выделяются блокировки на уровне строк. Их реализация отличается от остальных длительных блокировок из-за потенциально огромного их количества (представьте обновление миллиона строк в одной транзакции). Такие блокировки будут рассмотрены в следующей статье.

Третья статья цикла будет посвящена оставшимся блокировкам на уровне объектов, а также предикатным блокировкам (поскольку информация о всех этих блокировках хранится в оперативной памяти однотипным образом).

К коротким блокировкам относятся различные блокировки структур оперативной памяти. Их мы рассмотрим в последней статье цикла.

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

Расплывчатая формулировка? Так и есть, потому что блокировки из этой группы используются для самых разных целей. Объединяет их лишь то, как они устроены.

Устройство

Блокировки объектов располагаются в общей памяти сервера. Их количество ограничено произведением значений двух параметров: max_locks_per_transaction × max_connections.

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

Все блокировки можно посмотреть в представлении pg_locks.

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

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

Типы объектов

Вот список типов блокировок (или, если угодно, типов объектов), с которыми мы будем иметь дело в этой и следующей статьях. Названия приведены в соответствии со столбцом locktype представления pg_locks.

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


Режимы

Если не самая важная, то уж точно самая «развесистая» блокировка — блокировка отношений. Для нее определено целых 8 различных режимов. Такое количество нужно для того, чтобы как можно большее количество команд, относящихся к одной таблице, могло выполняться одновременно.

Нет никакого смысла учить эти режимы наизусть или пытаться вникнуть в смысл их названий; главное — иметь в нужный момент перед глазами матрицу, которая показывает, какие блокировки конфликтуют друг с другом. Для удобства она воспроизведена здесь вместе с примерами команд, которые требуют соответствующие уровни блокировки:

режим блокировки AS RS RE SUE S SRE E AE пример
Access Share X SELECT
Row Share X X SELECT FOR UPDATE/SHARE
Row Exclusive X X X X INSERT, UPDATE, DELETE
Share Update Exclusive X X X X X VACUUM, ALTER TABLE * , СREATE INDEX CONCURRENTLY
Share X X X X X CREATE INDEX
Share Row Exclusive X X X X X X CREATE TRIGGER, ALTER TABLE *
Exclusive X X X X X X X REFRESH MAT. VIEW CONCURRENTLY
Access Exclusive X X X X X X X X DROP, TRUNCATE, VACUUM FULL, LOCK TABLE, ALTER TABLE * , REFRESH MAT. VIEW
  • Первые 4 режима допускают одновременное изменение данных в таблице, а следующие 4 — нет.
  • Первый режим (Access Share) — cамый слабый, он совместим с любым другим, кроме последнего (Access Exclusive). Этот последний режим — монопольный, он не совместим ни с одним режимом.
  • Команда ALTER TABLE имеет много вариантов, разные из которых требуют разных уровней блокировки. Поэтому в матрице эта команда появляется в разных строках и отмечена звездочкой.

Для примера например

приведем такой пример. Что произойдет, если выполнить команду CREATE INDEX?

Находим в документации, что эта команда устанавливает блокировку в режиме Share. По матрице определяем, что команда совместима сама с собой (то есть можно одновременно создавать несколько индексов) и с читающими командами. Таким образом, команды SELECT продолжат работу, а вот команды UPDATE, DELETE, INSERT будут заблокированы.

И наоборот — незавершенные транзакции, изменяющие данные в таблице, будут блокировать работу команды CREATE INDEX. Поэтому и существует вариант команды — CREATE INDEX CONCURRENTLY. Он работает дольше (и может даже упасть с ошибкой), зато допускает одновременное изменение данных.

В сказанном можно убедиться и на практике. Для экспериментов мы будем использовать знакомую по первому циклу таблицу «банковских» счетов, в которой будем хранить номер счета и сумму.


Во втором сеансе начнем транзакцию. Нам понадобится номер обслуживающего процесса.


Какие блокировки удерживает только что начавшаяся транзакция? Смотрим в pg_locks:


Как я уже говорил, транзакция всегда удерживает исключительную (ExclusiveLock) блокировку собственного номера, а данном случае — виртуального. Других блокировок у этого процесса нет.

Теперь обновим строку таблицы. Как изменится ситуация?

Теперь появились блокировки изменяемой таблицы и индекса (созданного для первичного ключа), который используется командой UPDATE. Обе блокировки взяты в режиме RowExclusiveLock. Кроме того, добавилась исключительная блокировка настоящего номера транзакции (который появился, как только транзакция начала изменять данные).

Теперь попробуем в еще одном сеансе создать индекс по таблице.


Команда «подвисает» в ожидании освобождения ресурса. Какую именно блокировку она пытается захватить? Проверим:


Видим, что транзакция пытается получить блокировку таблицы в режиме ShareLock, но не может (granted = f).

Находить номер блокирующего процесса, а в общем случае — несколько номеров, удобно с помощью функции, которая появилась в версии 9.6 (до того приходилось делать выводы, вдумчиво разглядывая все содержимое pg_locks):


И затем, чтобы разобраться в ситуации, можно получить информацию о сеансах, к которым относятся найденные номера:


После завершения транзакции блокировки снимаются и индекс создается.

В очередь.

Чтобы лучше представить, к чему приводит появление несовместимой блокировки, посмотрим, что произойдет, если в процессе работы системы выполнить команду VACUUM FULL.

Пусть вначале на нашей таблице выполняется команда SELECT. Она получает блокировку самого слабого уровня Access Share. Чтобы управлять временем освобождения блокировки, мы выполняем эту команду внутри транзакции — пока транзакция не окончится, блокировка не будет снята. В реальности таблицу могут читать (и изменять) несколько команд, и какие-то из запросов могут выполняться достаточно долго.


Затем администратор выполняет команду VACUUM FULL, которой требуется блокировка уровня Access Exclusive, несовместимая ни с чем, даже с Access Share. (Такую же блокировку требует и команда LOCK TABLE.) Транзакция встает в очередь.

Но приложение продолжает выдавать запросы, и вот в системе появляется еще команда SELECT. Чисто теоретически она могла бы «проскочить», пока VACUUM FULL ждет, но нет — она честно занимают место в очереди за VACUUM FULL.

После того, как первая транзакция с командой SELECT завершается и освобождает блокировку, начинает выполняться команда VACUUM FULL (которую мы сымитировали командой LOCK TABLE).


И только после того, как VACUUM FULL завершит свою работу и снимет блокировку, все накопившиеся в очереди команды (SELECT в нашем примере) смогут захватить соответствующие блокировки (Access Share) и выполниться.

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

Безусловно, блокировки необходимы для корректной работы, но могут приводить к нежелательным ожиданиям. Такие ожидания можно отслеживать, чтобы разобраться в их причине и по возможности устранить (например, изменив алгоритм работы приложения).

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


Значение параметра deadlock_timeout по умолчанию равно одной секунде:

Вторая команда UPDATE ожидает блокировку. Подождем секунду и завершим первую транзакцию.

Читайте также: