Deadlock BLOB INSERT MySQL 8.0 InnoDB кластер - PullRequest
0 голосов
/ 25 октября 2019

При вставке файла большего размера в базу данных MySQL 8.0 с настроенной репликацией кластера InnoDB запрос переходит в тупик таблицы. Для меньшего файла 6 КБ, INSERT работает. Проблема возникает при работе через маршрутизатор MySQL, а также при запуске INSERT через прямое соединение с хостом «R / W». Соответствующие лимиты транзакций вряд ли будут достигнуты. См. Настройки MySQL ниже.

Таблица

CREATE TABLE `onlineorder_attachments` (
  `AttachmentGUID` varchar(36) NOT NULL,
  `Filename` varchar(80) DEFAULT NULL,
  `File` mediumblob,
  PRIMARY KEY (`AttachmentGUID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

Тестовые файлы M-02-012.jpg 4.813KB => Тупик! M-05-055.jpg 6 КБ => Работает

Команда

INSERT INTO `onlineorder_attachments`
(`AttachmentGUID`,`Filename`,`File`)
VALUES
('00a2b54f-b0cf-4f3a-9bed-02dba853b505', 'M-02-012.jpg', LOAD_FILE('/var/lib/mysql-files/tmp/M-02-012.jpg'));

Вывод настроек MySQL

group_replication_communication_max_message_size    10485760
group_replication_components_stop_timeout   31536000
group_replication_compression_threshold 1000000
group_replication_group_seeds   10.29.169.13:33561
group_replication_local_address 10.29.169.12:33561
group_replication_member_expel_timeout  0
group_replication_message_cache_size    1073741824
group_replication_transaction_size_limit    150000000
slave_max_allowed_packet    1073741824
slave_net_timeout   60

Состояние установки кластера InnoDB:

{
    "clusterName": "AppCluster",
    "defaultReplicaSet": {
        "GRProtocolVersion": "8.0.16",
        "groupName": "3afe628e-bdd1-11e9-8bbe-ac1f6bd3521c",
        "name": "default",
        "primary": "10.29.169.12:3356",
        "ssl": "REQUIRED",
        "status": "OK_NO_TOLERANCE",
        "statusText": "Cluster is NOT tolerant to any failures.",
        "topology": {
            "10.29.169.12:3356": {
                "address": "10.29.169.12:3356",
                "fenceSysVars": [],
                "memberId": "a715990f-bdc2-11e9-8ec6-ac1f6bd3521c",
                "memberRole": "PRIMARY",
                "memberState": "ONLINE",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "10.29.169.13:3356": {
                "address": "10.29.169.13:3356",
                "fenceSysVars": [
                    "read_only",
                    "super_read_only"
                ],
                "memberId": "74c57dda-bdbb-11e9-94f8-ac1f6bd350ce",
                "memberRole": "SECONDARY",
                "memberState": "ONLINE",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "10.29.169.12:3356"
}

Вывод MySQL Shell при ошибке

mysql> show open tables where in_use>0;
+----------+-------------------------+--------+-------------+
| Database | Table                   | In_use | Name_locked |
+----------+-------------------------+--------+-------------+
| appws30 | onlineorder_attachments |      1 |           0 |


mysql> show processlist;
+------+-----------------------------+---------------------------------+----------+---------+------+--------------------------------------------------------+-----------------------                                                            -------------------------------------------------------------------------------+
| Id   | User                        | Host                            | db       | Command | Time | State                                                  | Info                                                                                                                                                             |
+------+-----------------------------+---------------------------------+----------+---------+------+--------------------------------------------------------+-----------------------                                                            -------------------------------------------------------------------------------+
|    5 | event_scheduler             | localhost                       | NULL     | Daemon  |  472 | Waiting on empty queue                                 | NULL                                                                                                                                                             |
|    9 | system user                 |                                 | NULL     | Connect |  472 | waiting for handler commit                             | Group replication appl                                                            ier module                                                                     |
|   14 | system user                 |                                 | NULL     | Query   |  472 | Slave has read all relay log; waiting for more updates | NULL                                                                                                                                                             |
|  344 | remoteuser                  | 10.29.169.12:56834              | NULL     | Sleep   |  351 |                                                        | NULL                                                                                                                                                             |
|  350 | remoteuser                  | 10.29.169.12:56842              | NULL     | Sleep   |  388 |                                                        | NULL                                                                                                                                                             
|
|  497 | remoteuser                  | 10.29.169.12:56996              | NULL     | Sleep   |  351 |                                                        | NULL                                                                                                                                                             |
|  615 | root                        | localhost                       | appws30 | Query   |  255 | waiting for handler commit                             | INSERT INTO `onlineord                                                            er_attachments` (`AttachmentGUID`,`Filename`,`File`) VALUES  ('44a2b54f-b0cf-4 |
| |
+------+-----------------------------+---------------------------------+----------+---------+------+--------------------------------------------------------+-----------------------                                                            -------------------------------------------------------------------------------+

Тестовые случаи:

Для обычной установки MySQL 8.0 без Конфигурация InnoDB Cluster, INSERT работает.

Для MySQL 8.0 с конфигурацией InnoDB Cluster, но только одинхост в кластере, также работает INSERT.

Только MySQL 8.0 с конфигурацией кластера InnoDB и больше хостов INSERT работает в тупике.

Мы забылинастройка или это ошибка?

1 Ответ

0 голосов
/ 12 ноября 2019

Между серверами Mysql была локальная сеть 10 Мбит / с. В результате репликация базы данных MySQL оказалась слишком большой для файлов большего размера, что вызвало откат транзакции, что, в свою очередь, привело к блокировке таблиц.

В локальной сети со скоростью 100 Мбит / с ошибка не возникает после несколькихтесты. Только это помогло. Увеличение slave_net_timeout также не помогло.

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

ОБНОВЛЕНИЕ: В локальной сети со скоростью 100 Мбит / с ошибка теперь возникает для файлов размером более 20 МБ. Так как в любом случае мы не хотим хранить в базе данных файлы размером более 16 МБ, мы просто устанавливаем максимальный размер пакета SQL равным 16 МБ. Это приводит к тому, что код ошибки 1301 «... больше, чем max_allowed_packet ...» выводится непосредственно в INSERT файла большего размера, предотвращая тем самым блокировки таблиц.

max_allowed_packet = 16777216
...