Недавно я подключился к провайдеру Интернет по Ethernet, да ещё с постоянным IP-адресом. Сервер, на котором у меня расположен сайт, периодически ведёт себя очень странно, я думаю, что вы могли это заметить. Иногда сервер перестаёт отвечать, я подозреваю вываливание в Kernel Panic (на сервере стоит FreeBSD 6.3). Подозреваю аппаратную проблему, но заменить сервер я пока не могу, а обновить систему до 8.0, или установить Linux можно, но непросто, так как я использую для сайтов jail'ы. В итоге я решил временно перенести сайты на MacBook, который у меня используется в виде сервера.

Подъём сервера для хостинга Wordpress состоит из нескольких этапов, и я рассмотрю их в серии статей. В этой части я опишу установку MySQL, затем - настройку web-сервера на базе nginx с использованием PHP в виде Fastcgi (можно было бы использовать и Apache, но мне нужен легковесный и быстрый web-сервер, хорошо работающий под большой нагрузкой). Итак, приступим.

Поставить MySQL под Mac OS X можно несколькими методами. Самый неинтересный для меня - это MAMP (готовое решение, включающее MySQL, Apache, PHP с полным набором модулей). Объяснять почему мне это не нравится не буду, и так понятно.

Второй - из бинарного пакета с сайта MySQL (выбираем версию MySQL 5.1—Generally Available (GA) release for production use). Вот более короткий линк к нужному пакету, я ставлю из package format, Mac OS X 10.5 (x86_64), весь процесс описан в документации. Во многих случаях этот способ предпочтительный, так как MySQL здесь собран гарантированно нормально. Но есть некоторая сложность в обновлении - я предполагаю, что автообновлений нет, и придётся устанавливать новые версии вручную.

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

Есть, конечно же, и четвёртый метод, заключающийся в компиляции MySQL из исходных текстов с накладыванием различных патчей, оптимизирующих работу MySQL, но я не любитель стиля Gentoo, и мне важнее предсказуемость работы системы и простота обновлений, чем выигрыш производительности на 15%.

Сначала нужно поставить XCode, в котором находятся средства разработки под Unix, необходимые для компиляции MySQL и других пакетов. Это просто, объяснять не буду.

Потом - MacPorts. Списывается пакет последней версии под нужную версию Mac OS X, в моём случае MacPorts-1.8.2-10.6-SnowLeopard.dmg, и устанавливается. Сразу же обновим дерево портов:

$ . ~/.profile
$ sudo port selfupdate

Ставим MySQL Server (на MacBook 2.2 GHz пакет поставился за 22 минуты):

$ sudo port install mysql5-server

При установке выдалось сообщение о том, как установить файлы базы данных и как запустить mysql. Выполняем:

$ sudo -u _mysql mysql_install_db5
$ sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist

Проверим, что MySQL запустился:

$ ps ax | grep mysql | grep -v grep
 2050   ??  Ss     0:00.00 /opt/local/bin/daemondo --label=mysql5 --start-cmd /opt/local/etc/LaunchDaemons/org.macports.mysql5/mysql5.wrapper start ; --stop-cmd /opt/local/etc/LaunchDaemons/org.macports.mysql5/mysql5.wrapper stop ; --restart-cmd /opt/local/etc/LaunchDaemons/org.macports.mysql5/mysql5.wrapper restart ; --pid=none
 2060   ??  S      0:00.02 /bin/sh /opt/local/lib/mysql5/bin/mysqld_safe --datadir=/opt/local/var/db/mysql5 --pid-file=/opt/local/var/db/mysql5/ceiling-cat.local.pid
 2110   ??  S      0:00.07 /opt/local/libexec/mysqld --basedir=/opt/local --datadir=/opt/local/var/db/mysql5 --user=_mysql --log-error=/opt/local/var/db/mysql5/ceiling-cat.local.err --pid-file=/opt/local/var/db/mysql5/ceiling-cat.local.pid

Я привык к именам программ вида mysqladmin и mysql, а в каталоге /opt/local/bin описаны симлинки вида mysqladmin5/mysql5. Можно сделать нужные симлинки, но я сделаю универсальнее, прописав путь к нужным утилитам без суффикса "5". Путь после модификации должен быть таков:

$ vim ~/.profile
export PATH=/opt/local/lib/mysql5/bin:/opt/local/bin:/opt/local/sbin:$PATH

Перечитываем путь с помощью "source":

