Сравнительное описание процесса установки и настройки двух популярных СУБД
Сергей Супрунов (amsand@rambler.ru)
В мире свободных программ так повелось: мы говорим «база данных» — подразумеваем «мускуль». А чем нам, спрашивается, не угодила PostgreSQL — открытая (даже более открытая, чем MySQL), свободная, с мощнейшей функциональностью? Кто-то скажет — сложная; кто-то — тяжелая; кто-то — что тормозит. Но всегда ли высокая скорость — самое главное? И правда ли, что поставить ее сложнее, чем совладать с «дельфинчиком»? Вот в этом и попытаемся сегодня разобраться…
Содержание:
- Инсталляция
- Инициализация и настройка
- Кое-что про функциональность
- Итоги
- Врезка: Графические инструменты для работы с СУБД
- Боковые выносы
Для чистоты эксперимента обе СУБД ставить будем из исходников. Если приложение есть в менеджере пакетов твоей системы (мне пока еще не попадались такие, где не было бы MySQL или PostgreSQL), то лучше устанавливать оттуда. Так и с обновлением меньше проблем, и отслеживать зависимости проще — а то попробуй потом какому-нибудь RoundCube докажи, что СУБД у тебя уже есть. Но поскольку «официальная» инсталляция никаких проблем вызвать не должна (скомандовать «aptitude install mysql-server-5.0» или «portinstall postgresql-server» особого труда не составит), то мы пойдем по пути наибольшего сопротивления.
Итак, разжившись архивами с исходным кодом свежих версий (сразу бросается в глаза соотношение по размеру — 24 МБ MySQL 5.0.27 против 10 МБ PostgreSQL 8.2.0; а еще говорят, что постгрес тяжелый), потратим несколько минут на изучение опций конфигурации, чтобы не было потом мучительно больно… Как обычно, полный список доступных опций можно просмотреть, введя в полученном после распаковки тарбола каталоге следующую команду:
$ ./configure --help
В случае с MySQL первое, на что следует обратить внимание — это на кодировку, которую СУБД будет использовать по умолчанию. Поскольку latin1 нас вряд ли устроит, то нужно будет указать опцию ′--with-charset′ в соответствии с твоей кодировкой (скорее всего, это будет koi8r, cp1251 или utf8). Если ты планируешь работать в дальнейшем с несколькими кодовыми страницами, то дополнительные кодировки укажи в опции ′--with-extra-charsets′. Чтобы себя ни в чем не ограничивать, можешь задать сразу ′--with-extra-charsets=all′.
Вторая вещь, не совсем привычная пользователям, работавшим ранее с другими СУБД, — возможность выбрать тип таблиц. MySQL поддерживает целую вереницу различных движков на все случаи жизни: BDB, InnoDB, MyISAM, HEAP… Первые две — Berkeley DB (разработчик — Sleepycat Software, ныне принадлежащий Oracle) и InnoDB (опять-таки, купленный Oracle) — являются транзакционными. Это обеспечивает высокую надежность работы с данными (БД не потеряет согласованность в случае возникновения программного или аппаратного сбоя, и существует возможность восстановить или откатить незавершенные операции) и позволяют объединять логически связанные изменения в БД в атомарные (транзакционные) блоки, фиксирующиеся в базе по принципу «все или ничего». Таблицы MyISAM не поддерживают транзакции, что обеспечивает им более высокую скорость работы, но меньшую надежность. Таблицы HEAP размещаются в оперативной памяти, благодаря чему работают очень быстро, но, естественно, не сохраняют данные при сбоях. С учетом ряда других ограничений, HEAP-таблицы удобно использовать для временных данных, но для «нормальной» работы они мало пригодны.
Если ты точно знаешь, какой тип таблиц тебе нужен, то можно при сборке СУБД указать только их. Обычно в таких случаях рекомендуют использовать MyISAM там, где ради скорости можно пожертвовать всеми данными, и InnoDB для остальных задач.
Перейдем к PostgreSQL. С языками здесь чуть проще — эта СУБД не будет «напрягать» тебя по поводу дефолтных кодировок и т.д. Единственное, что можно сделать, это указать в ′--enable-nls′ перечень языков, на которых система будет с тобой общаться.
А вот над чем можно задуматься — так это над списком языков программирования. Их можно использовать для разработки триггеров, хранимых процедур и прочих прелестей. PostgreSQL поддерживает несколько языков на твой выбор — «из коробки» можно включить поддержку PL/Tcl, PL/Perl и PL/Python вдогонку к стандартному PL/pgSQL; также поддерживаются PHP и Java.
Опции ′--with-krb5′, ′--with-pam′, ′--with-ldap′ позволяют включить поддержку дополнительных способов авторизации, что может быть очень полезно для работы в локальной сети, когда требуется обеспечить предельную гибкость и прозрачность при работе пользователей с базой. Также подумай сразу, нужна ли тебе поддержка безопасных соединений ′--with-openssl′ и протокола автоматической настройки сети Bonjour ′--with-bonjour′.
По большому счету, параметры, предлагаемые по умолчанию, достаточно хороши, и если ты ставишь себе СУБД «общего назначения», то вполне можно оставить все, как есть. Только для MySQL лучше бы не забыть указать кодировку, чтобы потом не удивляться, что как-то криво работает сортировка по отечественному алфавиту.
Итак, после того как ты наметил для себя, с какими параметрами следует собирать приложения, сборка и инсталляция традиционны и просты:
$ sudo addgroup mysql $ sudo adduser -g mysql mysql $ ./configure --prefix=/usr/local/mysql --with-charset=utf8 $ make $ sudo make install
Возможно, придется самую малость повозиться с зависимостями (раз уж мы пошли по пути сборки из исходников, то избежать этого трудно). Например, потребуется библиотека curses (или ncurses), причем нужны будут и заголовочные файлы (которые обычно вынесены в отдельный dev-пакет и по умолчанию редко устанавливаются).
Для PostgreSQL:
$ sudo adduser postgres $ ./configure --prefix=/usr/local/pgsql --with-python --with-perl $ make $ sudo make install
Здесь из зависимостей могут встретиться библиотеки readline, zlib (тоже с dev-пакетами). Если PostgreSQL собирается с поддержкой процедурных языков PL/Perl и PL/Python (как в примере), то понадобятся также dev-пакеты для libperl и python. Для других опций, естественно, будут выплывать свои зависимости. Главное — не забудь создать нужных для работы пользователей и группы. С установкой на этом все, переходим к настройкам.
Итак, установка позади. Прежде чем приступать к работе, нужно выполнить инициализацию баз, а также сверить умолчальные настройки со своими желаниями. По традиции, начнем с MySQL.
Для инициализации базы разработчики подготовили специальный скрипт mysql_install_db, который можно найти в каталоге bin. Запускать его следует с правами root, чтобы он мог создать необходимые каталоги, но желательно сразу указать параметр ′--′, чтобы задать пользователя, который станет владельцем созданного каталога. Можно, конечно, и вручную, потом права поменять, но лучше сразу:
$ sudo ./mysql_install_db --user=mysql --datadir=/var/db/mysql
В конце работы этого сценария на экран будут выведены инструкции по дальнейшим действиям. В частности, нужно будет задать пароль пользователю root (не путай его с системным «рутом»):
$ /usr/local/mysql/bin/mysqladmin -u root password 'jabubntkmysq'
Кстати, почитай документацию к mysqladmin — это очень мощная утилита для администрирования СУБД. База test, с которой будем экспериментировать, создастся автоматически на этапе инициализации. Рабочие базы можно создать либо из клиента mysql командой ‘CREATE DATABASE‘, либо с помощью той же mysqladmin. При необходимости создай пользователя (‘CREATE USER‘), и можно работать.
Но прежде чем запускать сервер, желательно сначала создать конфигурационный файл (по умолчанию /etc/my.cnf). Разработчики любезно заготовили несколько шаблонов конфигурации для различных случаев — см. каталог support-files в исходниках. Шаблоны my-large.cnf, my-medium.cnf и my-small.cnf отличаются, по большей части, значениями, заданными для различных влияющих на потребление памяти переменных (буферов, кэшей и т.д.). Если интересно, можно выполнить «diff -u my-large.cnf my-small.cnf«. Для небольшой домашней машины вполне подойдет шаблон my-small.cnf, который следует скопировать в /etc под именем my.cnf. Для более крупных инсталляций лучше просмотреть самому один из выбранных шаблонов и подогнать параметры под оптимальные значения в зависимости от объема имеющейся в наличии памяти.
Если ты планируешь использовать таблицы типа InnoDB, то my.cnf нужно будет обязательно подредактировать — по умолчанию все, что касается этих таблиц, в нем закомментировано. Отыщи в конфигурационном файле в секции [mysqld] следующие строки, сними комментарии и приведи в соответствие со своими потребностями:
# Путь к каталогу, где будут размещены InnoDB-таблицы:
innodb_data_home_dir = /var/db/mysql/innodb/db/
# Имя файла хранилища, его первоначальный размер (10 МБ)
# и разрешение на автоматическое расширение при необходимости:
innodb_data_file_path = ibdata1:10M:autoextend
# Каталог хранения журналов и архивов
# (если есть возможность, лучше выносить на отдельный винч):
innodb_log_group_home_dir = /var/db/mysql/innodb/log/
innodb_log_arch_dir = /var/db/mysql/innodb/log/
# Память, отводимая под буферы (если на машине работает что-то
# кроме mysql, лучше не поднимать выше 30-70% от объема ОЗУ):
innodb_buffer_pool_size = 16M
innodb_additional_mem_pool_size = 2M
# Размеры журнальных файлов (рекомендуется держать на уровне
# 20-25% от размера буферов):
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50
Приведенные цифры, естественно, можно менять в зависимости от конкретной ситуации — ресурсопотребления других процессов, работающих на этой же машине, объема памяти и т.д. Каталоги, указанные в конфигурации, должны существовать (в том смысле, что их придется создать вручную до того, как сервер будет перезапущен с новыми параметрами) и принадлежать пользователю mysql:
$ sudo -u mysql mkdir -p /var/db/mysql/innodb/{db,log}
В опции innodb_data_file_path можно указывать несколько файлов. При первом запуске сервера после внесения изменений в конфигурацию будет выполнена инициализация указанных хранилищ:
$ sudo /usr/local/mysql/bin/mysqld_safe --user=mysql --datadir=/var/db/mysql
Starting mysqld daemon with databases from /var/db/mysql
Сразу замечу, что остановить запущенный сервер можно такой командой:
$ sudo kill `sudo cat /var/db/mysql/toshiba.pid`
Для удобства команды запуска и останова можно оформить в виде стартового сценария. Еще одна причина воспользоваться дистрибутивной установкой — там все это уже сделано.
Таблицы формата MyISAM будут размещаться в указанном каталоге «пофайлово», в то время как таблицы InnoDB размещаются в одном (или нескольких) файле-хранилище, согласно конфигурационному файлу.
В PostgreSQL поддерживается один тип хранилища данных, поэтому все несколько проще — нужно создать каталог, где будет размещаться хранилище, сделать его владельцем пользователя postgres и выполнить инициализацию:
$ sudo mkdir -p /var/db/pgsql/data $ sudo chown postgres /var/db/pgsql/data $ sudo su postgres $ cd /usr/local/pgsql/bin $ ./initdb -D /var/db/pgsql/data $ exit
После инициализации будет выведено предупреждение, что для локальных подключений разрешена так называемая «trust-аутентификация» (об этом — чуть позже), и показано два способа запустить сервер. В первом случае — «postgres -D /var/db/pgsql/data» — сервер будет запущен в интерактивном режиме, т.е. информация о его работе будет отображаться в окне терминала, а при закрытии терминала сервер будет остановлен. Безусловно, работающий процесс всегда можно перевести в фоновый режим, либо сразу указав символ ‘&’ после команды, либо в дальнейшем приостановив его работу комбинацией клавиш <Ctrl-Z> и затем возобновив в фоне с помощью утилиты bg:
$ sudo -u postgres ./postgres -D /var/db/pgsql/data
LOG: database system was shut down at 2006-12-16 13:58:54 MSK
…
LOG: database system is ready
// здесь нажали <Ctrl-Z>
[1]+ Stopped sudo -u postgres ./postgres -D /var/db/pgsql/data
$ bg
[1]+ sudo -u postgres ./postgres -D /var/db/pgsql/data
Управление сервером с помощью pg_ctl, на мой взгляд, более удобно, и в этом случае сервер будет сразу запущен как фоновый процесс. Нужно только не забывать, что обе команды должны быть запущены от имени пользователя postgres. В приведенном выше примере это выполняется с помощью утилиты sudo. Если запуск сервера прошел без ошибок, значит, все готово для работы (если же какие-то проблемы возникнут, то они, как правило, достаточно подробно расписаны в сообщениях, выводимых на экран или в лог. Наиболее часто проблемы связаны с правами доступа — либо хранилищу не того пользователя владельцем сделали, либо от имени неправильного пользователя запускается сервер). Но перед началом работы хорошо бы посмотреть, а что же у нас творится в настройках.
Конфигурация PostgreSQL запрятана в каталоге хранилища, которое создается во время инициализации. В нашем случае это будут файлы postgresql.conf, pg_hba.conf и pg_ident.conf в каталоге /var/db/pgsql/data. В первом из них сосредоточены основные опции, управляющие работой сервера — по умолчанию они достаточно хорошо работают, но в случае проблем с производительностью имеет смысл попробовать их подкрутить согласно конкретным условиям. Оставшиеся два файла отвечают за доступ к серверу. Они снабжены предельно подробными комментариями, так что разобраться с ними не составит труда. Кстати, предупреждение о trust-аутентификации, полученное при инициализации базы, связано со следующими строками в pg_hba.conf:
# «local» is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
Они означают, что любой локальный пользователь, подключающийся к любой базе, сможет соединяться с сервером без указания пароля. В некоторых дистрибутивах вместо второго «all» (означающего «все пользователи») ставят более жесткое ограничение — «sameuser«, т.е. пользователь сможет подключиться к базе только в том случае, если его имя в PostgreSQL совпадает с системным именем. Если тебе нужен доступ к БД «снаружи», добавь соответствующие строки. Например, так можно разрешить доступ к серверу всем пользователям к базе «common» из указанной подсети с аутентификацией через PAM или LDAP (поддержка соответствующих типов аутентификации должна быть добавлена на этапе компиляции):
host common all 10.0.0.0/8 pam,ldap
Отрегулировав права, можно подключаться к базе template1 (она создается при инициализации и служит шаблоном для всех создаваемых впоследствии баз, если явно не указана база-»родитель»):
$ bin/psql -U postgres template1
template1=# create user test;
CREATE ROLE
template1=# create database test owner test;
CREATE DATABASE
template1=# c test test
You are now connected to database «test» as user «test».
test=> create table test (fnum numeric, fstr varchar);
CREATE TABLE
test=> q
Здесь мы создали пользователя test и одноименную базу для экспериментов. Раз все получилось, значит, установка прошла без эксцессов.
К сожалению, рамки этой статьи не позволяют подробно остановиться на работе с базами, но это, как говорится, уже дело техники. Пару слов скажу о возможностях, которые предоставляют эти СУБД.
Начиная с версии 5.0, функциональные возможности MySQL существенно расширились: появилась поддержка триггеров, хранимых процедур, представлений (view), курсоров. Поддержка нескольких типов таблиц позволяет гибко варьировать между надежностью и скоростью. В общем, MySQL сейчас вплотную приближается по своим возможностям к таким «монстрам» как Oracle, DB2, MS SQL, хотя на данном этапе ей пока недостает «зрелости».
А что же PostgreSQL? Все перечисленные выше функциональные возможности в ней были давно, и их можно считать вполне зрелыми и проверенными временем. Огромным плюсом, на мой взгляд, является поддержка различных языков для разработки «серверной логики». К тому же, PostgreSQL всегда славилась своей поддержкой стандартов — в отличие от других СУБД, включая MySQL, в PostgreSQL стандарты SQL-92 и SQL-99 поддерживаются наиболее полно и последовательно, в последних версиях появилась частичная поддержка SQL-2003. Хотя, как показывает практика, стандарты, к сожалению, не часто пользуются должной популярностью.
О производительности говорить не буду, поскольку этот вопрос требует проведения серьезного исследования и, по возможности, на различном железе. Небольшие тесты, которые я проводил «на коленке», не продемонстрировали явного преимущества MySQL даже с таблицами MyISAM, и если верить сторонним исследованиям, PostgreSQL гораздо лучше держит нагрузку, в то время как MySQL проваливается при большом числе одновременных запросов (см. ).
Итак, получается, что и MySQL, и PostgreSQL сейчас довольно близки функционально, хотя MySQL по-прежнему в роли догоняющего. То, что одна сложнее другой в установке или работе, тоже не скажешь, — это, скорее, вопрос привычки и личных предпочтений. Скорость работы — вопрос сложный, и ответ на него зависит от целого ряда условий (режим использования, железо, размеры и структура базы и т.д.). Выбирать, конечно, тебе. Но обрати внимание на PostgreSQL, если еще с ней не работаешь, — она того заслуживает.
Врезка: Графические инструменты для работы с СУБД
Как MySQL, так и PostgreSQL не обделены средствами для более комфортной работы с СУБД. Прежде всего, следует отметить вездесущий PHP-инструментарий: phpPgAdmin и phpMyAdmin. Также для PostgreSQL нужно отметить утилиту pgAdmin — простой, но в то же время достаточно удобный способ администрировать базу.
INFO
-
Вечный спор «MySQL vs PostgreSQL» можно найти практически на любом «админском» сайте. Главное — не доверяй слепо первым попавшимся аргументам.
WWW
- — сайт компании MySQL AB
- — почти то же самое, но ориентированное на сообщество
- — официальный сайт СУБД PostgreSQL
- — русскоязычный сайт почитателей MySQL
- — страница русскоязычной документации по PostgreSQL
Статья опубликована в февральском номере журнала «Xakep» за 2007 год.



