среда, 27 июля 2016 г.

Git - минимизация merge-commit'ов в master

У нас небольшая команда разработки и, зачастую, мы правки делаем прямо в master.
В среднем у нас 16 commit'ов в день (от 1 до 45), поэтому периодически сталкиваюсь с тем, что кто-то за'push'ил в мастер в центральный репозиторий одновременно со мной, а я забыл с'pull'иться перед своим commit'ом. После слияния веток возникают грязные commit'ы вида:

845f25b 2016-07-26 (Some User) -  Merge branch 'master' of github.com:Company/repository

Чтобы избегать commit'а в мастер, когда в центральном репозитории кто-то что-то поменял, можно использовать hook на pre-commit:

cat .git/hooks/pre-commit

#!/bin/sh

red="\033[01;91m"
green="\033[01;32m"
reset="\033[0m"

branch=`git rev-parse --abbrev-ref HEAD`
if [ a$branch == amaster ]
then
git fetch origin master >/dev/null 2>&1
local_commit=`git rev-parse --verify HEAD`
origin_commit=`git rev-parse --verify origin/master`
#if [ a$local_commit != a$origin_commit ]
if ! git log | grep -qs $origin_commit
then
echo
echo "${red}origin/master ушел вперед.${reset} Сделай сначала: ${green}git pull origin master${reset}"
echo
exit 1
fi
fi
exit 0

Надо отметить, что такой подход не гарантирует отсутствие merge-commit'ов, но если все свои изменения сразу после commit'а push'ить в центральный репозиторий, то таких ситуаций будет крайне мало.

понедельник, 18 января 2016 г.

Как склонировать SD-карту под Mac OS X

Возникла задача, нужно сделать 6 клонов для одной SD карты.

Нашел в сети описание, как склонировать SD-карту под Mac OS X.

sudo dd if=/dev/disk2 of=/Users/ruzin/raspberrypi.dmg
sudo dd of=/dev/disk2 if=/Users/ruzin/raspberrypi.dmg

Процесс занял нереальное время (я даже не дождался создания первого дубликата - прервал через 45 минут). В моем случае скорость копирования с диска на карту составляла 1 Мбайт/с. Потом нашел способ, как поднять скорость в 13 раз (до ~13 Мбайт/с): 

Процедура:

  1. Вставляем исходную карту и делаем копию образа к себе на диск:

    sudo dd if=/dev/rdisk2 of=/Users/ruzin/raspberrypi.dmg bs=1m
  2. Перед заменой карты отмонтируем ее от файловой системы:

    diskutil unmountDisk /dev/disk2
  3. Вставляем пустышку (она автоматически монтируется) и отмонтируем ее:

    diskutil unmountDisk /dev/disk2
  4. Копируем на нее образ (и отмонтируем перед вытаскиванием):

    sudo dd of=/dev/rdisk2 if=/Users/ruzin/raspberrypi.dmg bs=1m
    diskutil unmountDisk /dev/disk2

Копия диска заняла ~10 минут для карты размером в 8GB.

среда, 23 декабря 2015 г.

При использовании конструкции:

LOAD DATA LOCAL INFILE '/path/to/file.data' REPLACE INTO TABLE `table` (id, ...)

Столкнулся с проблемой:

EException django.db.utils.OperationalError: OperationalError(1148, 'The used command is not allowed with this MySQL version') in <bound method MySQLLoader.__del__ of <libs.db.loader.MySQLLoader object at 0x10c0ccb90>> ignored

На моем Mac вылечилось добавлением в /etc/my.cnf двух строк:

[mysqld]
local_infile=1...
[client]
local_infile=1...

среда, 7 октября 2015 г.

Удаление значительного числа строк из большой таблицы MySQL

Если у вас большая таблица (скажем, 10+ млн.строк), то удаление значительной части строк (скажем, 20+%) из нее может стать проблемой.


  1. Во-первых, эта операция будет занимать длительное время и некоторые операции на выборку/модификацию данных в эту таблицу все это время нельзя будет произвести.
  2. Во-вторых, удаление строк не освободит место на диске.


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

    create table <new_table> like <old_table>
  2. запомнить максимальный id в старой таблице:

    select max(id) from <old_table>
    Записываем на лист бумаги ;-)
  3. переставить id (автоинкрементный) в новой таблице на это max(id) + запас (скажем +2 миллиона):

    ALTER TABLE <new_table> AUTO_INCREMENT=<old_value>+2000000

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

    insert into <new_table> select * from <old_table> where ...
  5. переименовать обе таблицы:

    RENAME TABLE <old_table> TO <very_old_table>, <new_table> TO <old_table>

    Да, можно делать переименование двух таблиц за одну операцию.
  6. проверить, что максимальные ID в обеих таблицах совпадают. Если не совпадают, докопировать недостающие записи из старой таблицы в новую:

    insert into <new_table> select * from <old_table> where ... and id > <max(id)>

    <max(id)> берем из второго шага.
  7. удалить старую таблицу

    drop table <very_old_table>

