死锁BLOB INSERT MySQL 8.0 InnoDB集群

时间:2019-10-25 13:51:08

标签: mysql innodb mysql-innodb-cluster

当使用配置好的InnoDB集群复制将较大的文件插入MySQL 8.0数据库时,查询会陷入表死锁。对于较小的6 KB文件,可以使用INSERT。通过MySQL路由器运行以及通过直接连接到“ R / W”主机运行INSERT时,会发生问题。不太可能达到适当的交易限额。请参阅下面的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 6KB =>有效

命令

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可以正常工作。

对于具有InnoDB群集配置但在群集中仅一个主机的MySQL 8.0,INSERT也有效。

只有具有InnoDB群集配置和更多主机的MySQL 8.0死锁运行。

我们忘记了设置还是一个错误?

1 个答案:

答案 0 :(得分:0)

在Mysql服务器之间是10MBit / s的LAN。结果,MySQL数据库复制似乎在较大的文件上超时,从而导致事务回滚,进而导致表锁定。

对于100MBit / s的LAN,经过多次测试后不会发生该错误。仅此而已。 slave_net_timeout的增加也无济于事。

在我看来,为什么异步复制中的超时会导致主服务器上的表锁定没有意义。

更新: 使用100MBit / s的LAN,对于大于20MB的文件,现在会出现错误。由于无论如何我们都不想在数据库中存储任何大于16 MB的文件,因此我们只需将最大SQL数据包大小设置为16 MB。这将导致错误代码1301“ ...大于max_allowed_pa​​cket ...”直接输出到较大文件的INSERT,从而防止表锁定。

max_allowed_packet = 16777216

更新2:

cluster.setOption("expelTimeout", 3600); 

在/etc/mysql/mysql.conf.d/mysqld.cnf中设置group_replication_transaction_size_limit可以部分地帮助您。

group_replication_transaction_size_limit = 0 #0=Maximum=2147483647=2GB

最终提示: 看起来,当表中存储较大的文件时,MySQL复制通常会出现问题。因此,我们已经更改了应用程序,以便所有文件都保存在文件系统中,而MySQL表仅存储文件密钥和其他文件信息。我们已经创建了自己的解决方案,可以在多台计算机上复制文件。