Analitycs

Показаны сообщения с ярлыком решения. Показать все сообщения
Показаны сообщения с ярлыком решения. Показать все сообщения

пятница, 23 декабря 2011 г.

Как удалить MacPorts?

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

После 2 дней попыток обойти все баги перекомпиляции MacPort, решил их снести к чертовой матери и попробовать собрать все начисто.

Итак, как удалить MacPorts?


# port -f uninstall installed

После чего ставлю/собираю заново то, что нужно - пока "коробочка жужжит" (с) ;-)

Если же нужно вычистить всю жизнедеятельность MacPorts из системы, то


$ sudo rm -rf /opt/local \
    /Applications/DarwinPorts  /Applications/MacPorts \
    /Library/LaunchDaemons/org.macports.* /Library/Receipts/DarwinPorts*.pkg \
    /Library/Receipts/MacPorts*.pkg /Library/StartupItems/DarwinPortsStartup \
    /Library/Tcl/darwinports1.0 /Library/Tcl/macports1.0 \
    ~/.macports

Да, если у вас вторая версия - то удаляемые каталоги, разумеется, меняются на те, что у вас. 

Найдено тут, HomeBrew ставить не собираюсь. ПОКА не собираюсь, во всяком случае.

среда, 21 декабря 2011 г.

Как сохранить/восстановить настройки-сайты/Sites в Panic Coda под MacOS?

Вот всем хороша Coda, но при восстановлении данных из бекапа или переносе профиля на другую машину - часто теряются настройки проектов - Sites. А если их много... и там прошита куча паролей... то жить честному разработчику становиться совсем грустно;-(

В отличие от Transmit - в ней нет встроенного механизма бекапа/переноса, но как обычно - почти любую проблему можно решить и не "в лоб" - можно "ручками" перенести файл настроек, который находится в

~/Library/Preferences/com.panic.Coda.plist

Где ~/ ваш домашний каталог.

P.S. И да, принимаю поздравления с долгожданным новым Pro 13' (MD314RS/A). Теперь Aperture ведет себя вполне прилично - и даже матрица нормальная, без цветовых искажений ;-) ;-)

/me почти счастлив ;-)




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

Как сделать sharding картинок в PHP между несколькими серверами?

Сегодня небольшой хак - боюсь, что скоро их будет тут больше, чем методически грамотных решений. ;-(

Когда вам нужно разшардить картинки/статические ресурсы по разным поддоменам для ускорения загрузки - можно использовать очень-очень грязный хак.

Дано

4 поддомена:
  • http://st1.xxx.ru
  • http://st2.xxx.ru
  • http://st3.xxx.ru
  • http://s4.xxx.ru
По ним и нужно раскидывать превьюшки - особенно это актуально, когда их много на страницах.

Функция получения url для превьюшки картинки после небольшой доработки выглядит так

 public function thumb_url($file = false) {
  $path = $this->path_by_file($file);
  $url = CMS_URL.'/'.$path.'/thumbs/'.$file;
  
  $key = md5($url) & 3;
  
  $static_url = 'http://st'.($key+1).'.xxx.ru/'.$path.'/thumbs/'.$file;
  
  return $static_url;
 }

Чем плох этот вариант?

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

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

Короче - не делайте так.

А как правильно?

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

вторник, 29 ноября 2011 г.

Как включить показ ошибок PHP в браузере?

Классический вопрос всех похапешников - "как показать ошибки PHP скрипта в окне браузера"

error_reporting(E_ALL);
ini_set("display_errors", 1);

P.S. Причем сам постоянно забываю, как точно пишется эта конструкция - особенно после переключения с языка на язык. Ненавижу переключать контекст мозга ;-)

четверг, 24 ноября 2011 г.

Как сделать автодополнение git в MacOS X?

При установке git возникает ошибка и автодополнение не работает

-bash: __git_ps1: command not found

Лечение (работаю со SnowLeopard)

Ставим MacPorts из .dmg, затем в консоли

$ sudo port selfupdate
$ sudo port install git-core +bash_completion

Если нужна дополнительная работа с SVN и docs, вторую строчку заменяем на:


$ sudo port install git-core +bash_completion +doc +svn

Затем добавляем в ваш ~/.profile или ~/.bash_profile:

# MacPorts Bash shell command completion
if [ -f /opt/local/etc/bash_completion ]; then
    . /opt/local/etc/bash_completion
fi

среда, 23 ноября 2011 г.

Как распаковать содержимое rpm-пакета?

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

Обычный rpm-пакет - это архив формата cpio вместе с некоторым набором метаданных.

Распаковать его можно

