Мои ошибки за 2012 год

17th Декабрь 2012 | Категории: Сервер | Метки: , ,

Год назад я стал счастливым обладателем VPS сервера. О своих ошибках при установке и настройке я уже писал в теме Переезд на VPS. Часть 2 – Мои ошибки.
Прошел год, а значит у меня было 365 дней, что бы накосячить.

Что нужно было сделать, но не сделано

Бэкап хранится локально

Да, я храню бэкапы на том же самом сервере. По крайней мере я так делал большую часть 2012 года. Сравнительно недавно у меня появился быстрый интернет и теперь я забираю бэкапы почти сразу. Но это не выход. Ведь сейчас есть множество готовых решений. Начиная от бесплатного DropBox и его аналогами, заканчивая серверами под бэкап (Amazon S3, бэкап-хостинги и т. д.) со стоимостью до 15-30$/год. Цены приведены, исходя из моих потребностей. А это не более 25Gb.
Необходимо настроить автоматическую выгрузку бэкапов в надежное место.

Бэкап

Каюсь, но я до сих пор не настроил автоматические бэкапы. Скрипты для резервного копирования созданы, но я их запускаю вручную. Причем делаю это примерно раз в месяц. Так делать нельзя. Нельзя. Нельзя.
Необходимо настроить ежедневный бэкап с ротацией.

Пару слов о моих бэкапах. Все БД и файлы вместе занимают 3Gb. Один бэкап архив этих данных занимает 700Mb. Кроме этого нужно место под логи и под сырые данные, на основании которых рассчитываются данные в одном из проектов. Все это вместе съедает 8 из 15Gb, отведенных на VPS. Если я настрою автоматический бэкап и не буду его забирать, то место на сервере кончится за неделю. Как видно, задача комплексная. Нужно собраться с духом и решить её.

Бэкап MySQL наживую

Во время дампа БД я не забочусь о целостности данных.
Представим ситуацию. У нас есть база данных из 500 таблиц, общий размер которых 2Gb, есть CRON скрипты и пользователи на сайте, которые заполняют эти таблицы. Дамп 2Gb – дело не быстрое. Новые данные могут прийти в тот момент, когда мы сделали дамп половины таблиц. В итоге часть новых данных будет утеряна. Допустим, что это статистика гонок. Есть таблицы Drivers и Races. Скрипт пишет информацию о каждом заезде (Races) и о каждом гонщике (Drivers). После заезда он обновляет статистику гонщика. Заезд заканчивается в момент дампа, когда сохранены таблицы с именами на A-E. То есть в дамп попадут старые таблицы A-E и новые F-Z. А это означает, что информация о заездах будет полная, а статистика гонщиков не будет содержать информацию о последнем заезде.
Есть множество способов, как снять грамотный дамп даже с высоконагруженного проекта. Но это тема для отдельной статьи.

Ротация логов

Не настроена. Вроде бы, очень просто настроить logrotate. Даже не знаю, как отмазаться :). Кстати. Во время DDoS у меня очень быстро закончилось место. Если бы была настроена ротация логов, ничего страшного не произошло бы. Да, сервер не был бы доступен ночью. Но CRON скрипты продолжали бы работать и собирать статистику.
Необходимо настроить logrotate.

Смена пароля SSH

Пароль длинный и созданный по всем правилам (цифро-буквы в разном регистре с использованием спец символов). Но и такие пароли нужно менять раз в 6-12 месяцев. Может быть, это просто моя паранойя.

Сижу под ROOT

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

Обновления библиотек посреди рабочего дня

Вот захотелось мне обновить MySQL до версии 5.5 в полдень среды – я обновил. Переименовать таблицы – переименовал. Всё это сопровождалось остановкой MySQL и недоступностью сайтов.
Никогда так не делайте.
И не забывайте про поговорку: «Семь раз отмерь – один отрежь».

Обновление с MySQL 5.1 до 5.5

Поначалу все было отлично. Кроме того, что у меня в голове возникла идея обновиться посреди рабочего дня.

yum remove mysql mysql-*
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
yum --enablerepo=remi,remi-test list mysql mysql-server
yum --enablerepo=remi install mysql-server
service mysqld start

Пробуем и получаем:

Fatal error: Call to undefined function mysql_connect()

Добавляем:

yum install php-mysql

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

yum install php-pecl-apc

Всё отлично.
Только через два часа я заметил большое количество ошибок в отчетах CRON скриптов.

PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib/php/modules/apc.so' - /usr/lib/php/modules/apc.so: undefined symbol: pcre_exec in Unknown on line 0

Суть ошибки в том, что CRON скрипты не могут загрузить модуль apc, который им вообще не нужен.
Решение похоже на костыль, но зато простое. Нужно создать отдельный php.ini для командной строки, в котором убрать модуль apc. Так как ini файлы модулей загружаются автоматически, нам придется добавить все настройки из php.d/apc.ini в основной php.ini. В командах это выглядит так.

cp /etc/php.ini /etc/php-cli.ini 
cat /etc/php.d/apc.ini >> /etc/php.ini

После чего открываем в любом редакторе apc.ini и добавляем ; в начале каждой строки.
Было:

extension = apc.so
apc.enabled = 1
apc.shm_size = 128
apc.shm_segments = 1
apc.gc_ttl = 7200
apc.ttl = 0
apc.num_files_hint = 1024
 
apc.file_update_protection = 2

;apc.optimization = 1
;apc.include_once_override = 1
;apc.stat = 0
apc.max_file_size = 5M
;apc.stat_ctime = 1

;apc.mmap_file_mask=/tmp/apc.XXXXXX
;apc.mmap_file_mask=/dev/zero
 
apc.filter="-/usr/share/phpMyAdmin/.*"

Стало:

;extension = apc.so
;apc.enabled = 1
;apc.shm_size = 128
;apc.shm_segments = 1
;apc.gc_ttl = 7200
;apc.ttl = 0
;apc.num_files_hint = 1024

;apc.file_update_protection = 2

;apc.optimization = 1
;apc.include_once_override = 1
;apc.stat = 0
;apc.max_file_size = 5M
;apc.stat_ctime = 1

;apc.mmap_file_mask=/tmp/apc.XXXXXX
;apc.mmap_file_mask=/dev/zero

;apc.filter="-/usr/share/phpMyAdmin/.*"

После этого всё заработало в полном объеме.

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

CREATE TABLE IF NOT EXISTS abc_data (fields) TYPE=MyISAM;

Начиная с MySQL 5.5, больше не поддерживается опция TYPE. Вместо неё нужно использовать опцию ENGINE.
Правильный запрос:

CREATE TABLE IF NOT EXISTS abc_data (fields) ENGINE=MyISAM;

Планы на 2013 год

1. Настроить нормальный бэкап.
2. Отучить себя править исходники наживую.
3. Развертывать код только через GIT.
4. Сменить связку Apache + Nginx на PHP-FPM + Nginx.

Subscribe without commenting


Пока комментариев нет.