Analitycs

понедельник, 24 октября 2011 г.

Как включить MySQL innodb_file_per_table?

В продолжение темы насморков и гильотины оптимизации MySQL привожу рецепт по включению такой полезной функции как innodb_file_per_table.

Зачем это нужно?

MySQL по умолчанию все таблички innodb хранит в одном файле - когда их накапливается приличное количество - файл значительно разрастается. Плюс не забывайте, что при удалении данных в innodb - размер файла не уменьшается - он растет только в большую сторону. Так что если данных в базе у вас много или идет активное удаление - рано или поздно вы задумаетесь о том, чтобы выполнить подобное разделение

Что нужно сделать?

  1. Прежде всего - отрубаем нагрузку, выключаем связь сервер с внешним миром  - php и прочее беспокоить вас не должны - процесс не быстрый
  2. Теперь тщательно делаем ПОЛНЫЙ бекап всех баз данных и конфига
  3. Удаляем все таблицы из БД
  4. Выключаем mysqld
  5. В /etc/my.cnf удаляем старое значение innodb_data_file_path
    и добавляем

    innodb_data_file_path=ibdata1:10M:autoextend
    innodb_file_per_table=1

  6. удалаем cледующие файлы
    • /var/lib/ibdata1
    • /var/lib/ib_logfile0
    • /var/lib/ib_logfile1
    или сколько там файлов ibdata - оставлять старые logfile нельзя!!
  7. запускаем mysqld
  8. вкатываем таблицы обратно
  9. проверяем наличие свежесозданных файликов *.ibd
  10. PROFIT!!
Да, разумеется - операция опасная по сути, поэтому - бекап, бекап и еще раз бекап.

суббота, 22 октября 2011 г.

Немного о сборке программ с dylib в MacOS

Узнать, какие зависимости у файла к библиотекам

$ otool -L yourFile

На примере злополучной библиотеки MySQL для Qt

$ otool -L /Developer/Applications/Qt/plugins/sqldrivers/libqsqlmysql.dylib
/Developer/Applications/Qt/plugins/sqldrivers/libqsqlmysql.dylib:
 libqsqlmysql.dylib (compatibility version 0.0.0, current version 0.0.0)
 /opt/local/lib/mysql5/mysql/libmysqlclient_r.16.dylib (compatibility version 17.0.0, current version 17.0.0)
 QtSql.framework/Versions/4/QtSql (compatibility version 4.6.0, current version 4.6.2)
 QtCore.framework/Versions/4/QtCore (compatibility version 4.6.0, current version 4.6.2)
 /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
 /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 438.0.0)
 /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)

Включить показ динамически загружаемых библиотек runtime

# export DYLD_PRINT_LIBRARIES=1

В результате

$ nano dylib.log
dyld: loaded: /usr/bin/nano
dyld: loaded: /usr/lib/libncurses.5.4.dylib
dyld: loaded: /usr/lib/libSystem.B.dylib
dyld: loaded: /usr/lib/system/libmathCommon.A.dylib

Потом, разумеется, не забываем выключить в 0.

Изменить путь линкуемой библиотеки

$ install_name_tool -change /Developer/Applications/Qt/plugins/sqldrivers/libqsqlmysql.dylib @executable_path/libqsqlmysql.dylib ./dist/MyApp.app/Contents/MacOS/MyApp



Спасибо MikhailEdoshin

пятница, 21 октября 2011 г.

Настройка медленного MySQL - о насморках и гильотине

Последнее время часто вижу советы по оптимизации MySQL, в которых авторы сразу (не глядя на ситуацию) сразу рекомендуют - поставить Percona, поставить SSD.

Нет, конечно - варианты обновления софта и железа помогут - но этот как-то... лечить насморк гильотиной - быстро и точно пройдет. ;-) Давайте вспомним стоимость SSD - для компаний как бы пофиг, а для частного вебмастера - сумма в 500$ на дороге не валяется.


Мониторинг - всему голова

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

Стоять! ;-) Выдыхаем и думаем, теперь вдыхаем и продолжаем думать.

Вот если вы временно заболели насморком - следует ли вам прямо сейчас делать операцию по удалению гайморита? Вот и с сервером - не нужно делать скоропалительных выводов, основываясь на единичном срезе времени. В текущий момент может быть все что угодно - случайный всплеск активности ботов, забытый кем-то cron скрипт бекапа и так далее. "Ширше надо смотреть, товарищи" (с) Так что ставим мониторинг и смотрим как себя машина ведет в течении нескольких суток/недели.

Теперь немного советов для тех, кто не торопится с брутальными методами "а-ля гильотина" (с)

Прежде всего - запускаем скрипт-анализатор mysqld, мне известны два основных
После выполнения они дают рекомендации - что стоит подкрутить/изменить. Обязательно - сервер mysql перед анализом должен проработать под нагрузкой не менее 2 суток, а вообще-то - чем дольше, тем точнее будут выборки и рекомендации.

