Имеется Astra Linux 1.3, PostgreSQL 9.1.6, Ansible 2.9.16
В инстансе базы данных неожиданно перестали создаваться таблицы.
Создание таблицы приводит к ошибке:
- name: Create a new database impulse
postgresql_db:
name: impulse
encoding: UTF-8
lc_collate: ru_RU.UTF-8
lc_ctype: ru_RU.UTF-8
owner: impUser
...
FAILED! =>
{"changed": false,
"msg": "Database query failed:
new encoding (UTF8) is incompatible with the encoding
of the template database (SQL_ASCII)\n
ПОДСКАЗКА: Use the same encoding as in
the template database, or use template0 as template.\n"}
Чтобы исправить эту ошибку, необходимо выполнить следующий SQL-скрипт (взят отсюда):
- name: Исправление кодировки шаблона базы данных
postgresql_query:
query: |
update pg_database set datallowconn = TRUE where datname = 'template0';
update pg_database set datistemplate = FALSE where datname = 'template1';
drop database template1;
create database template1 with encoding = 'UTF-8' lc_collate = 'ru_RU.UTF8' lc_ctype = 'ru_RU.UTF8' template = template0;
update pg_database set datistemplate = TRUE where datname = 'template1';
update pg_database set datallowconn = FALSE where datname = 'template0';
Однако выполнение такого плейбука завершается ошибкой:
FAILED! => {"changed": false,
"msg": "Cannot execute SQL 'drop database template1;\n
create database template1 with encoding = 'UTF-8'
lc_collate = 'ru_RU.UTF8' lc_ctype = 'ru_RU.UTF8'
template = template0;\n'
None: DROP DATABASE cannot run inside a transaction block\n"}
То есть, похоже, что Ansible сама заворачивает выполнение SQL-команд в транзакцию. Я нашел тему, что можно принудительно сначала завершить транзакцию, а потом ее открыть. То есть получится, что сначала выполняется пустая транзакция, потом SQL-команды вне транзакции, и потом опять пустая транзакция:
- name: Исправление кодировки шаблона базы данных
postgresql_query:
query: |
end;
update pg_database set datallowconn = TRUE where datname = 'template0';
update pg_database set datistemplate = FALSE where datname = 'template1';
drop database template1;
create database template1 with encoding = 'UTF-8' lc_collate = 'ru_RU.UTF8' lc_ctype = 'ru_RU.UTF8' template = template0;
update pg_database set datistemplate = TRUE where datname = 'template1';
update pg_database set datallowconn = FALSE where datname = 'template0';
begin;
Но тогда появляется другая ошибка:
FAILED! => {
"changed": false,
"msg": "Cannot execute SQL
'end;\n
update pg_database set datallowconn = TRUE where datname = 'template0';\n
update pg_database set datistemplate = FALSE where datname = 'template1';\n
drop database template1;\n
create database template1 with encoding = 'UTF-8' lc_collate = 'ru_RU.UTF8' lc_ctype = 'ru_RU.UTF8' template = template0;\n
update pg_database set datistemplate = TRUE where datname = 'template1';\n
update pg_database set datallowconn = FALSE where datname = 'template0';\n
begin;\n'
None: DROP DATABASE cannot be executed from a function
or multi-command string\n"}
Далее я уже не могу придумать как обходить эти ограничения.
Вопрос: как в Ansible сделать простейшее действие: выполнить несколько SQL-команд?