Введение
Цель: Построить отказоустойчивый кластер базы данных для 1С на основе PostgreSQL
Что мы имеем: 2 одинаковых сервера с конфигурацией:
1 2 3 |
Дисковый массив - 18 гиг для системы, 18 гиг для файл подкачки, ~ 280 гиг для базы данных Оперативная память - 8 гиг Процессор - 2 * AMD Apteron 2.2 ггц |
dbnode1 — имя 1 узла кластера
dbnode2 — имя 2 узла кластера
После установки базовой системы Ubuntu, сетевые интерфейсы будут выглядеть так
dbnode1:
1 2 |
eth0 192.168.30.52/24 gw 192.168.30.1 eth1 10.0.0.1/24 |
dbnode2:
1 2 |
eth0 192.168.30.72/24 gw 192.168.30.1 eth1 10.0.0.2/24 |
Настройка Ubuntu
Послу установки необходимо обновить систему
1 2 |
aptitude update aptitude full-upgrade |
И установить необходимые для работы пакеты
1 |
apt-get install mc ssh console-cyrillic libxslt1.1 drbd8-utils heartbeat-2 libreadline5 |
Настройка DRBD
Перед настройкой DRBD нужно убедится, что никаких разделов на 280 гиговом разделе (sdb не создано) Посмотреть можно командой fdisk -l /dev/sdb
1 2 3 4 5 6 7 8 |
root@dbnode2:~# fdisk -l /dev/sdb Disk /dev/sdb: 293.9 GB, 293995544576 bytes 255 heads, 63 sectors/track, 35742 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x00000000 Disk /dev/sdb doesn't contain a valid partition table |
Если какие-то разделы присудствуют, то необходимо отчистить диск такой командой
1 |
dd if=/dev/zero of=/dev/sdb bs=1M count=1 |
Конфиг DRBD /etc/drbd.conf
Приводим его к такому виду на обоих узлах кластера
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 |
resource r0 { protocol C; startup { wfc-timeout 20; degr-wfc-timeout 20; } net { after-sb-1pri violently-as0p; after-sb-2pri violently-as0p; rr-conflict violently; } syncer { rate 100M; } on dbnode1 { device /dev/drbd0; disk /dev/sdb; address 192.168.30.52:7792; meta-disk internal; } on dbnode2 { device /dev/drbd0; disk /dev/sdb; address 192.168.30.72:7792; meta-disk internal; } } |
Чтобы избежать проблем с разименовыванием узлов кластера, необходимо добавить записи о dbnode1 и dbnode2 в dns-сервер
Или прописать в файл /etc/hosts
1 2 3 |
127.0.0.1 localhost localhost.localdomain 192.168.30.52 dbnode1 dbnode1.cisural.local 192.168.30.72 dbnode2 dbnode2.cisural.local |
Запуск синхронизации
Останавливаем службу DRBD на обоих узлах кластера
1 |
/etc/init.d/drbd stop |
Выполняем инициализацию дисков в DRBD на обоих узлах кластера.
1 2 3 |
modprobe drbd drbdadm create-md all /etc/init.d/drbd start |
Выбирем один главный узел, с которого будем выполнять синхронизацию и выполним на нем команду:
1 |
drbdsetup /dev/drbd0 primary -o |
Дальше пойдет синхронизация дисков, будет она идти очень долго. 200 гигабайт, часа за 3
Смотреть за процессом можно одним из удобных вам способом. Третий способ удобнее всего
1 2 3 |
/etc/init.d/drbd status cat /proc/drbd watch cat /proc/drbd |
После синхронизации необходимо отформатировать диск.
Форматирование
Теперь устройства sdb не используем, иначе синхронизация не будет работать. Используем только устройство drbd
1 |
mke2fs -j /dev/drbd0 |
Heartbeat
Создадим каталог /cluster на обоих узлах кластера
1 |
mkdir /cluster |
Работаем с 3 файлами конфигурации
/etc/ha.d/authkeys — файл авторизации кластеров
/etc/ha.d/ha.cf — файл настройка кластера
/etc/ha.d/haresources — файл с настройками ресурсов кластера
/etc/ha.d/authkeys
/etc/ha.d/authkeys — одинаковый на обоих узлах
1 2 |
auth 1 1 crc |
/etc/ha.d/haresources
/etc/ha.d/haresources — одинаковый на обоих узлах (даже имя компьютера, должно быть одно и то же, опеределяет, кто будет главный)
1 2 |
dbnode1 drbddisk::r0 IPaddr::192.168.30.202/24/eth0/ Filesystem::/dev/drbd0::/cluster::ext3 pgsql cron dbnode1 MailTo::79126862978@sms.ural.mts.ru |
/etc/ha.d/ha.cf
/etc/ha.d/ha.cf — изменяем ип для каждого нода. Ип прописываем нода, которого будем пинговать (на нод1 пишем ип нод2 и наоборот)
1 2 3 4 5 6 7 |
ucast eth0 192.168.30.52 node dbnode1 node dbnode2 warntime 3 deadtime 10 initdead 30 keepalive 2 |
/etc/ha.d/resource.d/pgsql
/etc/ha.d/resource.d/pgsql — Скрипт для запуска службы postgresql (делаем на обоих узлах)
1 2 |
touch /etc/ha.d/resource.d/pgsql chmod +x /etc/ha.d/resource.d/pgsql |
И вставить этот код в него
1 |
nano /etc/ha.d/resource.d/pgsql |
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 |
#!/bin/sh -e PGVERSION=8.3.8 PGMAJORVERSION=`echo "$PGVERSION" | sed 's/^\([0-9]*\.[0-9]*\).*$/\1/'` PGENGINE=/usr/bin PGPORT=5432 PGDATA=/cluster/var/lib/pgsql/data LC_ALL=ru_RU.UTF-8 SU=su PGLOG=/cluster/var/lib/pgsql/pgstartup.log SERVNAME=postgresql NAME=postgresql start(){ $SU -s /bin/sh -l postgres -c "$PGENGINE/postmaster -p '$PGPORT' -D '$PGDATA' ${PGOPTS} &" >> "$PGLOG" 2>&1 < /dev/null sleep 2 pid=`pidof -s "$PGENGINE/postmaster"` if [ $pid ] && [ -f "$PGDATA/postmaster.pid" ] then if [ -d /var/lock/subsys ] ; then touch /var/lock/subsys/${NAME} else mkdir -p /var/lock/subsys touch /var/lock/subsys/${NAME} fi head -n 1 "$PGDATA/postmaster.pid" > "/var/run/postmaster.${PGPORT}.pid" fi } stop(){ $SU -l -s /bin/sh -c "$PGENGINE/pg_ctl stop -D $PGDATA -m fast" postgres > /dev/null 2>&1 < /dev/null rm -f /var/run/postmaster.${PGPORT}.pid > /dev/null 2>&1 rm -f /var/lock/subsys/${NAME} > /dev/null 2>&1 rm -f $PGDATA/postmaster.pid > /dev/null 2>&1 echo } restart(){ stop start } reload(){ if [ -e /var/lock/subsys/${NAME} ] ; then $SU -l -s /bin/sh -c "$PGENGINE/pg_ctl reload -D '$PGDATA' -s" postgres > /dev/null 2>&1 < /dev/null fi } status() { $SU -l -s /bin/sh -c "$PGENGINE/pg_ctl status -D '$PGDATA' -s" postgres } case "$1" in start) echo "* Starting PostgreSQL server ..." start return 0 ;; stop) echo "* Stoping service PostgreSQL ..." stop return 0 ;; status) status return 0 ;; restart) restart return 0 ;; reload|force-reload) reload return 0 ;; *) echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}" exit 1 esac exit 0 |
PostgreSQL
Установка PostgreSQL
Скачиваем и устанавливаем postgresql
На обоих узлах кластера
1 2 3 4 5 6 7 8 |
mkdir /root/postgresql cd /root/postgresql wget ftp://updates.etersoft.ru/pub/Etersoft/Postgre@Etersoft/stable/x86_64/Ubuntu/10.04/libpq5.2-8.4eter_8.4.4-eter1.1ubuntu_amd64.deb wget ftp://updates.etersoft.ru/pub/Etersoft/Postgre@Etersoft/stable/x86_64/Ubuntu/10.04/postgresql-8.4eter-contrib_8.4.4-eter1.1ubuntu_amd64.deb wget ftp://updates.etersoft.ru/pub/Etersoft/Postgre@Etersoft/stable/x86_64/Ubuntu/10.04/postgresql-8.4eter-server_8.4.4-eter1.1ubuntu_amd64.deb wget ftp://updates.etersoft.ru/pub/Etersoft/Postgre@Etersoft/stable/x86_64/Ubuntu/10.04/postgresql-8.4eter_8.4.4-eter1.1ubuntu_amd64.deb dpkg -i postgresql-8.3* Сейчас эти ссылки недоступны но процедура установки и настройки остается такой же. Заходим на их фтп сервер и скачиваем необходимый нами пакет. |
Убераем из автозапуска службы, их будет запускать heartbeat
1 2 |
update-rc.d -f postgresql remove update-rc.d -f cron remove |
Настройка системы для запуска postgresql
Значение 8589934592 — это объем оперативной памяти в байтах
- Настройка файла /etc/sysctl.conf
1 2 3 |
echo "kernel.shmmax = 8589934592" >> /etc/sysctl.conf echo "kernel.shmall = 8589934592" >> /etc/sysctl.conf sysctl -p |
- Проверяем, примонтирован ли каталог /cluster на главном узле кластера
1 |
mount |
Если в выводе есть такая строчка, значит каталог уже примонтирован
1 |
/dev/drbd0 on /cluster type ext3 (rw) |
Если нету, то на главном узле кластера выполняем команду
1 |
mount /dev/drbd0 /cluster |
На главном узле кластера слудующие действия
- Переносим каталок /var/lib/pgsql в каталог /cluster, который синхронизируется по сети
1 2 3 |
mkdir /cluster/var/lib/pgsql -p chown postgres:postgres /cluster/var/lib/pgsql -R cp -R /var/lib/pgsql /cluster/var/lib/pgsql |
На обоих узлах кластера
Заходим в /etc/init.d/postgresql и приводим к такому виду 2 переменные
1 2 3 4 5 |
PGDATA=/cluster/var/lib/pgsql/data ... PGLOG=/cluster/var/lib/pgsql/pgstartup.log |
На главном узле кластера
Запускаем службу
1 |
/etc/init.d/postgresql start |
- Создаем пользователя и пароль PostgreSQL
Заходим в файл /cluster/var/lib/pgsql/data/pg_hba.conf
Ищем строчку:
1 |
host all all 0.0.0.0/0 md5 |
Меняем ее на такую, для того чтобы пускало всех и без авторизации. У нас же нету еще пользователей
1 |
host all all 0.0.0.0/0 trust |
Перезапускаем службу
1 |
/etc/init.d/postgresql restart |
Теперь создаем пользователя
1 2 |
psql -h localhost -U postgres template1 template1=# ALTER USER postgres WITH PASSWORD 'secret'; |
Мы только что создали пользователя postgres с паролем secret
Теперь необходимо закрыть доступ всем без авторизации, для этого заходим в файл /var/lib/pgsql/data/pg_hba.conf
Ищем строчку:
1 |
host all all 0.0.0.0/0 trust |
Меняем ее на такую, для того чтобы пускало только с авторизацией
1 |
host all all 0.0.0.0/0 md5 |
Перезапускаем службу
1 |
/etc/init.d/postgresql restart |
Система готова к работе
Перезагружаемся и проверяем все ли работает
ping 192.168.30.202
1 2 3 4 5 6 7 8 9 |
Обмен пакетами с 192.168.30.202 по 32 байт: Ответ от 192.168.30.202: число байт=32 время<1мс TTL=64 Ответ от 192.168.30.202: число байт=32 время<1мс TTL=64 Ответ от 192.168.30.202: число байт=32 время<1мс TTL=64 Ответ от 192.168.30.202: число байт=32 время<1мс TTL=64 Статистика Ping для 192.168.30.202: Пакетов: отправлено = 4, получено = 4, потеряно = 0 (0% потерь), Приблизительное время приема-передачи в мс: Минимальное = 0мсек, Максимальное = 0 мсек, Среднее = 0 мсек |
По ssh заходим на 192.168.30.52 и проверяем что примонтирован каталог /cluster
1 2 |
mount /dev/drbd0 on /cluster type ext3 (rw) |
Смотрим ifconfig, и проверяем что появился интерфейс eth0:0
1 2 3 4 |
eth0:0 Link encap:Ethernet HWaddr 00:40:F4:98:77:C5 inet addr:192.168.30.201 Bcast:192.168.30.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 Interrupt:177 Base address:0x4c00 |
И смотрим что запущем процесс postgresql
1 |
ps ax |grep postmaster |
Решение проблем
- 1с спрашивает английскую локаль, но зовет он её неправильным именем — «en_US», и возникает ошибка: «lc_messages en_US»
А в убунте нет локали с таким именем, поэтому мы сделаем символьные ссылки на правильные имена На обоих узлах кластера:
1 2 |
ln -s /usr/lib/locale/en_US.utf8/ /usr/lib/locale/en_US ln -s /usr/share/locale/en_US.UTF-8/ /usr/share/locale/en_US |