Применение Mutex через блокировку строк Myno InnoDB - PullRequest
1 голос
/ 26 мая 2011

Мое приложение состоит из пары серверов Apache, которые общаются с общей коробкой MySQL.Часть приложения позволяет пользователям создавать часовые встречи в будущем.Мне нужен механизм, который не позволяет разным пользователям приходить из разных экземпляров Apache в одно и то же время, заказывать один и тот же час для встреч.Я видел аналогичное решение «межсистемного мьютекса», реализованное в базах данных Oracle (в основном «выберите ... для обновления»), но не рассматривал детали того же, что и с MySQL.Буду признателен за любые советы, ссылки на код или документацию, лучшие практики и т. Д. Попробовал поискать в гугле, но в основном идут дискуссии о внутренних мьютексах MySQL.

Это мои настройки MySQL, которые я считал актуальными (мой код будет иметь try-catch и все, и он никогда не должен запускаться без разблокировки того, что он заблокировал, но должен учитывать и то, что происходит в этих случаях):

mysql> show variables like 'innodb_rollback_on_timeout';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| innodb_rollback_on_timeout | OFF   | 
+----------------------------+-------+
1 row in set (0.00 sec)

mysql> show variables like 'innodb_lock_wait_timeout';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 100   | 
+--------------------------+-------+
1 row in set (0.00 sec)

mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 | 
+--------------+
1 row in set (0.00 sec)

Какие альтернативные решения (кроме MySQL) вы могли бы порекомендовать?У меня также работает экземпляр memcached, но он довольно часто сбрасывается (и я не уверен, что хочу иметь memcachedb и т. Д., Чтобы сделать его отказоустойчивым).

Ценю вашу помощь ...

Ответы [ 2 ]

1 голос
/ 14 сентября 2012

Отвечая на мой собственный вопрос здесь. Разновидностью этого является то, что мы в конечном итоге делаем (в PHP):

<?php
$conn = mysql_connect('localhost', 'name', 'pass');
if (!$conn) {
  echo "Unable to connect to DB: " . mysql_error();
  exit;
 }
if (!mysql_select_db("my_db")) {
  echo "Unable to select mydbname: " . mysql_error();
  exit;
 }
mysql_query('SET AUTOCOMMIT=0'); //very important! this makes FOR UPDATE work                                                                                           
mysql_query('START TRANSACTION');
$sql = "SELECT * from my_mutex_table where entity_id = 'my_mutex_key' FOR UPDATE";
$result = mysql_query($sql);
if (!$result) {
  echo "Could not successfully run query ($sql) from DB: " . mysql_error();
  exit;
 }
if (mysql_num_rows($result) == 0) {
  echo "No rows found, nothing to print so am exiting";
  exit;
 }

echo 'Locked. Hit Enter to unlock...';
$response = trim(fgets(STDIN));
mysql_free_result($result);
echo "Unlocked\n";
?>

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

0 голосов
/ 14 июня 2018

Можно также использовать функции MySQL и MariaDB GET_LOCKRELEASE_LOCK):

Функции могут быть использованы для реализации поведения, описанного в вопросе.

...