Бэкап на Mozy.com

О важности бэкапов и как это я организую на сервере, я уже писал. Пару месяцев назад серьёзно задумался о бэкапе дома. Как говорят жизнь делится на две части: до сгоревшего винчестера, и после. Т.к. я уже терял свои веники два раза, то все важные данные я сохраняю на второй винчестер в компьютере и раз в пару недель всё копирую на внешний винчестер. Всё это замечательно защищает данные от того, что может полететь основной винчестер, или два одновременно (например, такое случается, если сгорает блок питания). Но случаи бывают разные и неправильно хранить все бэкапы в одной квартире — тут нарушается основной принцип бэкапа, чем географически дальше находятся копии, тем лучше.

Сохранять данные на DVD-болванки уже неудобно, т.к. на диск влезает чуть меньше 5 Гб, что мало, а коллекции быстро растут, у меня например одних фотографий уже 55 гигайбайт. К тому же нужно ждать пока данные насобираются на новый диск (можно потерять, то что не успел записать), и нужно диски куда то отвозить, например к родственникам (что долго), чтобы не хранить все бэкапы в одном месте.

Поэтому я обратил внимание на онлайн сервисы для бэкапа. Благодаря развитию рынка интернет услуг в последние два года у нас в стране, сильно выросли скорости и трафик на тарифах интернет-провайдеров, стало возможно закачивать/скачивать большие объёмы данных. У меня, например, сейчас на тарифе 100 гигабайт трафика, что более чем достаточно, чтобы в течение месяца забэкапить все важные данные.

Сервисов для бэкапа существует великое множество, все они примерно дают схожую функциональность, но отличаются ценами, условиями и удобством. Попробовал несколько крупных сервисов и остановился на Mozy.com. Основная проблема во многих сервисах, что они держат пользователей за идиотов не дают выбрать, какие папки бэкапить, а сохраняют всё подряд. Возможно это удобно, если есть 300-гигабитный интернет, чтобы восстановить потом все данные за сутки, но когда террабайт места на дисках занимают фильмы, сериалы, дистрибутивы программ и игр, это совершенно не удобно 🙂


Статус отправки файлов на сервер

Mozy позволяет бесплатно бэкапить 2 гигабайта информации, либо неограниченный объём за 5$ в месяц и обладает хорошей функциональностью. Понравилась удобная клиентская часть, позволяет выбрать в какие папки будут забэкаплены. Можно настроить автоматический бэкап в определённое время суток, ограничение полосы канала.


Интерфейс клиентской части

Данные  можно восстановить, установив клиентскую часть, либо прямо из своего веб-аккаунта на Mozy.com, что крайне удобно — файлы архивируются и присылается ссылка для скачивания на архив. Восстановить можно отдельно любую папку (как ни странно, не во всех сервисах такое возможно). Что важно, можно восстановить не только файлы из последнего бэкапа, но и файлы из бэкапа за любое число.

Java = Дырка в безопасности

В начале года писал про Adobe Acrobat, что он является причиной 80% взломов, и писал про альтернативу, чтобы уменьшить поверхность атаки на компьютер.

Сейчас ситуация изменилась и основной дыркой является Java.

http://www.3dnews.ru/software-news/kolichestvo-atak-na-java-previsilo-vse-mislimie-predeli/

Популярность у киберпреступников уязвимостей в платформе Java стала приобретать катастрофический оттенок и вызывать серьезные опасения у экспертов по информационной безопасности…
…за последние полгода количество атак на Java увеличилось в десятки раз. Если в начале года было зафиксировано около 300 тыс. случае применения эксплойтов для платформы, то в третьем квартале — уже более 6 миллионов…

Поэтому, нужно проверить, обновляется ли Java: http://www.java.com/ru/download/help/java_update.xml

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

Для Firefox и Chrome проще всего отключить Java можно с помощью плагина Web Developer (там много чего можно отключить), с помощью этого дополнения можно легко включить Java обратно, когда она потребуется.

Для Chrome проще всего отключить Java, если вписать -disable-java в путь вызываемого файла в ярлыке на рабочем столе.

Transcend StoreJet 25M3

Вчера приобрёл портативный винчестер Transcend StoreJet 25M3 640 Gb, в первую очередь, чтобы решить проблему с бэкапом важных файлов с компьютера. У меня два винчестера и я сохраняю всё важное с одного на другой, но далеко не гипотетична ситуация, когда могут сгореть сразу два, из-за проблем связанных, например, с блоком питания. Ну и «огромная флешка» никогда не помешает.

Цены за последние года полтора на подобные устройства очень сильно снизились, давно хотел купить, но раньше цены кусались (были больше двух сотен), а сейчас потратил чуть больше $100 . Цены на портативные винчестеры с меньшим объёмом и USB 2.0 ещё ниже.

Обещают определённую ударопрочность (резиновый корпус и прокладки амортизируют удары до определённой степени), я бы конечно не рискнул проверять, но надеюсь, можно его спокойно таскать с собой, например, в сумке.

Специально взял версию с USB 3.0, она дороже на 20$ аналогичной модели с USB 2.0, но ускорение передачи файлов в 3 раза в перспективе, как мне кажется, того стоит. Через несколько месяцев планирую апгрейд свого компа, обязательно возьму плату с поддержкой USB 3.0. Из минусов, третья версия USB совместима со второй только на уровне разьёма type A (прямоугольный, тот который втыкается в комьютер), а mini и micro разьёмы новые, т.е. придётся с винчестером всегда таскать ещё и кабель.

У Transcend есть фирменная программка для бэкапа, можно добавить определённые папки, а потом при нажатии одной кнопки происходит синхронизация. Всё это сначала показалось удобным, но после того как сделал повторную синхронизацию, оказалось, что программка определяет были ли изменения в файлах не по дате/размеру, а читает файл полностью (наверное для подсчёта хэша), и даже минимальное обновление занимает море времени (проще файлы скопировать вручную заново). Сколько пересмотрел программ для бэкапа (в том числе онлайн), пока так не нашёл для себя по-настоящему удобной.

Google Voice

Вчера в аккаунте Gmail появилась новая ссылка с баннером, что можно звонить прямо из Gmail, а потом куда-то пропала.

Возможность звонить на мобильные/стационарные телефоны, это новая возможность в Google. Явная конкуренция Skype. Мне в первую очередь в данный момент интересны звонки в Россию (по работе) и в Беларусь (если ехать в другую страну), но пока цены практически одинаковы.

Более примечательны различные возможности — расшифровка голосовых сообщений в виде текста, исходящие звонки — указываете свой номер мобильного, на него идёт входящий звонок и сразу же подключается разговор на второй указанный телефон, т.е. звонок получается с мобильного, но за нормальные деньги. Всё это пока доступно для англоязычных пользователей, но вскоре должно быть доступно для всех.

Класс SD карточек

Купил сегодня себе SD флеш-карточку для фотоаппарата. Так вот, сейчас ввели очень грамотную градацию скорости карт для, так называемый класс. На данный момент есть 2, 4, 6 и 10-ый класс скорости. Число означает гарантированную скорость записи (кол-во мегабайт в секунду). Т.е. 4 класс это не менее 4 мб\с и т.д.

Мне нужна была карточка не меньше 6-го класса (чтобы записывалось FullHD видео), но оказывается карточки 10-го класса скорости (я брал Transcend) стоят всего на пару баксов дороже, а обеспечивают скорость записи не 6 мб\с, а целых 16 мб\с (в два с половиной раза больше), что достаточно заметно при использовании, и при копировании снимков с фотоаппарата на компьютер.

Бэкапиться, бэкапиться и ещё раз бэкапиться..

Вчера приезжаю с отдыха, а один из проектов, над которым работал больше месяца сгорел. Сгорел во всех смыслах, большой пожар неделю назад был в украинском дата-центре в Одессе (hosting.ua), где сервер временно размещался. К счастью бэкап проекта был, его быстро восстановили, хотя потеряли часть критически не важных данных.

Суть в том, что потеря данных может быть в любом, даже в самом навороченном дата-центре. Нельзя полагаться только на RAID, дизель-генераторы и автоматизированные системы пожаротушения. Сервер могут арестовать (по ошибке или просто за компанию с другими), может пройти короткое замыкание или начаться война, попасть метеорит, застрять таракан в лопастях вентилятора или прогрызть проводку мышь, да на него кофе в конце концов могут пролить. Где-то читал, что одна комания бэкапила данные в всемирном торговом центре с одного небоскрёба на сервер в другом небоскрёбе. А потом наступило 9 сентября 2001 года.

В отдельности вероятность этих событий очень маленькая, но вместе, за годы, умноженная на человеческое разгильдяйство — какое-либо чрезвычайное событие, которое приведёт к потере целого сервера, может вполне произойти и нужно быть к этому готовым. Панацея одна — делать бэкапы, причём важно чтобы они хранились где-нибудь подальше (дома или в другом территориально расположенном дата-центре)

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

Я около года назад сделал небольшой PHP скрипт, который использую для бэкапа своих проектов. Файлик лежит в корне веб-сайта, делает бэкап базы и файлов и заливает данные на удалённый сервер. Для каждого нового сайта я заливаю этот скрипт в корень директории сайта и ставлю его выполнение раз в пару дней в cron. Раз в месяц я сливаю архивы с FTP к себе на домашний компьютер.

Я приведу команды для подобного бэкапа в linux. Для вызова консольных команд из PHP можно использовать команды exec или system. Можно на основе этих команд сделать bash скрипт.


Бэкап файлов

Сохраняем сайт в tar архив:
tar -cf {путь к получаемому tar архиву} {полный путь к директории сайта}

например: tar -cf site.tar /var/www/site.com/htdocs

Сжимаем полученный архив в tar.gz (т.к. tar не сжимает, а только пакует файлы в один):
gzip -c {путь к tar архиву} > {путь к получаемому tar.gz архиву}

например:
gzip -c /var/www/site.com/htdocs/site.tar > /var/www/site.com/htdocs/site.tar.gz


Бэкап MySQL базы данных

—quote-names —add-drop-table —user=’.$DBLogin.’ —password=’.$DBPassword.’ —host=’.$hostname;
$str = exec(‘mysqldump ‘.$params.’ ‘.$DBBase.’ > ‘.$path.’/tmp.sql

Сохраняем базу в SQL дамп:
mysqldump —quote-names —add-drop-table —user={юзер БД} —password={пароль к БД} —host={хост, как правило localhost} {название БД}>{путь к сохраняемому SQL дампу}

например: mysqldump —quote-names —add-drop-table —user=root —password=12345 —host=localhost site_database>/var/www/site.com/htdocs/dump.sql

Аналогично сжимаем дамп базы данных в gz архив.


Восстановление данных из архивов

Распаковка файлов из tar.gz в текущую директорию:
tar zxvf {tar.gz архив}

например:
tar zxvf archive.tar.gz

Восстановление базы из sql дампа:
mysql —host={хост} —user={юзер БД} —password={пароль к БД} {название БД}<{SQL дамп}

например: mysql —host=localhost —user=root —password=12345 site_database<dump.sql

Если дамп сжат в gz, то нужно его перед тем как скормить утилите mysql предварительно разархивировать:
gzip -d {название gz файла}


Заливаем на FTP средствами PHP:

Если бэкапить скриптом, то полученные архивы неплохо бы сразу залить на удалённый FTP. Простейший код для заливки файла по FTP в PHP:

$conn_id = ftp_connect({FTP сервер:порт});
$login_result = ftp_login($conn_id, {FTP логин}, {FTP пароль});
if ($conn_id && $login_result) $upload = ftp_put($conn_id, {путь к заливаемому файлу}, {путь сохраняемого файла по FTP}, FTP_BINARY);
ftp_close($conn_id);


Шифруем архивы средствами GPG:

Чтобы можно было использовать любой FTP хостинг, а также без опасений заливать и хранить бэкапы где угодно, неплохо бы их шифровать. Я для шифрования использую GPG — аналог симметричного шифрования PGP.

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

Для создания ключей выполняем: gpg —gen-key

  • Тип ключа (первый вопрос) выбираем по умолчанию — 1
  • Выбор размера ключа — по умолчанию 1024 (или можно 2048 байта)
  • Третий вопрос, время действия ключа выбираем 0 (никогда не истекает)
  • Четвёртый вопрос — указание личных данных (имя и мэйл). Главное имя — название ключа. У меня это backup_key.
  • В конце нужно заполнить пароль. Пароль нужен для получения доступа к секретному ключу. НЕ ЗАБЫВАЕМ ЗАПИСАТЬ!

САМОЕ ГЛАВНОЕ! Не забываем скачать и сохранить в надёжном месте у себя на компьютере секретный и публичный ключ, и пароль к секретному ключу,  а то расшифровать потом архивы самому не получиться =)

