Порядок определения дисков в Linux

Стыдно признаться, НЕДЕЛЮ устанавливал Ubuntu на сервер. Проблемы начались после того, как я тестировал сервер под Windows с динамическими GPT дисками. Видать винда что то там сделала с областью загрузчика и после установки Ubuntu загрузка заканчивалась на мигающем курсоре, даже до Grub не доходило. Я долгое время тупил и что то там делал с MD RAID массивом при установке, пока не догадался, что порядок дисков для загрузки в BIOS и Linux отличается, а Ubuntu этого не просек. Windows, кстати, это определил и создавал 100 мегабайтный загрузочный раздел не на первом диске в списке дисков. В результате я не стал вспоминать как инсталлировать GRUB вручную с rescue диска, а просто инсталлировал Ubuntu на все диски поочередно оставляя их единственными в шасси. После этого заработала загрузка в нужной конфигурации software RAID. Вот выдержка по этому поводу из исходников драйвера:

4.4. Controlling Boot order on non SES-2 systems
    Linux discovers drives by walking sequentially through
    each channel/target/lun of the host adapter, mapping the
    drives that it finds sequentially to sda, sdb, sdc, etc.
    SAS, on the other hand, does not guarantee what order
    drives will be discovered, or appear.  Because of this
    "drive drift" (different than migration) a mechanism is
    needed to guarantee that SAS drives will be consistently
    mapped to device names.  The Razor BIOS provides a
    mechanism for determining what order drives have been
    reported to the system BIOS.  Because of the different
    mechanisms that system BIOS vendors use to manage
    devices in BIOS and because of the limited size of the
    Razor OCM structures, the Razor BIOS structures can not
    be use to consistently map all drives to a unique device
    name that persists across boots.
    The only way to solve the problem of "drive drift" is to
    require that users assign a UUID or label to the
    filesystems on their drives.  In addition, because swap
    does not support labels or UUIDs, we should recommend
    that the users use swap files instead of swap
    partitions.

Репликация MySQL на уже работающем сервере

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

При использовании описанного ниже подхода стоит рассчитывать на даунтайм основного сервера на время его перезапуска. В примере использовался сервер под управлением Ubuntu и MySQL 5.0 из основного репозитория с настройками по умолчанию. Я исходил из того, что реплицировать нужно все базы данных, за исключением системных.

На главном сервере.

Надо поправить файл /etc/mysql/my.cnf:

[mysqld]
# Необходимо открыть доступ к серверу по сети,
# что бы slave имел возможность подключиться
# и не забыть закрыть этот доступ, например файрволом, для тех, кому он не нужен
bind-address            = 0.0.0.0
server-id               = 1
log_bin                 = /var/log/mysql/mysql-bin.log
expire_logs_days        = 10
max_binlog_size         = 100M
# Исключим ненужные БД
#binlog_do_db           = include_database_name
binlog_ignore_db        = information_schema
binlog_ignore_db        = mysql
binlog_ignore_db        = test
# Это рекомендуется для более стабильной работы репликации баз на InnoDB
innodb_flush_log_at_trx_commit=1
sync_binlog=1

Перезапускаем mysql:

/etc/init.d/mysql restart

Выдаем slave права на репликацию:

mysql -u root
GRANT REPLICATION SLAVE ON *.* TO 'replication'@'10.0.0.2' IDENTIFIED BY 'slave_password';
FLUSH PRIVILEGES;

Посмотреть статус можно командой:

SHOW MASTER STATUS;
+------------------+----------+--------------+-------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB              |
+------------------+----------+--------------+-------------------------------+
| mysql-bin.000015 |       98 |              | information_schema,mysql,test |
+------------------+----------+--------------+-------------------------------+
1 row in set (0.00 sec)

Далее делаем дамп существующих баз данных. Ключи –single-transaction –master-data –flush-logs должны глобально заблокировать на время дампа базу данных на запись и вписать в дамп номер и позицию лога, с которых надо начать репликацию на slave. Это обеспечит точность совпадения данных на главном и slave серверах, даже если с главным сервером в этот момент идет работа и записываются данные.

mysqldump -u root --single-transaction --master-data --flush-logs --databases db1 db2 db3 > ALL_DB.sql

Если посмотреть внутрь ALL_DB.sql, то там должна присутствовать строка:

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000015', MASTER_LOG_POS=98;

Далее копируем дамп на slave:

scp ALL_DB.sql 10.0.0.2:

Продолжаем на втором сервере.

Убеждаемся что там нет остатков настроек репликации, в принципе, если на сервере нет нужных данных, не помешает переустановить mysql с очисткой папок БД.

Так как начиная с версии MySQL 5.2 параметры доступа для репликации убираются из my.cnf сразу перейдем на использование такой схемы.

