[英]Deadlock BLOB INSERT MySQL 8.0 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 設置 output
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 output 出錯
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 |
| |
+------+-----------------------------+---------------------------------+----------+---------+------+--------------------------------------------------------+----------------------- -------------------------------------------------------------------------------+
測試用例:
對於沒有InnoDB Cluster 配置的正常 MySQL 8.0 安裝,INSERT 有效。
對於具有 InnoDB 集群配置但集群中只有一台主機的 MySQL 8.0,INSERT 也可以工作。
只有具有 InnoDB Cluster Configuration 和更多主機INSERT 的 MySQL 8.0 在死鎖中運行。
我們忘記了設置還是這是一個錯誤?
Mysql 服務器之間是一個 10MBit/s 的 LAN。 結果,MySQL 數據庫復制似乎在較大的文件上超時,導致事務回滾,進而導致表鎖定。
使用 100MBit/s 的 LAN,經過多次測試后不會出現錯誤。 只有這有幫助。 slave_net_timeout 的增加也沒有幫助。
為什么在異步復制中超時會導致主服務器上的表鎖定在我看來沒有意義。
更新:對於 100MBit/s 的 LAN,現在對於大於約 20MB 的文件會發生錯誤。 由於我們不想在數據庫中存儲任何大於 16 MB 的文件,我們只需將最大 SQL 數據包大小設置為 16 MB。 這導致錯誤代碼1301“...大於max_allowed_packet...”為output直接插入到更大文件的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 表僅存儲文件密鑰和其他文件信息。 我們創建了自己的解決方案,用於在多台機器上復制文件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.