
lost
01.07.2017
12:57:20

Александр
01.07.2017
12:59:34
а как на это смотрите http://skeletor.org.ua/?p=3401 ?
innodb не поддерживает копирование файлами, это только с myisam канает
не жизнеспособно?

Google

Александр
01.07.2017
13:00:01
80Gb в транзакциях - это до седовласой старости переносить

lost
01.07.2017
13:04:47
есть же percona xtrabackup, зачем велосипеды придумывать

Александр
01.07.2017
13:07:35
а он может сделать бэкап сразу на другой сервер?
а то основная проблема собсн вот в чем:
/dev/xvdb1 99G 84G 11G 90% /var/lib/mysql
раздел 99G, из него занято 84G
т.е. "положить" бэкап на этот же сервак - не получится (

Alexey
01.07.2017
13:08:28
вот тут примеры: https://www.percona.com/doc/percona-xtrabackup/LATEST/howtos/recipes_ibkx_stream.html

Александр
01.07.2017
13:10:35
спасибо огромное!!!!

Nurik
01.07.2017
14:28:52
а как выглядят запросы?
Внутри транзакции делаю выборку 1 водителя, достаю его id и тут же делаю UPDATE строки по id. где ставлю in_search = 1

Alexey
01.07.2017
14:33:44

lost
01.07.2017
14:33:45

Google

Nurik
01.07.2017
14:34:05
Можно сюда скинуть запрос ?

Alexey
01.07.2017
14:34:35
да

lost
01.07.2017
14:35:40
лучше даже транзакцию целиком


Nurik
01.07.2017
14:40:30
START TRANSACTION;
SELECT
id,
is_busy,
first_name,
last_name,
role,
msisdn,
thumbnail,
lat,
lon,
car,
device_id,
drivers.serial_number,
(
:radiusOfEarth * acos (
cos ( radians(:lat) )
* cos( radians( lat ) )
* cos( radians( lon ) - radians(:lon) )
+ sin ( radians(:lat) )
* sin( radians( lat ) )
)
) AS distance
FROM
(
SELECT
u.id,
is_busy,
first_name,
last_name,
role,msisdn,
thumbnail,
lat,
lon,
CONCAT(c.color,' ',c.brand,' ',c.model) as car,
c.serial_number,
dev.device_id
FROM users u
JOIN car_info c
ON u.car_id=c.id
JOIN devices as dev
ON dev.user_id = u.id
WHERE
is_busy = 1
AND status = 1
AND role = 'passanger_car'
AND u.car_id IS NOT NULL
AND is_offline = 1
AND u.id NOT IN (23)
AND u.in_search_flag = 0
) as drivers
HAVING distance < :distance
ORDER BY distance
LIMIT 0 , :num
FOR UPDATE;
UPDATE users u SET in_search_flag = 1 WHERE id = 24;
COMMIT;
Правильно ли я ожидаю, что такая же параллельная транзакция по идее, должна ждать предыдущую ?


Andrey
01.07.2017
14:49:32
Че-то мне кажется, что из-за подзапроса блокировки не будет

lost
01.07.2017
14:53:04
меня тоже такая мысль посетила, либо перенести в подзапрос, либо выбрать айдишник с помощью запроса, а потом простым селектом выбрать по первичному ключу и блокировать
да, перенеси for update в подзапрос

Nurik
01.07.2017
14:56:48

Andrey
01.07.2017
14:58:48
Не знаю как for update внутри работает, скорее всего блокировка будет на результат подзапроса, а этот результат - временная табличка, поэтому хоть заблокируйтесь - вне запроса она и так никому не доступна, а раз только на результат, то таблицы самого подзапроса свободны, поэтому второй запрос спокойно будет работать сам по себе.
Только интересно: а со вьюхами так же будет? Вроде ни чем не отличается от примера, но с другой стороны - два запроса будут с одной и той же вьюхой работать. Или вьюхе нельзя for update ставить?

lost
01.07.2017
14:59:25
Да, на результат подзапроса, только что проверил

Andrey
01.07.2017
14:59:45
А с вьюхами как?

lost
01.07.2017
15:00:25
во вьюхе не т смысла делать такое

Andrey
01.07.2017
15:01:25
Я для общего развития. For update как и вьюхи не пользую )

