Pull to refresh

Comments 33

Одно плохо, что при «split-brain», оно выдает «Invalid command», а не свою, «родную» ошибку.
Кстати, не invalid, a unknown. Сейчас исправлю.

Полностью ошибка выглядит так:
ERROR 1047 (08S01): Unknown command

Состояние кластера ещё можно узнать командой clustercheck
Какое то невнятное падение производительности.
Пробовали развернуть на centos?
Нет. Но беглый осмотр аналогичных логов с NDBcluster говорит от том, что падение вполне себе обычное.
UFO just landed and posted this here
За замечания спасибо. Особенно полезным мне будет второе. А насчёт первого я писал, что при использовании xtrabackup ноды останавливаться не будут на время дампа.
UFO just landed and posted this here
Скажите, вы не проверели случайно?
UFO just landed and posted this here
Осилю конечно. Просто меня интересует кластерное решение mysql. Пока не могу определится на чем остановится или galera или percona. Вроде бы mariadb использует percona.

Может быть порекомендуете, что почитать? Я хотел бы понять, что мне подайдет для моих задач.
Планирую для начала 3 Master-Master сервера.
UFO just landed and posted this here
Так ясно. Какие тогда плюсы перед mariadb-galera?

Понятно, что mariadb-galera в стадии альфа. Я так понимаю патчи от percona так же включены в mariadb, или я не прав?
UFO just landed and posted this here
Если не секрет, на чем остановились?
Ищу товарищей по несчастью, мучаю третью неделю Percona XtraDB Cluster, хочется мнений / отзывов
Думаю все же percona.

Выбор прост. Много кто использует в серьзных вещах, есть платная поддержка.
mariadb-galera находится в альфа версии, выход из этой стадии непонятен, поддержки платной нет :)
Хотя сама mariadb у нас на текущий момент рабоает без нареканий.
по п.4. вопрос — при выходе из строя той ноды, на которую идет запись, haproxy сам переключит запись на другие? как это возможно, если мы к примеру жестко вписали ip ноды?
UFO just landed and posted this here
ясно, меня собственно что и удивило — если тупо писать на один жестко заданный узел, то зачем прокси? спасибо за объяснение
UFO just landed and posted this here
> Сеанет он недоступным, будем писать на другой, пока будет доступным…
если я правильно понял, не «мы», а haproxy =)
UFO just landed and posted this here
А чем обусловлена большая вероятность split-brain, если писать сразу на 3 сервера? Это же мультимастер, и это требование выглядит немного странно
Наткнулся на глюк, которого по идее в кластере возникать не должно.

Сделал прогу, которая сравнивает последние записи в таблицах на двух узлах кластера (третий узел тупо garbd). Так вот частенько (а при нагрузочном тестировании так постоянно) выползают несоответствия между базами. Например, в одной базе одно поле имеет старое значение, в то время как в другой уже обновилось. Или же в одной есть такая запись, а в другой нет вообще.

Это можно было бы списать на то, что запись делалась непосредственно в интервале между проверкой на первом и втором узле, но это не стыкуется с частичным обновлением полей. К тому же я сделал блокироку через транзакцию на таблицы обоих кластеров до их чтения (тоже не панацея, но снижает вероятность существенно)…

Что бы это могло быть?
А можно детали проги приподраскрыть, чтобы можно было воспроизвести у себя?
Я просто повесил прогу, которая в бесконечном цикле проходится по серверам и сравнивает последнюю строку в каждой таблице. Если что-то не совпадает — выдаёт сообщение. И такие сообщения при нормальной работе сайта периодически выдаются. При нагрузочном же тестировании выдаются постоянно.

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

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

Сама программа (PHP)
<?php
require dirname(__FILE__).'/config.php';

