Задать вопрос

Percona MySQL table locking

Добрый день

Установил себе Percona MySQL server 5.5 + HandlerSocket. Решил поиграться. Вот тестовый скрипт:

Insert with PDO code
<?php

function out($line = '')
{
	echo PHP_EOL.$line.PHP_EOL;
}

function sep()
{
	out();
	out('------------------------------');
	out();
}

/**
 * @param $pdo PDO
 * @param $config array
 */
function run($pdo, $config)
{
	$sql = "TRUNCATE products";

	$stmt = $pdo->prepare($sql);
	$stmt->execute();

	$numberOfInsertOps = $config['insert_number'];

	$startInsertTime = microtime(true);

	$sql = "INSERT INTO products (name, price) VALUES (:name, :price)";
	$stmt = $pdo->prepare($sql);

	for ($i = 0; $i < $numberOfInsertOps; $i++)
	{
		$name = md5(rand(0, 1000));
		$price = rand(1, 1000);

		$stmt->bindParam(':name', $name);
		$stmt->bindParam(':price', $price);

		try
		{
			$result = $stmt->execute();

			if (!$result)
			{
				out('shit happened');
			}

			out($pdo->lastInsertId());
		}
		catch (Exception $e)
		{
			sep($e->getMessage());
		}
	}

	out('Insert in one query time: ' . ( microtime(true) - $startInsertTime) );
}


$pdo = new PDO("mysql:host=$hostname;dbname=$db_name", $username, $password);

run($pdo, array(
	'insert_number' => 100
));



По идеи должны вставится все 100 записей. На другой машине все правильно работает, но там обычный MySQL стоит.
А у меня происходит следующее:

— Количество добавленных сторк всегда лежит в диапазоне 40-70 и при каждом выполнении скрипта их количество меняется.
— Если проверить $pdo->errorInfo() — возвращает код 0000 — знаит что все хорошо, просто количество affected rows равно 0.
— И после первой не вставленной строки — все следующие тоже не добавляются.
То есть в итоге выполнения скрипта я вижу что-то вроде:

1
2
3

60
61
62
shit
62
shit
62
shit
62
shit


Похоже на блокоровки.

Если движок таблицы на MyISAM — то проблемы не возникают.

Если добавить такой хак (с 49 сторки) — проблема решается (Но решением это назвать невозможно).

Вот структура таблици:

CREATE TABLE IF NOT EXISTS `products` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `price` int(10) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

И еще:

если вставлять записи в таблицу с помощью HandlerSocket:
Insert with HandlerSocket code
	$hs = new \HSPHP\WriteSocket();
	$hs->connect();


	$id = $hs->getIndexId('test','products','','name,price');

	$startHandlerSocketInsertTime = microtime(true);
	for ($i = 0; $i < $numberOfInsertOps; $i++)
	{
		$name = 'handler-'.md5(rand(0, 1000));
		$price = rand(0, 1000);

		$hs->insert($id, array($name, $price));
	}

	out('Insert HandlerSocket time: ' . ( microtime(true) - $startHandlerSocketInsertTime) );




То количество вставленых строк в БД также зависит от количества итераций цикла.

if 10 loops — I have 100 rows in DB table
if 50 loops — 50 rows
if 100 loops — 100 rows
if 500 loops — 500 rows
if 1000 loops — ~1100 rows и это число будет менятся каждый раз когда запуская скрипт.


В чем может быть проблема? Как её найти и устранить?

Заранее благодарю.

update.
Выяснил, что ошибка вот такая:
Array (
[0] => 00000
[1] =>
[2] =>
)

An error occuredSQLSTATE[HY000]: General error: 2013 Lost connection to MySQL server during query
  • Вопрос задан
  • 3384 просмотра
Подписаться 4 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 2
kenny_opennix
@kenny_opennix
похоже на deadlock.
Попробуйте сделать
CREATE TABLE innodb_monitor (i INT) ENGINE=INNODB;
Плюс надо проверить настройки innodb_thread_concurrency и innodb_buffer_pool_instances
Ответ написан
hlx
@hlx Автор вопроса
Переустановил пхп и все стало хорошо. (точнее обновил с 5.3 до 5.5)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы