首页 文章 精选 留言 我的

精选列表

搜索[渲染问题],共10000篇文章
优秀的个人博客,低调大师

宇连通 IM 之 gif 图片的若干问题

宇连通IM经常会使用到gif图片,就增加了支持gif图片功能,已经gif图片制作功能。使IM不仅能发送截图,还能发送制作的gif图片。 但是当发送10M+的gif图片时,pc端内存就迅速升高,设置的500M内存就不够用了,就对gif占用大量内存进行了优化。 第一步优化: 不直接展示gif图片,而是读取gif中的图片,然后使用线程轮询展示图片,这样内存占用永远只是一张图片的大小。此种方法看起来已经解决掉了,但是,当消息列表中有多张大gif图片时,还是会占用太多内存。 第二部优化: 那就让消息列表中只展示当前需要展示的gif图片。此方法首先需要解决哪些图片是在展示区,哪些图片已经不在展示区了。当图片进入不需要展示区时,停止加载gif图片,停止加载线程,并释放内存。 通过上序两种优化方案,pc端的内存占用已经回归到正常。就测试flutter和arkts开发的客户端。 flutter制作IM直接对大gif图片当做普通图片展示,没有动画效果。需要针对性解决。 arkts鸿蒙IM对大gif能够正常展示,动画效果也很好。鸿蒙非常的牛逼。 这是就找了国内做的比较好的IM软件对大gif的展示效果如何,就找微信和QQ进行测试,试图从同行中找到解决的灵感。 Pc端微信做的很粗暴,对大于5M的gif图片直接当做文件处理,不做图片展示了。 PC端QQ对大gif支持得比较好,内存占用也不是很高,QQ做的还是很厉害了。 同时还测试了其他软件对大gif的支持情况: oschina上传10M+不支持上传。csdn也不能上传大于5M的gif。看来gif只能是小动画才行呀。 做好一个软件真的好难呀!!!,如果还需要继续优化下去,还需要大量的精力和潜心神的投入,

优秀的个人博客,低调大师

故障解析丨一次死锁问题的解决