$ . ~/.profile
$ echo $PATH
/opt/local/lib/mysql5/bin:/opt/local/bin:/opt/local/sbin:/opt/local/bin:/opt/local/sbin:/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin

Теперь можем привычно запускать утилиты MySQL

$ which mysql
/opt/local/lib/mysql5/bin/mysql

Проверить, запустился ли MySQL, можно и так:

$ mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.1.42 Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Сразу же устанавливаем пароль root (этот пароль я сразу же после написания статьи изменю):

$ mysqladmin -u root password 'fc97a2060ec0775ed3b6aa011ee27e88'

Для того, чтобы не вводить пароль каждый раз, прописываем его в конфиг-файле:

$ touch ~/.my.cnf
$ chmod 600 ~/.my.cnf
$ vim ~/.my.cnf
[mysql]
user    =   root
pass    =   fc97a2060ec0775ed3b6aa011ee27e88

Обязательно нужно или поменять пароль для доступа через сеть, или удалить записи для хостов "hostname.local" и 127.0.0.1. Когда мне понадобится, я создам нужных пользователей, поэтому буду удалять.

$ mysql mysql
mysql> select Host, User, Password from user where user = 'root';
+-------------------+------+-------------------------------------------+
| Host              | User | Password                                  |
+-------------------+------+-------------------------------------------+
| localhost         | root | *769F25A82BD5CC256FA4D47499CE6026D89D72E6 |
| ceiling-cat.local | root |                                           |
| 127.0.0.1         | root |                                           |
+-------------------+------+-------------------------------------------+
mysql> delete from user where User = "root" and Host = "127.0.0.1";
Query OK, 1 row affected (0.00 sec)

mysql> delete from user where User = "root" and Host = "ceiling-cat.local";
Query OK, 1 row affected (0.00 sec)

mysql> select Host, User, Password from user where user = 'root';
+-----------+------+-------------------------------------------+
| Host      | User | Password                                  |
+-----------+------+-------------------------------------------+
| localhost | root | *769F25A82BD5CC256FA4D47499CE6026D89D72E6 |
+-----------+------+-------------------------------------------+

Можно было бы на этом и закончить, но лучше донастроить MySQL через конфиг-файл /etc/my.cnf. По крайней мере нужно выставить использование по умолчанию UTF8, включить INNODB, ограничить количество коннектов, и включить slow_query_log.

Примеры конфиг-файлов поставляются вместе с MySQL:

$ ls -al /opt/local/share/mysql5/mysql/my*cnf
-rw-r--r--  2 root  admin   4851 Jan  7 22:26 /opt/local/share/mysql5/mysql/my-huge.cnf
-rw-r--r--  2 root  admin  20232 Jan  7 22:26 /opt/local/share/mysql5/mysql/my-innodb-heavy-4G.cnf
-rw-r--r--  2 root  admin   4825 Jan  7 22:26 /opt/local/share/mysql5/mysql/my-large.cnf
-rw-r--r--  2 root  admin   4836 Jan  7 22:26 /opt/local/share/mysql5/mysql/my-medium.cnf
-rw-r--r--  2 root  admin   2474 Jan  7 22:26 /opt/local/share/mysql5/mysql/my-small.cnf

Меня устраивает конфигурация medium:

$ head -5 /opt/local/share/mysql5/mysql/my-medium.cnf
# Example MySQL config file for medium systems.
#
# This is for a system with little memory (32M - 64M) where MySQL plays
# an important part, or systems up to 128M where MySQL is used together with
# other programs (such as a web server)

Копирую её в /etc/my.cnf:

$ sudo cp /opt/local/share/mysql5/mysql/my-medium.cnf /etc/my.cnf

Корректирую конфиг (если интересно, то одна из первых версий доступна для списывания):

  • Отключаю возможность доступа по сети: skip-networking
  • Выставляю везде default-character-set=utf8
  • Для mysqld включаю character-set-server = utf8 и default-character-set = utf8
  • Ограничиваю количество сессий max_connections=50
  • thread_cache_size = 16
  • query_cache_size = 32M
  • Включаю секцию innodb
  • Выставляю логгирование (slow_query_log = 1, slow_query_log_file = /var/log/mysql-slow.log, log-error = /var/log/mysql.log)

Создаю нужные файлы логов, иначе они не воспримутся:

$ sudo touch /var/log/mysql-slow.log
$ sudo chown _mysql:_mysql /var/log/mysql-slow.log
$ sudo touch /var/log/mysql.log
$ sudo chown _mysql:_mysql /var/log/mysql.log