while(true)
{
$ts=date('r');
// echo «старт\n»;
foreach ($config['db'] as $key=>$val)
{
if(!$db[$key]=mysql_connect($val['host'], $val['user'], $val['password']))
die(«Ошибка подключения к БД: ». var_dump($val)."\n");
}
// echo «подключено\n»;

$tables=array();
$tables_summary=array();

// считываем названия всех таблиц во всех базах
foreach($config['db'] as $key=>$val)
{
$db_=$db[$key];
if(!mysql_query(«USE {$config['scheme']}», $db_))
echo $ts.' Ошибка выбора таблицы: '.mysql_error($db_)."\n";
mysql_query(«SET names 'utf8'», $db_);
if($res=mysql_query(«SHOW TABLES», $db_))
{
while($row=mysql_fetch_row($res))
{
$tables[$key][$row[0]]=true;
$tables_summary[$row[0]]=true;
}
}
else
echo $ts.' '.mysql_error($db_);
}

// echo «проверка таблиц\n»;
// проверяем наличие таблиц во всех базах
foreach($tables_summary as $key=>$val)
{
foreach($config['db'] as $key0=>$val0)
{
if(!@$tables[$key0][$key])
{
echo "$ts В базе $key0 нет таблицы $key. Таблица исключена из проверки.\n";
$tables_summary[$key]=false;
}
}
}

//system(«clear»);

// echo «проверка данных\n»;
foreach($tables_summary as $key=>$val)
{
if($val)
{
// лочим таблицы
foreach($config['db'] as $key0=>$val0)
{
$db_=$db[$key0];
if(mysql_query(«START TRANSACTION», $db_))
mysql_query(«SELECT 1 FROM $key LIMIT 1», $db_); // чтоб запустилась блокировка внутри транзакции надо что-нибудь прочитать из таблицы
if(mysql_error($db_))
echo $ts.' Ошибка блокировки: '.mysql_error($db_)."\n";
}
//echo "$key\t";
unset($id_summary);
unset($id_name);
foreach($config['db'] as $key0=>$val0)
{
if(!isset($id_name))
{
$db_=$db[$key0];
// получаем имя первой колонки
$res=mysql_query(«DESCRIBE $key», $db_);
$row=mysql_fetch_row($res);
$id_name=$row[0];
//echo "$id_name\t";
}

// получаем максимальный id
$res=mysql_query(«SELECT MAX($id_name) FROM $key», $db_);
$row=mysql_fetch_row($res);
if(is_numeric($row[0]))
{
//echo " $row[0] ";
if(!isset($id_summary))
{
$id_summary=$row[0];
}
else
{
if($id_summary<$row[0])
{
echo "$ts В базе $key0 в таблице $key ключ $id_name опережает другие на ".$row[0]-$id_summary."\n";
}
if($id_summary>$row[0])
{
echo "$ts В базе $key0 в таблице $key ключ $id_name отстаёт от других на ".$row[0]-$id_summary."\n";
$id_summary=$row[0]; // В $id_summary попадает значение id, которое есть во всех базах
}
}
}
else
unset($id_summary);
}
if(@$id_summary)
{
// echo «сравнение данных\n»;
$data=array();
foreach($config['db'] as $key0=>$val0)
{
$db_=$db[$key0];
// считываем по одной строке из каждой базы
$res=mysql_query(«SELECT * FROM $key WHERE $id_name='$id_summary' LIMIT 1», $db_);
$row=mysql_fetch_row($res);
if($data)
{
if(is_array($data) && is_array($row))
$result = array_diff($data, $row);
elseif($data!=$row)
$result=true;
if($result || !$row)
{
echo "$ts Есть расхождения в таблице $key, $id_name='$id_summary':\n";
print_r($data);
print_r($row);
}
}
else
{
if($row)
$data=$row;
}
}
}
// разлочиваем таблицы
foreach($config['db'] as $key0=>$val0)
{
$db_=$db[$key0];
mysql_query(«COMMIT», $db_);
if(mysql_error($db_))
echo $ts.' Ошибка разблокировки: '.mysql_error($db_)."\n";
}
}
}
//echo «закрытие соединений\n»;
foreach($config['db'] as $key0=>$val0)
{
mysql_close($db[$key0]);
}
usleep(10);
}

А как распараллеливать запросы на ноды в таком кластере?
Понятно что в приложении можно, но интересует вариант с прозрачным коннектом и балансировкой. Какие есть варианты?
UFO just landed and posted this here
спасибо

еще вопрос — вот вы пишите о том что тестировали и кластер, и ноды отдельно — имеется в виду, что ноды выкидывались на время из кластера и на стандартном mysql сервере проводился тест?
Просто убирал из конфига всё относящееся к кластеру, и он работал как самостоятельный сервер.
спс, ясно
да, система выглядит привлекательно, но без ложки дегтя не бывает — такое проседание по записи удручает.
Я думаю, надо копать в сторону более быстрых SSD. У меня были вполне рядовые OCZ Vertex 3
Sign up to leave a comment.

Articles