Nurik
01.07.2017
15:01:47
Всем спасибо.

lost
01.07.2017
15:02:12
во вьюхах сам по себе функционал ограничен

Google

lost
01.07.2017
15:02:23
да и это попахивает выстрелом в колено

Andrey
01.07.2017
15:03:30
Я не вижу разницы между вьюхой и подзапросом, если для подзапроса так делается, то почему для вьюхи так сделать нельзя? ))) это просто вопрос, делать так я не собираюсь ))))

lost
01.07.2017
15:03:46
А она есть)
во первых там два вида алгоритмов создания вьюх
в первом случае вьюха будет генерить временную таблицу и класть результаты туда, смысла вешать блокировки на временную таблицу как выше обсуждалось смысла нет
а во втором случае эта вьха будет как обычный запрос
с вьюхами будет работать только в случае если ты будешь делать select * from view for update и работать это будет только в случае, если вьюха обновляемая, что накладывает еще ряд ограничений на код внутри вьюхи
короче это жопа


Alexey
01.07.2017
15:36:42
START TRANSACTION;
SELECT
id,
is_busy,
first_name,
last_name,
role,
msisdn,
thumbnail,
lat,
lon,
car,
device_id,
drivers.serial_number,
(
:radiusOfEarth * acos (
cos ( radians(:lat) )
* cos( radians( lat ) )
* cos( radians( lon ) - radians(:lon) )
+ sin ( radians(:lat) )
* sin( radians( lat ) )
)
) AS distance
FROM
(
SELECT
u.id,
is_busy,
first_name,
last_name,
role,msisdn,
thumbnail,
lat,
lon,
CONCAT(c.color,' ',c.brand,' ',c.model) as car,
c.serial_number,
dev.device_id
FROM users u
JOIN car_info c
ON u.car_id=c.id
JOIN devices as dev
ON dev.user_id = u.id
WHERE
is_busy = 1
AND status = 1
AND role = 'passanger_car'
AND u.car_id IS NOT NULL
AND is_offline = 1
AND u.id NOT IN (23)
AND u.in_search_flag = 0
) as drivers
HAVING distance < :distance
ORDER BY distance
LIMIT 0 , :num
FOR UPDATE;
UPDATE users u SET in_search_flag = 1 WHERE id = 24;
COMMIT;
Скорее всего, подзапрос выполняется через временную таблицу (легко проверить с помощью EXPLAIN) и тогда FOR UPDATE действительно пойдёт на временную таблицу, а не на базовую. Но зачем там вообще подзапрос?
я бы даже сказал, что переносить FOR UPDATE в подзапрос — это плохо. мы будем блокировать больше строчек, чем нужно. а именно всех свободных водителей, а не одного в нужном радиусе


Nurik
01.07.2017
16:08:25

Alexey
01.07.2017
16:10:14
здесь-то подзапрос не нужен совсем вроде?
а кстати какая версия mysql?

Nurik
01.07.2017
16:14:28
А да, я этот запрос много раз переписывал поэтому там раньше ещё была логика. Я её выкинул.

Alexey
01.07.2017
16:16:52
подзапросы вида SELECT ... FROM (SELECT ...) называются derived tables
у оптимизатора есть две стратегии выполнения таких запросов: 1. объединить подзапрос во внешний запрос и 2. материализовать подзапрос во временную таблицу, а внешний запрос выполнять по ней
видимо, оптимизатор из каких-то своих соображений решил использовать вариант 2. я не помню, есть ли в 5.6 вариант 1, в 5.7 уже точно есть

Google