# rpm2cpio package.rpm | cpio -dimv

Параметры и флаги



  • имя rpm-файла, который необходимо распаковать и перенаправить вывод на архиватор cpio.
  • -i - распаковать архив,
  • -d - сохранить структуру директорий.
  • -v - вывести список распакованных файлов,
  • -m - наследовать даты модификаций извлекаемых файлов.
  • PHP - хак быстрого логгирования в файл


    Если вам в зубы выдали какой-то очередной супер-мега-пупер проект на PHP, в дебрях которого нет возможности и желания разбираться, однако нужно что-то быстро пофиксить с отладкой, (причем доступа к php error_log нету) - то можно быстро воткнуть небольшой полезный хак.

    Это дополнительный метод в класс (или просто - функция) с минимальным количеством кода.

       function log($msg) {
           file_put_contents(SUPER_CMS_ROOT_PATH.'/cache/php-debug.log',"\n".$msg, FILE_APPEND);
       }
    

    Соотвественно, после отладки ее можно либо убить, либо оставить, закомментировав содержимое.

    P.S. И да -про некошерность данного метода и недопустимости этого при учете всех методик программирования - я в курсе, не нужно возбуждаться. ;-)
    Просто нужно пофиксить и отладить - БЫСТРО.

    воскресенье, 20 ноября 2011 г.

    Как на python проверить, открыт ли какой-то port?


    from socket import socket, gethostbyname, AF_INET, SOCK_STREAM
    
    target = "localhost"
    targetIP = gethostbyname(target)
    port = 80
    s = socket(AF_INET, SOCK_STREAM)
    
    result = s.connect_ex((targetIP, port))
    
    if(result == 0) :
     print 'Port %d is open' % (port,)
    s.close()
    

    суббота, 19 ноября 2011 г.

    Как запустить приложение MacOS X из terminal.app с передаваемым файлом?

    Когда работаешь в консоли - иногда лень тянуться к мышке, а запустить какой-то сложный редактор нужно. Тогда используется полезная программа open

    $ open -a TextMate ./README

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

    Как реализовать периодические задачи в Twisted? (cron vs LoopingCall)

    Первое что делают все программисты на Twisted, чтобы сделать периодические задачи - это лезут в cron. Я сам так раньше делал - и, к сожалению, не было никого рядом, чтобы стукнуть меня бамбуковой палкой по рукам.

    Есть же методически грамотное, ВСТРОЕННОЕ решение - и нашел я его сегодня случайно, когда искал совершенно другую вещь.

    from twisted.internet.task import LoopingCall
    
    #==============================================================================
    class MySuperServer(MyServer, twisted.web.server.Site):
        '''
        мой собственный веб-сервер, с блекджеком и шлюхами ;-)
        '''
    
        def __init__(self):
            lp = LoopingCall(self.checkStatus)
            lp.start(1.0) # период в секундах    
    
        def checkStatus(self):
            #self._log('Looping call')
            pass
    

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

    Chef creating new cookbook - rake aborted! Don't know how to build task

    При попытке создания нового cookbook для Chef по некоторым мануалам вываливается ошибка

    # rake new_cookbook COOKBOOK=xxx CB_PREFIX=site-
    rake aborted!
    Don't know how to build task 'new_cookbook'
    

    Причина - прямое использование rake тут было deprecated, потом вообще убрали. Теперь труЪ-путь для подобных операций - только использование knife, командной утилиты Chef.

    
    
    # knife cookbook create xxx
    

    Вот не люблю ruby за это очень сильно - ведь был же суслик... а теперь его нету. ;-(

    четверг, 10 ноября 2011 г.

    Синхронизация времени на CentOS/Fedora

    Как поправить разошедшееся время на CentOS/Fedora

    $ sudo yum update tzdata -y
    

    Проверить/выставить

    $ cat /etc/sysconfig/clock 
    ZONE="Europe/Moscow" 

    И под конец запустить

    $ sudo chkconfig --level 345 ntpd on && sudo service ntpd start
    

    Подрезано тут (спасибо sanjek65)

    среда, 9 ноября 2011 г.

    PHP header("HTTP/1.0 404 Not Found") показывает пустую страницу

    При отправке из PHP скрипта HTTP ошибки 404 - показывается белая страница, хотя в настройках вашего веб сервера явно задана собственная красивая страничка для этой ошибки.

    Как лечить?

    Просто считать содержимое файла с красивой 404 ошибкой и вывести его HTML в поток - примерно так
    if ($is404) {
     $html = file_get_contents(YOUR_ROOT_PATH.'/404.htm');
     header("HTTP/1.0 404 Not Found");
     echo $html;
     exit();
    }
    
    

    четверг, 3 ноября 2011 г.

    Python, Twisted, logging - Как логгировать несколько процессов/демонов в один файл?

    Давайте поговорим немного про логгирование в Python.

    Да, меня это ДЕЙСТВИТЕЛЬНО беспокоит, и я хочу об этом поговорить ;-)

    Совсем недавно столкнулся с тем, что достаточно серьезный проект при портировании с Linux на MacOS потерял логгирование. Ну нет лог файла - и все тут. Полез в код разбираться - выяснилось, что разработчики очень любили изобретать велосипеды и делали логгирование через файл, открытый ручками и обычную запись туда переменных - прямо в файл. Все это работало... до поры до времени. Пришлось на скору руку переписывать.

    В общем, мораль сей басни такова...

    Есть в Python СТАНДАРТНЫЙ модуль logging  - его и нужно использовать для разного типа логгирования. Батарейка-то уже включена ;-)

    Чтобы пример кода не был совсем тривиальным - приведу решение для той ситуации, когда у нас есть несколько многопроцессных РАЗНЫХ демонов на Twisted на одной машине, а еще и cron-скрипт запускается время от времени. И всю жизнедеятельность этого дурдома нужно логгировать в один файл

    import os
    import logging
    from twisted.python import log                                                                                   
    
    CURRENT_PATH = os.path.realpath(os.path.dirname(__file__))
    
    # Все это "по уму" обычно запихивается в нормальный конфиг-файл
    LOG_DIR = os.path.join(CURRENT_PATH, 'logs')                            
    LOG_FILE = os.path.join(LOG_DIR, 'super-puper.log')  
    LOG_LEVEL = logging.INFO
     
    # инициализируем
    FORMAT = ('%(asctime)-15s %(levelname)s %(message)s') 
    
    if not os.path.exists(LOG_DIR):
        os.mkdir(LOG_DIR) 
     
    logging.basicConfig(format=FORMAT, filename=LOG_FILE, handler=logging.handlers.RotatingFileHandler)   
    observer = log.PythonLoggingObserver(loggerName='twisted')
    observer.start()
    observer.logger.setLevel(LOG_LEVEL)  
    
    # класс-примесь для логгирования - в принципе - необязательно, реализация может быть разная - хоть функциями
    class BasicLogClass():
    
        def _log(self, msg):
            log.msg(msg, logLevel=logging.INFO)
    
        def _error(self, msg):
            log.msg(msg, logLevel=logging.ERROR)
    
        def _warning(self, msg):
            log.msg(msg, logLevel=logging.WARNING)
    

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

    Кстати, если у кроновских скриптов нет использования twisted'овского reactor, то могуть быть проблемы, нужно подумать. Как вариант - использовать развилку в инициализации и логгировании без применения observer, но не уверен.

    вторник, 1 ноября 2011 г.

    Как исправить переход на зимнее время в MacOS X Snow Leopard 10.6.8?

    Проблема 2011 года подкралась незаметно - новые машины с Lion не пострадали, а вот Snow Leopard честно перевел часы, не зная о новом приказе президента РФ.

    Варианта решения два

    1) Поставить другой TimeZone в настройках

    2) Отхачить по аргентинскому рецепту (первый хак для консоли, второй для GUI)

    mkdir temp
    cd temp
    curl -O http://www.iana.org/time-zones/repository/releases/tzdata2011m.tar.gz
    tar zxvf tzdata2011m.tar.gz
    sudo zic europe
    
    curl -O http://www.opensource.apple.com/tarballs/ICU/ICU-400.42.tar.gz
    tar zxvf ICU-400.42.tar.gz
    cp tzdata2011m.tar.gz ICU-400.42/icuSources/tools/tzcode/
    cd ICU-400.42/icuSources
    ./runConfigureICU MacOSX --with-data-packaging=archive
    gnumake
    sudo install -o root -g wheel -m 0644 -Sp data/out/icudt40l.dat /usr/share/icu/icudt40l.dat
    cd ../../..
    rm -rf temp
    
    
    Источник 

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

    Как переименовать home directory в MacOS?

    Так как я свою текущую систему не очень грамотно восстанавливал из бекапа с TimeCapsule,  то у меня в имени пользователя появился пробел (/Users/michael_xiiii\ 1), в связи с чем я постоянно и ловил проблемы на различных компиляциях. Под конец меня это достало, и я решился мигрировать. Разумеется - перед миграцией необходимо тщательно забекапится.

    Теперь - пошаговая инструкция, как переименовать папку пользователя в MacOS.

    1. Включить  root пользователя в MacOS (Надеюсь, что все в курсе - как это сделать?). 
    2. Войти как root. 
    3. Перейти в папку /Users. 
    4. Выберать главную папку с коротким именем, которую вы хотите изменить, и переименовать ее - как необходимо. Имейте в виду, что короткое имя должно быть все в нижнем регистре, без пробелов и содержать только латинские буквы. (прим. нижнее подчеркивание и цифры вроде тоже без особых проблем) 
    5. Использовать Пользователи и группы (Accounts в Mac OS X v10.6.8 или более ранней) в Системных настройках, чтобы создать нового пользователя с именем учетной записи или ником, которое использовалось в предыдущем шаге. 
    6. Нажмите OK, когда появится сообщение что "Такая папка Пользователя уже существует "ВАШ_LOGIN". Хотели бы Вы использовать эту папку для домашней папки для этой учетной записи"?  Примечание: Это исправит права доступа/владения - во избежание проблем.
    7. Выбрать "Выйти" из главного меню Apple. 
    8. Войти в качестве вновь созданного пользователя. 
    9. Вы должны получить доступ ко всем вашим оригинальным файлам (на рабочем столе, в документах и в других папках). Убедившись, что все ваши данные доступны, можно удалить старую учетную запись пользователя. 
    10. Отключить корневого пользователя.
    Найдено у Apple.

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

    Распространение приложений на twisted

    Как выяснилось - nobody cares по поводу фигурок, так что продолжу сношать вам мозг выкладывать технические статьи и старые переводы.

    Моя работа — создание различных приложений на Twisted для работы с многочисленными веб-сервисами. В отличие от проектов на TurboGears, которые я распространяю как eggs с помощью easy_install (через setuptools) у меня не было удобного способа «выкатить» проекты на Twisted.

    До этого момента.

    Twisted преодставляет удобную систему плагинов, которые позволяют приложениям встраиваться в «twistd» стартер.

    Только одна проблема — полное отсутствие приличной документации об этом процессе.

    Ниже я хочу привести небольшой рассказ о том, как можно собрать простое приложение в пакет twisted. На самом деле — я возьму известный туториал — Twisted finger и допишу шаг №12: «Как создать пакет для finger как приложение Twisted для twistd» (aka «Пропущенный шаг»).

    Step 12: How to package the finger service as an installable Twisted application plugin for twistd

    Создайте структуру каталогов, как показано ниже

    finger
    finger/__init__.py
    finger/finger.py
    MANIFEST.in
    setup.py
    twisted
    twisted/plugins
    twisted/plugins/finger_plugin.py
    

    finger/finger.py — приложение finger отсюда. twisted/plugins — структура каталогов, содержит файл finger_plugin.py, который будет описан ниже.

    Обратите внимание — никаких файлов __init__.py в каталогах twisted и twisted/plugins — это важно!

     finger_plugin.py реализует интерфейсы IServiceMaker и IPlugin.
    # ==== twisted/plugins/finger_plugin.py ====
    # - Zope modules -
    from zope.interface import implements
    
    # - Twisted modules -
    from twisted.python import usage
    from twisted.application.service import IServiceMaker
    from twisted.plugin import IPlugin
    
    # - Finger modules -
    from finger import finger
    
    class Options(usage.Options):
        synopsis = "[options]"
        longdesc = "Make a finger server."
        optParameters = [
            ['file', 'f', '/etc/users'],
            ['templates', 't', '/usr/share/finger/templates'],
            ['ircnick', 'n', 'fingerbot'],
            ['ircserver', None, 'irc.freenode.net'],
            ['pbport', 'p', 8889],
        ]
        
        optFlags = [['ssl', 's']]
    
    class MyServiceMaker(object):
        implements(IServiceMaker, IPlugin)
        
        tapname = "finger"
        description = "Finger server."
        options = Options
        
        def makeService(self, config):
            return finger.makeService(config)
    
    serviceMaker = MyServiceMaker()
    


    setup.py стандартный файл установщика. Обратите внимание на аргументы «packages» и «package_data» в функции setup() и функцию- refresh_plugin_cache(), которая вызывается после того, как полностью отработает setup()s. Последняя вручную сбросит кэш плагинов Twisted (twisted/plugins/dropin.cache).
    # ==== twisted/plugins/finger_plugin.py ====
    '''setup.py for finger.
    
    This is an extension of the Twisted finger tutorial demonstrating how
    to package the Twisted application as an installable Python package and
    twistd plugin (consider it "Step 12" if you like).
    
    Uses twisted.python.dist.setup() to make this package installable as
    a Twisted Application Plugin.
    
    After installation the application should be manageable as a twistd
    command.
    
    For example, to start it in the foreground enter:
    $ twistd -n finger
    
    To view the options for finger enter:
    $ twistd finger --help
    '''
    
    __author__ = 'Chris Miles'
    
    
    import sys
    
    try:
        import twisted
    except ImportError:
        raise SystemExit("twisted not found.  Make sure you "
                         "have installed the Twisted core package.")
    
    from distutils.core import setup
    
    def refresh_plugin_cache():
        from twisted.plugin import IPlugin, getPlugins
        list(getPlugins(IPlugin))
    
    if __name__ == '__main__':
        
        if sys.version_info[:2] >= (2, 4):
            extraMeta = dict(
                classifiers=[
                    "Development Status :: 4 - Beta",
                    "Environment :: No Input/Output (Daemon)",
                    "Programming Language :: Python",
                ])
        else:
            extraMeta = {}
    
        setup(
            name="finger",
            version='0.1',
            description="Finger server.",
            author=__author__,
            author_email="you@email.address",
            url="http://twistedmatrix.com/projects/core/documentation/howto/tutorial/index.html",
            packages=[
                "finger",
                "twisted.plugins",
            ],
            package_data={
                'twisted': ['plugins/finger_plugin.py'],
            },
            **extraMeta)
        
        refresh_plugin_cache()
    

    MANIFEST.in содержит одну строчку, которая, как я полагаю, указывает distutils изменить существующий пакет Twisted (для установки twisted/plugin/finger_plugin.py) и нечто наподобие. graft twisted Это все для того, чтобы можно было начать установку пакета обычным способом:

    $ python setup.py install

    После этого нужно запустить twistd — чтобы убедится, чтто приложение установилось нормально и доступно. Посмотрите на опции twistd:

    $ twistd --help
    
    Usage: twistd [options]
    
     ...
    
    Commands:
     athena-widget Create a service which starts a NevowSite with a single
     page with a single widget.
     ftp An FTP server.
     telnet A simple, telnet-based remote debugging service.
     socks A SOCKSv4 proxy service.
     manhole-old An interactive remote debugger service.
     portforward A simple port-forwarder.
     web A general-purpose web server which can serve from a
     filesystem or application resource.
     inetd An inetd(8) replacement.
     vencoderd Locayta Media Farm vencoderd video encoding server.
     news A news server.
     words A modern words server
     toc An AIM TOC service.
     finger Finger server.
     dns A domain name server.
     mail An email service
     manhole An interactive remote debugger service accessible via
     telnet and ssh and providing syntax coloring and basic
     line editing functionality.
     conch A Conch SSH service.
    
    
    
    Посмотрим опции нашего сервера finger в плагине:

    $ twistd finger --help
    Usage: twistd [options] finger [options]
    
    Options:
    
     -s, --ssl 
     -f, --file= [default: /etc/users]
     -t, --templates= [default: /usr/share/finger/templates]
     -n, --ircnick= [default: fingerbot]
     --ircserver= [default: irc.freenode.net]
     -p, --pbport= [default: 8889]
     --version 
     --help Display this help and exit.
    
    Make a finger server.
    
    
    
    Запустим сервер finger в консоли:

    $ sudo twistd -n finger --file=users
    
    2007/12/23 22:12 +1100 [-] Log opened.
    2007/12/23 22:12 +1100 [-] twistd 2.5.0 (/Library/Frameworks/Python.framework/
    Versions/2.5/Resources/Python.app/Contents/MacOS/Python 2.5.0) starting up
    2007/12/23 22:12 +1100 [-] reactor class: 
    2007/12/23 22:12 +1100 [-] finger.finger.FingerFactoryFromService starting on 79
    2007/12/23 22:12 +1100 [-] Starting factory 
    2007/12/23 22:12 +1100 [-] twisted.web.server.Site starting on 8000
    2007/12/23 22:12 +1100 [-] Starting factory 
    2007/12/23 22:12 +1100 [-] twisted.spread.pb.PBServerFactory starting on 8889
    2007/12/23 22:12 +1100 [-] Starting factory 
    2007/12/23 22:12 +1100 [-] Starting factory 
    

    twistd предоставляет многочисленные полезные возможности — такие как запуск демона, указания расположения лог и pid файлов и т.д…

    К сожалению Twisted и setuptools не очень хорошо взаимодействуют вместе, так что я не смог упаковать мое приложение Twisted как egg, нужно повозится с системой разрешения зависимостей setuptools, или установить используя easy_install.

    Ссылки



    Источник, хабра

    понедельник, 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())  и т.д. - уже сейчас точно не вспомню. 

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

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

    Итог

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