Правим файл /etc/mysql/my.cnf:

[mysqld]
# ID slave должен отличаться от главного сервера
server-id               = 2
replicate-ignore-db     = information_schema
replicate-ignore-db     = mysql
replicate-ignore-db     = test
relay-log               = /var/log/mysql/mysqld-relay-bin.log

Перезапускаем сервер:

/etc/init.d/mysql restart

Поправим файл ALL_DB.sql:

Дописываем к строке

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000015', MASTER_LOG_POS=98;

параметры доступа:

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000015', MASTER_LOG_POS=98, MASTER_HOST='10.0.0.1', MASTER_USER='replication',
MASTER_PASSWORD='slave_password', MASTER_CONNECT_RETRY=60;

Загружаем данные:

mysql -u root < ALL_DB.sql

Проверяем состояние репликации, она НЕ должна быть запущена (Slave_IO_Running, Slave_SQL_Running: no, no):

mysql -u root
show slave status;

Запускаем репликацию (теперь должно быть Slave_IO_Running, Slave_SQL_Running: yes, yes):

START SLAVE;
show slave status;

Для проверки можно попробовать перезапустить mysql и проверить состояние репликации еще раз:

/etc/init.d/mysql restart
mysql -u root
show slave status;

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

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

Ubuntu 8.04 LTS Server Edition супротив Microsoft Virtual Server 2005

Мне всегда нравилась виртуализация от Microsoft благодаря её простоте использования и бесплатности. Когда мне нужно запустить на одном сервере несколько разных ОС, я всегда использую MS Virtual Server и совершенно не боюсь этого делать в Production.

А еще мне все больше нравится Ubuntu как ОС, когда мне нужен Unix. Например, я столкнулся с проблемой неправильности обработки русских тегов на моём блоге под FreeBSD-7.0, и решил попробовать поднять WordPress на Ubuntu в виртуальной машине.

Это оказалось совсем не просто. Если FreeBSD-7.0 устанавливалась в виртуальную машину без проблем и, по сравнению с реальным компьютером, надо было только решить проблему четкости работы часов, то с Ubuntu все пошло гораздо тяжелее. Виснет инсталляция, виснет ядро после инсталляции, опять же не работают правильно часы. Не буду вдаваться в подробности, а просто опишу как же все таки установить Ubuntu. Кстати кроме Ubuntu Server Edition существует еще и Ubuntu JeOS – специальная сборка Ubuntu для виртуальных машин. JeOS поставилась в виртуальную машину без особых проблем, но её ядро не увидело сетевой карты. Мне показалось что решить проблему со сменой или перекомпилированием ядра тяжелее чем заставить Server Edition, которая определяла сеть нормально, работать. Итак, последовательность такая:

Создаем виртуальную машину, подключаем образ диска, настраиваем автозапуск виртуальной машины. Запускаем виртуальную машину, в её биосе можно ничего не менять. Запускаемся с CD, выбираем язык:

Нажимаем F6 и добавляем перед двумя тире:
vga=791 noreplace-paravirt

Далее жмем Enter и запускаемся.

Vga=791 переводит экран в расширенный текстовый режим и избавляет от лишних проверок на тип графического адаптера. У меня несколько раз виртуальная машина входила в какой-то непонятный графический режим, а эта опция позволяет этого избежать. К тому же потом удобнее работать с большей в 2 раза консолью.

Дальше проводим инсталляцию как обычно по своим требованиям.

Если мы попытаемся запустить машину сразу после инсталляции, даже добавив vga=791 noreplace-paravirt к параметрам ядра, то мы получим вот такой красивый Stack-Trace и надпись BUG: Int 6: CR2 00000000.

Поэтому опять грузимся с компакт диска.

Выбираем “Rescue a broken system” и, конечно же, добавляем магические vga=791 noreplace-paravirt.

После того, как получаем доступ к командной строке (в окружении виртуального диска а не инсталлятора – первая опция), выполняем:
apt-get update
apt-get remove linux-server
apt-get install linux-386

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

Далее фиксируем параметры запуска ядра:
vim /boot/grub/menu.lst

Убираем две записи с -server ядром, а к -386 ядру добавляем нужные параметры:
vga=791 noreplace-paravirt noapic nolapic clock=pit
Будет выглядеть это вот так:

Кстати курсоры работать не будут, напоминаю, что в ViM можно использовать вместо курсоров клавиши H J K L.

Сохраняемся. Exit из шелла. Перегружаем систему и можно грузиться в установленную ОС! Все должно работать, при чем часы должны идти точно, не опаздывать и не спешить, благодаря noapic nolapic clock=pit.

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

Вот и все – пущай работает!