Alexey
01.07.2017
16:18:55
а раз внешний запрос выполняется по временной таблице, то и for update работает на ней
EXPLAIN конечно покажет, какая стратегия используется. но FOR UPDATE + подзапросы это в любом случае плохая идея, потому что зависит от выбора оптимизатора

Nurik
01.07.2017
16:21:11

Alexey
01.07.2017
16:22:24
но интересный случай. я бы написал запрос на bugs.mysql.com, чтобы это внесли в документацию

Nurik
01.07.2017
16:29:41

Alexey
01.07.2017
16:30:57
хотя тут скорее даже теоретический вопрос. каково правильное поведение SELECT ... FROM (SELECT ...) FOR UPDATE с точки зрения SQL стандарта, например?
ведь в подзапросе может вообще не быть базовой таблицы. например SELECT * FROM (SELECT 1) FOR UPDATE, на какие строчки тут ставить блокировки?
собственно, просто select 1 for update mysql отрабатывает молча, хотя в этой команде нет никакого смысла
кстати, постгрес точно так же себя ведёт. select 1 for update отрабатывается тоже молча

Александр
01.07.2017
16:37:03
ребят, подскажите пожалуйста, а innobackupex умеет не через mysql.sock подключаться?
а по хосту
блин :(
Failed to connect to MySQL server: Plugin 'auth_socket' is not loaded.
и всё тут :(

Alexey
01.07.2017
16:42:53

Nurik
01.07.2017
16:42:56

lost
01.07.2017
18:12:41
В 5.6 нет derived merge
видимо, оптимизатор из каких-то своих соображений решил использовать вариант 2. я не помню, есть ли в 5.6 вариант 1, в 5.7 уже точно есть
И фича так себе я вам скажу

Google

Alexey
01.07.2017
18:17:58

lost
01.07.2017
18:18:17
Это же не строка
Это константа)
Данные он же не из стораджа берет

Alexey
01.07.2017
18:19:42
да, и хорошо бы ругнуться, что выражение for update не имеет смысла. а все молча выполняют
а из этого следуют ошибки пользователей в менее тривиальных случаях, как в обсуждаемом

lost
01.07.2017
18:20:11
Мускуль это не про "ругаться" )

Alexey
01.07.2017
18:20:20
и постгрес тоже получается
я поэтому задался вопросом, что sql стандарт говорит. но пока нет времени выяснять

lost
01.07.2017
18:20:54
Оно того не стоит, я думаю

Alexey
01.07.2017
18:21:10
ну вот сегодня убедительный был пример, что стоит
постгрес кстати тоже местами молча проглатывает то, где мускль указывает на ошибку пользователя. я потихоньку собираю коллекцию в плане хобби

Andrey
02.07.2017
06:58:48
ну вот сегодня убедительный был пример, что стоит
Я не знаю как работают внутри другие СУБД, но имею некоторое представление о том как работает MySQL, поэтому, увидев запрос, сразу предположил то поведение, которое и наблюдалось.
Поэтому "стоит" знать инструмент, а не стандарты ) по стандартам HTML все круто должно быть, но в браузерах все совсем не так )))

Alexey
02.07.2017
07:00:55

Andrey
02.07.2017
07:07:38
так на вопрос "как" должно знание инструмента ответить,
вот начали транзакцию, внесли какие-то данные, а потом откатили - изменений наблюдать же не должны? но с myisam разве так? хоть что пусть стандарт и другие субд говорят, но разбираться "как правильно" надо будет в пределах инструмента, в частности, отказаться от myisam

Alexey
02.07.2017
07:26:51

Andrey
02.07.2017
07:29:07
че-то я не догоняю, пойду сдохну )

Arslanali
03.07.2017
07:07:38
Привет. Ребята. Как парсить xml файл размером 20 гиг и больше средствами php?
Такое возможно?

Dmitriy
03.07.2017
07:34:35
Возможно, но долго будет
И памяти нужно много

Arslanali
03.07.2017
07:35:05
Может разбивать файл?