背景 业务端遇到报错为"Deadlock found when trying to get lock; try restarting transaction"则表明有死锁发生 名称 配置 数据库版本 GreatSQL 8.0.26 隔离级别 Read-Commited innodb status 日志 greatsql> show engine innodb status\G *************************** 1. row *************************** Type: InnoDB Name: Status: ===================================== 2024-01-28 16:55:38 140737023727360 INNODB MONITOR OUTPUT ===================================== Per second averages calculated from the last 14 seconds ----------------- BACKGROUND THREAD ----------------- srv_master_thread loops: 41 srv_active, 0 srv_shutdown, 17830 srv_idle srv_master_thread log flush and writes: 0 ---------- SEMAPHORES ---------- ------------- RW-LATCH INFO ------------- Total number of rw-locks 132361 OS WAIT ARRAY INFO: reservation count 11180 OS WAIT ARRAY INFO: signal count 11177 RW-shared spins 0, rounds 0, OS waits 0 RW-excl spins 0, rounds 0, OS waits 0 RW-sx spins 0, rounds 0, OS waits 0 Spin rounds per wait: 0.00 RW-shared, 0.00 RW-excl, 0.00 RW-sx ------------------------ LATEST DETECTED DEADLOCK ------------------------ 2024-01-28 16:53:40 140735053358848 *** (1) TRANSACTION: TRANSACTION 37616, ACTIVE 8 sec inserting mysql tables in use 1, locked 1 LOCK WAIT 2 lock struct(s), heap size 1192, 1 row lock(s), undo log entries 1 MySQL thread id 16, OS thread handle 140737023432448, query id 652 127.0.0.1 root update insert into info values (50,11) *** (1) HOLDS THE LOCK(S): RECORD LOCKS space id 26 page no 5 n bits 80 index uk_name of table `apple`.`info` trx id 37616 lock mode S waiting Record lock, heap no 7 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 4; hex 8000000b; asc ;; 1: len 4; hex 80000028; asc (;; *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 26 page no 5 n bits 80 index uk_name of table `apple`.`info` trx id 37616 lock mode S waiting Record lock, heap no 7 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 4; hex 8000000b; asc ;; 1: len 4; hex 80000028; asc (;; *** (2) TRANSACTION: TRANSACTION 37615, ACTIVE 24 sec inserting mysql tables in use 1, locked 1 LOCK WAIT 3 lock struct(s), heap size 1192, 2 row lock(s), undo log entries 2 MySQL thread id 15, OS thread handle 140737024022272, query id 653 127.0.0.1 root update insert into info values (60,8) *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 26 page no 5 n bits 80 index uk_name of table `apple`.`info` trx id 37615 lock_mode X locks rec but not gap Record lock, heap no 7 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 4; hex 8000000b; asc ;; 1: len 4; hex 80000028; asc (;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 26 page no 5 n bits 80 index uk_name of table `apple`.`info` trx id 37615 lock_mode X locks gap before rec insert intention waiting Record lock, heap no 7 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 4; hex 8000000b; asc ;; 1: len 4; hex 80000028; asc (;; *** WE ROLL BACK TRANSACTION (1) ------------ TRANSACTIONS ------------ 查看表结构 greatsql> show create table info \G *************************** 1. row *************************** Table: info Create Table: CREATE TABLE `info` ( `id` int NOT NULL AUTO_INCREMENT, `name` int NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_name` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=61 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 1 row in set (0.01 sec) 梳理 innodb status 日志 整理如下: 事务 T1 T2 操作 insert into info values (50,11) insert into info values (60,8) 关联的对象 表apple.info的唯一索引 uk_name 表apple.info的唯一索引 uk_name 持有的锁 lock mode S waitingheap no 7 11,40(十六进制为8,28) lock_mode X locks rec but not gapheap no 7 11,40(十六进制为8,28) 等待的锁 lock mode S waitingheap no 7 11,40(十六进制为8,28) lock_mode X locks gap before rec insert intention waitingheap no 7 11,40(十六进制为8,28) 首先事务T2获取到了uk_name中记录11的 lock x,rec not not gap 锁 事务T1尝试获取uk_name中记录11的lock s, next key lock,由于T2持有了记录的独占锁,因此被T1堵塞 事务T2尝试获取uk_name中记录11的lock x, gap before rec,insert intention,但被堵塞 获取业务历史SQL语句 通过系统表方式 通过performance_schema.threads、performance_schema.events_statements_history、performance_schema.events_statements_history_long等系统表获取历史SQL 根据GreatSQL thread id获得线程id greatsql> select PROCESSLIST_ID,THREAD_ID,THREAD_OS_ID from performance_schema.threads where processlist_id in (15,16); +----------------+-----------+--------------+ | PROCESSLIST_ID | THREAD_ID | THREAD_OS_ID | +----------------+-----------+--------------+ | 15 | 61 | 5714 | | 16 | 62 | 5719 | +----------------+-----------+--------------+ 2 rows in set (0.00 sec) 根据线程id获得线程历史SQL greatsql> select THREAD_ID,EVENT_ID,CURRENT_SCHEMA,SQL_TEXT,MESSAGE_TEXT,EVENT_NAME,SOURCE from performance_schema.events_statements_history where thread_id in (61,62) order by THREAD_ID,EVENT_ID; +-----------+----------+----------------+---------------------------------+--------------------------------------------------------------------+--------------------------+---------------------------------+ | THREAD_ID | EVENT_ID | CURRENT_SCHEMA | SQL_TEXT | MESSAGE_TEXT | EVENT_NAME | SOURCE | +-----------+----------+----------------+---------------------------------+--------------------------------------------------------------------+--------------------------+---------------------------------+ | 61 | 3762 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 61 | 3807 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 61 | 3852 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 61 | 3897 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 61 | 3942 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 61 | 3987 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 61 | 4032 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 61 | 4077 | apple | begin | NULL | statement/sql/begin | init_net_server_extension.cc:94 | | 61 | 4100 | apple | insert into info values (40,11) | NULL | statement/sql/insert | init_net_server_extension.cc:94 | | 61 | 4569 | apple | insert into info values (60,8) | NULL | statement/sql/insert | init_net_server_extension.cc:94 | | 62 | 3215 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 62 | 3260 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 62 | 3305 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 62 | 3350 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 62 | 3395 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 62 | 3440 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 62 | 3485 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 62 | 3530 | apple | NULL | NULL | statement/com/Field List | init_net_server_extension.cc:94 | | 62 | 3575 | apple | begin | NULL | statement/sql/begin | init_net_server_extension.cc:94 | | 62 | 3598 | apple | insert into info values (50,11) | Deadlock found when trying to get lock; try restarting transaction | statement/sql/insert | init_net_server_extension.cc:94 | +-----------+----------+----------------+---------------------------------+--------------------------------------------------------------------+--------------------------+---------------------------------+ 20 rows in set (0.00 sec) 观察show engine innodb status中的GreatSQL thread id 16和GreatSQL thread id 15 通过performance_schema.threads获取THREAD_ID 通过performance_schema.events_statements_history获取THREAD_ID执行的历史SQL以及执行时间 最终可复现出如下业务SQL: 事务 T1 T2 语句 begin; begin; 语句 insert into info values (40,11); 语句 insert into info values (50,11); 语句 insert into info values (60,8); 通过解析binlog $ mysqlbinlog -vv --base64-output=decode-rows bin.000030 SET @@SESSION.GTID_NEXT= 'e319a624-b2ce-11ee-9aac-00163e62ca8a:8696'/*!*/; # at 10314 #240128 16:52:35 server id 1024 end_log_pos 10390 CRC32 0x59edb313 Query thread_id=18 exec_time=0 error_code=0 SET TIMESTAMP=1706431955/*!*/; BEGIN /*!*/; # at 10390 #240128 16:52:35 server id 1024 end_log_pos 10442 CRC32 0xc03dea61 Table_map: `apple`.`info` mapped to number 370 # at 10442 #240128 16:52:35 server id 1024 end_log_pos 10486 CRC32 0x670e0c66 Write_rows: table id 370 flags: STMT_END_F ### INSERT INTO `apple`.`info` ### SET ### @1=30 /* INT meta=0 nullable=0 is_null=0 */ ### @2=30 /* INT meta=0 nullable=0 is_null=0 */ # at 10486 #240128 16:52:35 server id 1024 end_log_pos 10517 CRC32 0xab4e0d89 Xid = 598 COMMIT/*!*/; # at 10517 #240128 19:22:12 server id 1024 end_log_pos 10596 CRC32 0x4f4cf08e GTID last_committed=30 sequence_number=36 rbr_only=yes original_committed_timestamp=1706440932450590 immediate_commit_timestamp=1706440932450590 transaction_length=378 /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/; # original_commit_timestamp=1706440932450590 (2024-01-28 19:22:12.450590 CST) # immediate_commit_timestamp=1706440932450590 (2024-01-28 19:22:12.450590 CST) /*!80001 SET @@session.original_commit_timestamp=1706440932450590*//*!*/; /*!80014 SET @@session.original_server_version=80026*//*!*/; /*!80014 SET @@session.immediate_server_version=80026*//*!*/; SET @@SESSION.GTID_NEXT= 'e319a624-b2ce-11ee-9aac-00163e62ca8a:8697'/*!*/; # at 10596 #240128 16:53:16 server id 1024 end_log_pos 10672 CRC32 0xf222c003 Query thread_id=15 exec_time=0 error_code=0 SET TIMESTAMP=1706431996/*!*/; BEGIN /*!*/; # at 10672 #240128 16:53:16 server id 1024 end_log_pos 10724 CRC32 0x20cb8c86 Table_map: `apple`.`info` mapped to number 370 # at 10724 #240128 16:53:16 server id 1024 end_log_pos 10768 CRC32 0xd8f53958 Write_rows: table id 370 flags: STMT_END_F ### INSERT INTO `apple`.`info` ### SET ### @1=40 /* INT meta=0 nullable=0 is_null=0 */ ### @2=11 /* INT meta=0 nullable=0 is_null=0 */ # at 10768 #240128 16:53:40 server id 1024 end_log_pos 10820 CRC32 0x23f22580 Table_map: `apple`.`info` mapped to number 370 # at 10820 #240128 16:53:40 server id 1024 end_log_pos 10864 CRC32 0x182ecdef Write_rows: table id 370 flags: STMT_END_F ### INSERT INTO `apple`.`info` ### SET ### @1=60 /* INT meta=0 nullable=0 is_null=0 */ ### @2=8 /* INT meta=0 nullable=0 is_null=0 */ # at 10864 #240128 19:22:12 server id 1024 end_log_pos 10895 CRC32 0x57fd1d3c Xid = 650 COMMIT/*!*/; SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/; DELIMITER ; # End of log file /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; 根据binlog中部分SET @@SESSION.GTID_NEXT= 'e319a624-b2ce-11ee-9aac-00163e62ca8a:8697'该GTID的事务信息,可恢复T2,但T1执行的语句由于被回滚了,则不会记录到binlog,可开启general log日志获取排查 事务 T1 T2 语句 begin; begin; 语句 insert into info values (40,11); 语句 insert into info values (50,11); 语句 insert into info values (60,8); 分析死锁 T1、T2开启了一个事务 随后T2执行了插入(40,11)的insert语句:insert into info values (40,11) T1执行了插入(50,11)的insert语句:insert into info values (50,11) 进行唯一性冲突检查,尝试获取LOCK_S 然后T1所在的连接会将T2中的隐式锁转换为显示锁,此时T2将获取Lock X, Rec_not_gap。由于T2的Lock X, Rec_not_gap与T1的LOCK S不兼容,因此T1被堵塞 随后,T2又执行了(60,8)的insert语句:insert into info values (60,8) 由于其插入的唯一索引值是8,因此不存在主键冲突,直接执行乐观插入操作。执行乐观插入时,需要检查其它事务是否堵塞insert操作。其核心是获取待插入记录的下一个值(这里刚好是10),并获取该记录上的所有锁,与需要添加的锁判断是否存在冲突。 T1持有了记录11的LOCK_S锁与T2的LOCK_X、LOCK_INSERT_INTENTION不兼容,因此T2被T1堵塞 死锁形成。 解决 • 适当的减少Unique索引 • 避免插入重复的值(唯一索引所在列) Enjoy GreatSQL :) 关于 GreatSQL GreatSQL是适用于金融级应用的国内自主开源数据库,具备高性能、高可靠、高易用性、高安全等多个核心特性,可以作为MySQL或Percona Server的可选替换,用于线上生产环境,且完全免费并兼容MySQL或Percona Server。 相关链接: GreatSQL社区 Gitee GitHub Bilibili GreatSQL社区: 社区有奖建议反馈: https://greatsql.cn/thread-54-1-1.html 社区博客有奖征稿详情: https://greatsql.cn/thread-100-1-1.html (对文章有疑问或者有独到见解都可以去社区官网提出或分享哦~) 技术交流群: 微信&QQ群: QQ群:533341697 微信群:添加GreatSQL社区助手(微信号:wanlidbc )好友,待社区助手拉您进群。

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册