Чтобы потом импортировать ключи на новую систему, выполняем:
gpg —import {путь к asc файлу с данными ключа}

Шифрование архива средствами GPG:
gpg —recipient {название ключа} —output {получаемый шифрованный файл} —encrypt {файл для шифрования}

например: gpg —recipient backup_key —output dump.sql.gz.gpg —encrypt dump.sql.gz

Расшифрование GPG файла:

gpg -d {шифрованный файл} > {файл}

например: gpg -d dump.sql.gz.gpg > dump.sql.gz

Чтобы расшифровать архивы в Windows, можно скачать консольную GPG для Windows. Если делать шифрование средствами PHP, нужно в корневой папке апача создать папку .gnupg и положить туда публичный ключ, чтобы он мог шифровать архивы.

Оптимизация MySQL — 2

Месяц назад в посте «Оптимизация MySQL» я писал в основном общие советы по оптимизации, которые для меня были полезны и которые я собрал из нескольких источников. В этот раз пишу некоторые нюансы с которыми столкнулся в процессе оптимизации своих баз данных.

В первую очередь я обратил внимание на те параметры, которые отображаются красным в PhpMyAdmin, и на которые обращает внимание tuning-primer.sh.

tuning-primer.sh — хороший скрипт, анализирует логи и параметры MySQL и даёт советы по оптимизации, мне он понравился больше чем mysqltuner.pl

Для установки выполняем:

wget http://day32.com/MySQL/tuning-primer.sh
chmod 755 tuning-primer.sh
./tuning-primer.s

wget http://day32.com/MySQL/tuning-primer.sh
chmod 755 tuning-primer.sh

Потом запускаем:

./tuning-primer.sh

Большое значение Created_tmp_disk_tables

В процессе работы MySQL для каждого соединения постоянно создаются временные таблицы, большое значение Created_tmp_disk_tables (у меня было 45% от общего числа создаваемых) означает, что временные таблицы создаются не в памяти, а в временных файлах на диске, что замедляет работу MySQL. За выделение памяти для временных таблиц отвечают параметры tmp_table_size и max_heap_table_size в конфиге. Я увеличивал значения этих параметров, но количество создаваемых таблиц на диске не уменьшилось.

Проблема оказалось была вот в чём: если в таблицах используются поля типов TEXT (TEXT, TINYTEXT, MEDIUMTEXT …) или BLOB, то таблица не может быть размещена в памяти, а только на диске. Эти типы полей могут содержать в каждом поле большой объём текста или данных, и в MySQL данные физически не хранятся в самой таблице, а в поле содержится ссылка на сами данные.

Раньше для текстовых данных с длиной поля больше 255 символов альтернативы особой не было, всегда приходилось использовать поле типа TEXT. Но, начиная с версии 5.0.3 тип поля VARCHAR может хранить в себе 65535 байт (до этого только 255 байт). Для всех видов SQL операций, работа с полем VARCHAR происходит быстрее, чем с полями типа *TEXT, но самое главное, что временные таблицы с полями VARCHAR хранятся в памяти.