Перезагружаем сервер MySQL (-w отключает disable, т.е. MySQL загрузится при рестарте системы)

$ sudo launchctl unload -w /Library/LaunchDaemons/org.macports.mysql5.plist
$ sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist

Нужно посмотреть лог на предмет ошибок или проблем:

$ tail -100 /var/log/mysql.log

Очень важно сделать базовый аудит конфигурации MySQL, для этого я использую два скрипта. Первый - mysqltuner.pl:

$ curl http://mysqltuner.com/mysqltuner.pl -o mysqltuner.pl
$ chmod +x mysqltuner.pl
$ ./mysqltuner.pl

Второй - mysql-tuning-primer:

$ curl http://launchpadlibrarian.net/36004840/tuning-primer.sh -o tuning-primer.sh
$ chmod +x tuning-primer.sh
$ ./tuning-primer.sh

Особых проблем скрипты не выявили. Если бы нашли, то нужно было бы подправить /etc/my.cnf и перезапустить MySQL.

Настройка закончена, осталось перезапустить Mac OS X для проверки, подымется ли MySQL после рестарта. У меня он поднялся.

Если вы хотите углубить свои знания по MySQL, то рекомендую ознакомиться с сайтом MySQL Performance Blog (этот сайт ведут специалисты широкоизвестной в узких кругах фирмы Percona).

Использование GUI для работы с базой данных

Я не разработчик, и мне хватает командно-строковой утилиты mysql. Но если вам нужен GUI, то можно будет или поставить phpMyAdmin (он будет доступен через web), или же утилиту под Mac OS X Sequel Pro (она бесплатная, приветствуются пожертвования).

Sequel Pro мне нравится тем, что он позволяет соединяться через туннель SSH, и на хосте с MySQL достаточно открыть сетевой доступ через 127.0.0.1. Для того, чтобы это сделать, нужно в /etc/my.cnf закомментировать опцию "skip-networking" (конечно же, после этого нужно перезагрузить MySQL) и открыть доступ пользователю (например, root):

$ mysql mysql
mysql> GRANT ALL ON *.* TO root@127.0.0.1 IDENTIFIED BY 'fc97a2060ec0775ed3b6aa011ee27e88';
mysql> FLUSH PRIVILEGES;

Настройка туннелирования:

Интерфейс программы:

Проверка производительности MySQL

Для того, чтобы знать, какую нагрузку выдержит MySQL, можно применить бенчмаркинг sql-bench (это необязательно, раздел можно пропустить). К сожалению, в портах его я не нашёл, поэтому сделаю не совсем правильно, но действенно - поставлю бинарный package с сайта MySQL (это второй описанный метод), но не буду запускать сам MySQL.

Списываю package Mac OS X 10.5 (x86_64) и устанавливаю его (только mysql-.....pkg, ни в коем случае не prefpane и не StartupItems). Система поставилась в /usr/local/mysql (это симлинк на каталог с установленной версией типа mysql-5.1.42-osx10.5-x86_64).

SQL-Bench использует Perl, для соединения с MySQL нужен DBD::mysql, поставим его (в ответ на предложение сконфигурировать CPAN нажимаем Enter или пишем "yes"):

$ sudo perl -MCPAN -eshell
Would you like me to configure as much as possible automatically? [yes] yes
cpan[1]> install DBD::mysql
...
 CAPTTOFU/DBD-mysql-4.013.tar.gz
 /usr/bin/make install  -- OK
cpan[2]> quit

Запускаем бенчмаркинг. Сразу предупреждаю, что процесс длительный, у меня он занял 16 минут:

$ cd /usr/local/mysql/sql-bench/
$ sudo ./run-all-tests --server=mysql --user=root -pass=fc97a2060ec0775ed3b6aa011ee27e88 --log

Смотрим на результат, размышляем.

На этом заканчиваем, в следующей части приступим к настройке web-сервера.

Замена паролей

При необходимости меняем пароль (как я и обещал, я это сделал - лучше три лишние команды, чем потеря данных):

$ mysql mysql
mysql> GRANT ALL ON *.* TO root@127.0.0.1 IDENTIFIED BY 'verysecretpassword';
mysql> GRANT ALL ON *.* TO root@localhost IDENTIFIED BY 'verysecretpassword';
mysql> FLUSH PRIVILEGES;