Дальше список типовых проблем mysqld

  • мало памяти на индексы (особенно критична нехватка памяти для таблиц InnoDB, MyISAM переживает ее более спокойно). Как косвенный признак - сильная загруженность диска - из-за нехватки памяти mysql отчаянно свапится/пишет tmp таблички на диск
  • много постоянно открытых коннектов к базе - уменьшаем - но опять таки - смотрим по времени - сколько РЕАЛЬНО используется.
  • для PHP - часто рекомендуют включать pconnect, на мой взгляд - оно того не стоит.
  • для InnoDB включаем innodb_table_per_file. Процесс миграции описан тут.
  • СПОРНО - если памяти много - рекомендуют загнать /tmp в RAM -> улучшится скорость работы с таблицами tmp, хотя мое мнение - если памяти хватает лучше просто дать базе памяти побольше - и временные таблички будут не нужны
  • смотрим внимательно на CurrentLockRation в результатах скрипта анализатора
    Current Lock Wait ratio = 1 : 8943
    Чем больше второе число - тем лучше.

Как увеличить Current Lock Wait? 

Тщательно изучать структуру своих таблиц и запросы - если часто идет запись, которая лочит таблицу - переводим на InnoDB, MyISAM оставляем для редко обновляющихся табличек, добавляем индексы и т.д.

Медленные запросы SQL

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

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

Через некоторое время сервер начал загибаться. При просмотре запросов к базе у меня зашевелились волосы на всех участках тела - там было что-то в стиле  JOIN ... GROUP BY CONCAT(SUBSTR(), SUBSTR())  и т.д. - уже сейчас точно не вспомню. 

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

Ну и пришлось переписывать код самому - с помошью нескольких простых запросов и мемкеша.

Итог

  • Мониторинг по времени
  • Изучение
  • И только потом - оптимизация


четверг, 20 октября 2011 г.

Как демонизировать(daemon) проект на Twisted?

Есть три способа демонизировать проект на Twisted.

1) использование родного демона twistd. По идее - это более "методически грамотный" способ, но в свое время что-то не завелся у меня "в лоб", по этому до сих пор применяю второй.

2) скрестить старый работающий демон с реактором Twisted

#!/usr/bin/python                                                                                               
import sys
import src.daemon
import procname

class YourServer(twisted.web.server.Site):
    pass

class YourDaemon(Daemon):
    name   = 'yourserverd'
    site   = None
    server = None

    #--------------------------------------------------------------------------
    def __init__(self):
        self.server = YourServer()
        Daemon.__init__(self, pidfile='/var/run/%s.pid' % (self.name.lower()) )
        procname.setprocname(self.name)

    #--------------------------------------------------------------------------
    def run(self):
        self.server = YourServer()
        reactor.listenTCP(self.server.port, self.server)
        reactor.run()

if __name__ == '__main__':
      daemon = YourDaemon()
      daemon.processAction(sys.argv)

Да, procname служит для переименования процесса, о чем писал тут.


3) есть еще правда и python-daemon (PEP-3143), надо бы повнимательней изучить, но думаю что родной twistd оптимальней.

Вопрос Python+Mac+Qt+MySQL+py2app

Джентельмены (ну и дамы, разумеется), а никто на Python под Мак/кросплатформенно, да еще и с особыми извращениями (Qt+MySQL) не пишет случайно? Да еще и все это извращение в приложения .app не собирает, случаем?

Есть проблемка, а спросить не у кого, приходится на StackOverflow постить вопросы.

Заранее спасибо!

Да, "мсье знает толк..." (с)

среда, 19 октября 2011 г.

Как настроить Nginx + php-fastcgi для Wordpress?

По просьбе Олега "TheAppleGeek" выкладываю рабочий конфиг Ngnix с php-fastcgi для Wordpress c включенным плагином W3 Total Cache
server {
    listen 80;
    server_name host.ru;
    index index.php;
    root /var/www/vhosts/host.ru/httpdocs;

    location ~ \.php$ {
                limit_conn three 20; 
                include         /etc/nginx/include.d/default_fastcgi_params.conf;
                fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass    php;
    }

    location ~ /\.ht {
        deny all;
    }

    if (!-e $request_filename) {
        rewrite ^(.+)$  /index.php   last;
    }
}

и общий для всех хостов на машине /etc/nginx/include.d/default_fastcgi_params.conf
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

fastcgi_connect_timeout 60;
fastcgi_send_timeout 60;
fastcgi_read_timeout 60;

Aperture 3.2 падает после обновления случайным образом

Нет, определенно -  после моего отъезда Apple распоясалась - сегодня очередное подтверждение.

После обновления Aperture 3.2 случайным образом падает в самопроизвольных местах - да так, что работа напоминает хождение по минному полю - рванёт в любую секунду.

На форуме Apple уже 6 страниц гневных посланий и баг идентифицировали - если у вас старая машина с CoreDuo (не Core2Duo - это первые серии машин с Intel, 2006 год) и RAW файлы - вы почти обречены.

Пока единственный вариант - НЕ ОБНОВЛЯТЬСЯ на 3.2, оставаясь на Aperture 3.1.3

 - либо уже если поторопились и обновились - то спасет только восстановление из бекапа TimeMachine. Но при мысле о восстановлении 25 Гб лично мне как-то становится грустно.

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

Нет, Apple определенно уже не торт...  "Грусть-печаль" (с) ;-(