Обещал пару трюков к шагу 4:

Что делать, если условие по определению хороших или плохих строк очень сложное? Можно отдельными запросами сохранить хорошие или плохие ID в отдельную таблицу (с одним полем ID). А потом при-JOIN-ить эту таблицу к нашему селекту.

Для хороших:

insert into <new_table> select * from <old_table> join <good_ids> on <old_table>.id=<good_ids>.id

Для плохих:

insert into <new_table> select * from <old_table> left join <good_table> on <old_table>.id=<bad_ids>.id where <bad_ids>.id is NULL

Чтобы JOIN'илось быстро, следует по колонке id в таблице good/bad_ids построить индекс.

воскресенье, 28 июня 2015 г.

Во что обойдется скачать весь интернет?

Читая новость о том, что http://archive.org/web/ претерпевает изменения, задумался во что обойдется скачать весь интернет?

Для начала решил оценить объем информации:
Google проиндексировал 46 млрд. страниц (http://www.worldwidewebsize.com/).
В действительности, страниц может быть больше, т.к. не все заслуживают индексации.

60Kb - средний размер HTML-страницы (https://gigaom.com/2014/12/29/the-overweight-web-average-web-page-size-is-up-15-in-2014/)
Верить этому числу нельзя, но за неимение лучшего...

Итого требуется скачать ~3000 ТБ (это не считая картинок, видео, музыки и пр.)

Далее нам нужны сервера, каналы и хранилище.
Для скачивания информации подойдут самые простые сервера, т.к. нагрузка на CPU - минимальная.
Подключение к интернету желательно быстрое - из мейнстрима - 1Gbit/sec (пиковая 10Тб/день, на практике, раза в 3 меньше)
Хранилище - самые большие из самых дешевых дисков (4Тб/диск)

Если набирать конфигурацию в дата-центре serverloft, предпочитаемом мной с точки зрения качество/цена.

$214 за конфигурацию с 16TB SATA на канале в 1Gbit/sec

Итого нам потребуется ~190 серверов и 5 дней (если дата-центр сможет обеспечить суммарный объем входящего трафика 63Gbit/sec).

Обойдется все это удовольствие в ~$40000/месяц

В своих расчетах я не учитывал:

  • разработку софта, который должен понимать, что скачено, а что нет
  • недоступность каких-то серверов (проблемы с DNS, обслуживание серверов, загрузку местных каналов)
  • медленную отдачу веб-серверов

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

Я оптимист? ;-)

суббота, 28 марта 2015 г.

Пара фишек для разработчиков JavaScript & MongoDB

После просмотра туториалов EventedMind по-мимо основного содержимого вынес две полезные штуки:

  1. JavaScript: ключевое слово debugger приостанавливает выполнение кода (в Chrome). После чего можно будет по шагам пронаблюдать, что происходит.

    var a = 3;
    debugger;
    // some code we want to debug
    _
  2. MongoDB: с консоли mongodb можно посмотреть результат выборки, обычно он выводится в неудобоваримом виде:

    > db.collection.find()

    {"_id" : "WHdEadDwWnwn7GYzg", "createdAt" : ISODate("2014-12-09T11:24:32.154Z"), "emails" : [{"address" : "dasha@yandex.ru"}], "profile" : {"name" : "Даша"},...}

    Это легко исправить, достаточно приписать .pretty()

    > db.collection.find().pretty()

    {
      "_id" : "WHdEadDwWnwn7GYzg",
      "createdAt" : ISODate("2014-12-09T11:24:32.154Z"),
      "emails" : [
        {
          "address" : "dasha@yandex.ru"
        }
      ],
      "profile" : {"name" : "Даша"},
      ...
    }





воскресенье, 18 января 2015 г.

Мозг тренирует себя на отвлечения

В книжке "Sort you brain out" Dr.Jack Lewis & Adrian Webster нашел интересную главу:
Brain training ourselves to distraction.

Краткая цитата на английском:
... people who regularly use technology to do multiple tasks at the same time are less able to ignore distractions than those who don't.
  и мой вольный перевод:
... люди, которые используют инструменты для одновременного решения задач, хуже сопротивляются отвлечениям, чем остальные.
Инструментов, помогающие вам быть в курсе текущих событий, препятствует вашему движению. Сохраняйте баланс. Реже проверяйте почту/skype и т.п. - больше делайте :)