После того, как я сконвертировал все поля типов TEXT в VARCHAR, значение created_time_disc_tables уменьшилось, и теперь таблицы создаваемые на диске составляют 8% от общего количества, т.е. улучшение в 5 с половиной раз.

Правда, тут есть небольшое ограничение. Одна строка данных (сумма размеров всех полей) в MySQL таблице не может быть больше 65535 байт, т.е. нельзя создать в таблице два поля VARCHAR размером 65000 байт, например. Можно создать два поля размером 32767 байта, или одно поле 32767 и два по 16388.

Кэш запросов и высокое значение Qcache_lowmem_prunes

Кэш запросов может неплохо помочь в случае слабо оптимизированных скриптов, когда часто выполняются одни и те же выборки SELECT. Если запрос уже находится в кэше, то MySQL не обращается к таблицам, а берёт его прямо из кэша, что очень быстро (т.к. кэш в памяти). У меня в моих базах данных из кэша берутся 90% всех запросов.

Qcache_lowmem_prunes — показывает количество запросов которые были удалены из кэша из-за нехватки памяти. Если не хватает размера кэша, то MySQL оставляет в памяти только самые популярные запросы, а редкие из него удаляет. Чтобы уменьшить большое количество Qcache_lowmem_prunes я сначала пытался постепенно увеличивать размер кэша запросов, доведя его до 768 мегабайт. Это не помогло, Qcache_lowmem_prunes не уменьшилось, процент эффективности кеша также не вырос.

Затем я более подробно изучил, как работает кэш, и поменял тактику. Дело в том, что если таблица меняется (происходит INSERT, DELETE или UPDATE), то все запросы из кэша для этой таблицы удаляются. Если кэш большого размера, то на его обслуживание нужно тоже время (т.к. память не может быть освобождена моментально). Часто обновляемые таблицы, по сути, только замедляют работу с кэшем, т.к. запросы почти сразу же удаляются и только фрагментируют кэш.

Для всех таблиц которые часто обновляются, я прописал директиву SQL_NO_CACHE (например SELECT SQL_NO_CACHE * FROM table), принудительно ограничивающую кэширование. Также для больших таблиц, везде где возможно, я прописал названия выбираемых полей в SELECT (например SELECT SQL_NO_CACHE id,name FROM table), что уменьшило размер возвращаемых данных, и увеличило количество запросов, которые могут поместиться в кэше. Несмотря на то, что сейчас размер кеша 256 Мб, количество Qcache_lowmem_prunes резко уменьшилось.

Борьба с Table_locks_waited и перевод некоторых таблиц на InnoDB

Table_locks_waited — показывает количество событий, когда запрос на блокировку таблиц был выполнен через определенный период ожидания. MyISAM — основной движок таблиц в MySQL имеет один большой недостаток, когда происходит изменение таблицы (кроме INSERT в конец таблицы), то она блокируется на чтение, а когда происходит чтение из таблицы, то она блокируется на запись. Другими словами запросы SELECT и UPDATE, DELETE, INSERT не могут проходить одновременно, и когда они пытаются делать это одновременно, какому то запросу приходиться ожидать и возникает Table_locks_waited событие.

Для небольших таблиц блокировка занимает доли секунды и практически не заметна, но ситуация меняется, если в таблице сотни тысяч или миллионы записей. Каждое обновление занимает заметное время, и в случае большой нагрузки происходит лавинообразный рост блокировок, в логе медленных запросов появляется много безобидных SELECT’ов, выполняющихся по несколько секунд, хотя обычно они выполняются за тысячные доли секунды, а некоторые страницы сайтов начинают медленно отдаваться.

Самое обидное, что эти ситуации сложно отследить при создании сайта, я столкнулся с этим через полтора года после того как некоторые таблицы выросли до миллиона записей. Решений этой проблемы несколько.

Первый способ, кардинальный, переделать логику работы с базой данной так, чтобы она обновлялась как можно реже, либо выборки SELECT шли из одной таблицы, а обновления INSERT, UPDATE, DELETE в другую, и например, раз в сутки они синхронизировались.

Второй способ, для таблиц MyISAM есть неплохое решение (если в таблицу происходят только частые вставки INSERT) использовать оператор DELAYED (Например INSERT DELAYED INTO table VALUES (…) ). При таких вставках они не выполняются в данный момент времени, а вставляются отложено с низким приоритетом, т.е. MySQL ждёт пока выполнятся все SELECT запросы и таблица освободится для записи. Такая вставка происходит реже, MySQL собирает сразу несколько таких запросов и вставляет их все вместе, что снижает нагрузку. Большой минус — для очень загруженных таблиц, запрос вставки может вообще никогда не произойти (если таблица не освободится), также в случае падения MySQL сервера все ожидающие запросы пропадут.

По моему опыту, даже не на очень загруженных таблицах данные могут вставлены только через несколько минут (запросы которые ожидают, или долго выполняются можно видеть в реальном режиме времени с помощью утилиты mytop). Из-за своих недостатков, DELAYED подойдет только для не очень важных данных, которые сразу не нужны, и которые не так страшно потерять, например логи.

Третий способ, перевести такие таблицы на InnoDB — более продвинутый движок для таблиц, который поддерживает транзакции, но самое главное, блокировка в InnoDB работает не на уровне всей таблицы, а на уровне отдельных строк. Т.е. могут происходить одновременные запросы на запись и чтение в таблице.

Плюсы InnoDB:

  • Поддержка транзакций (если не нужны, то не является плюсом)
  • Меньше вероятность потерять данные при падении сервера (только если используются бинарные логи)
  • Блокировки на уровне строки (а не всей таблицы, как для MyISAM)
  • Выдерживает большую нагрузку при больших размерах таблиц
  • Показывает большую производительность при одновременных запросах на чтение и запись

Минусы InnoDB:

  • Индексы в 2-3 раза большего размера, чем для MyISAM
  • Нельзя восстановить таблицу из файла (без бинарного лога), нужно регулярно делать бэкапы, чтобы не потерять данные
  • Для быстрой работы InnoDB нужно существенно больше оперативной памяти (переменная innodb_buffer_pool_size)
  • Точное количество элементов в таблице, в определённый момент времени можно узнать только примерно (запросы COUNT (*) для всей таблицы очень медленно выполняются)
  • Время выполнения вставки/обновления больше чем для таблиц MyISAM.

InnoDB или MyISAM это тема для большого холивара, в интернете я так и не нашёл единого мнения что лучше, у кого то серьёзные аргументы за MyISAM, у кого то за InnoDB .  Эти движки таблиц имееют свои различия, плюсы и минусы, и выбор больше зависит от архитектуры построенной базы данных. Для себя я вывел правило: если таблица редко обновляется, то лучше использовать MyISAM, если таблица имеет большой размер и часто обновляется, то лучше использовать InnoDB. Конечно, блокировки случаются и в InnoDB — но для моих данных это случается на несколько порядков реже, а если и случаются то время блокировки незначительное (несколько миллисекунд).

Для быстрой работы InnoDB самое главное это размер буфера innodb_buffer_pool_size, т.к. InnoDB сильно кеширует индексы и данные в памяти. Размер памяти для этой переменной зависит от размера таблиц, я у себя выделил 1 гигабайт памяти (у меня InnoDB таблицы вместе с индексами занимают 600-700 мегабайт).

Для максимально быстрой работы InnoDB устанавливаем innodb_flush_logs_at_trx_commit  равным нулю. Если переменная равна нулю, то логи сохраняются не после каждой транзакции, что уменьшает надёжность, но даёт самую быструю скорость. Если  innodb_flush_logs_at_trx_commit = 1, то логи сохраняются после каждой транзакции, что крайне медленно, если значение равно двум — то раз в 1-2 секунды.

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