MySQL权限表损坏导致无法启动怎么办?

一、背景

近期,公司RDS云产品的MySQL Server版本进行升级,由目前使用的5.7.26版本升级到最新版本5.7.31;升级后测试同学发现:在MySQL创建用户后,5.7.31版本重新启动集群会出现启动失败的现象;而5.7.26版本在相同测试场景下是正常启动的。这到底是为什么呢?

二、问题复现

2.1 实验环境

  • CentOS 7.5
  • MySQL 5.7.31

2.2 操作步骤

按照测试同学的测试步骤,首先创建一个用户:

mysql> create user test@'%' identified by '1234';
Query OK, 0 rows affected (0.01 sec)

然后关闭mysqld;这里需要介绍一下,我们集群的关闭方式是如下方式:

shell> kubectl delete pod yuelei-57-f3b6200-0 -n qfusion-admin

这种方式的内部实现类似于kill -9模式。所以我在线下环境使用kill -9的方式来复现,操作如下:

shell> kill -9 $(pidof mysqld)

然后重启mysqld,操作如下:

shell> mysqld_safe --defaults-file=/etc/mysql/my.cnf &

此时问题复现了,mysqld启动失败,我们查看了下error日志,信息如下:

...
2020-08-18T10:13:55.506415+08:00 0 [ERROR] /usr/local/mysql/bin/mysqld: Table './mysql/user' is marked as crashed and should be repaired
2020-08-18T10:13:55.506553+08:00 0 [ERROR] Fatal error: Can't open and lock privilege tables: Table './mysql/user' is marked as crashed and should be repaired
2020-08-18T10:13:55.506658+08:00 0 [ERROR] Fatal error: Failed to initialize ACL/grant/time zones structures or failed to remove temporary table files.
2020-08-18T10:13:55.506789+08:00 0 [ERROR] Aborting
...

根据报错信息可以看出:MySQL的权限系统表发生了损坏,导致了mysqld启动失败;由于在MySQL 5.7及其之前版本该表是MyISAM引擎,且该引擎不支持事务,所以在mysqld异常崩溃会导致该类型引擎表的损坏;但在mysqld启动时是有参数控制MyISAM引擎的恢复模式,且该参数在我们产品中也配置到了my.cnf中,如下所示:

[mysqld] 
myisam_recover_options=BACKUP,FORCE

2.3 参数解析

对于该参数的官方文档的解释如下:

设置MyISAM存储引擎恢复模式。选项值是OFF、DEFAULT、BACKUP、FORCE或QUICK的值的任意组合。如果指定多个值,请用逗号分隔。指定不带参数的选项与指定DEFAULT相同,指定显式值” “将禁用恢复(与OFF值相同)。如果启用了恢复,则mysqld每次打开MyISAM表时,都会检查该表是否标记为已崩溃或未正确关闭。(只有在禁用外部锁定的情况下运行,最后一个选项才起作用。)在这种情况下,mysqld在表上运行检查。如果表已损坏,mysqld将尝试对其进行修复。

  • OFF:No recovery.
  • DEFAULT:Recovery without backup, forcing, or quick checking.
  • BACKUP:If the data file was changed during recovery, save a backup of the tbl_name.MYD file as tbl_name-datetime.BAK.
  • FORCE:Run recovery even if we would lose more than one row from the .MYD file.
  • QUICK:Do not check the rows in the table if there are not any delete blocks.

服务器自动修复表之前,它将有关修复的注释写到错误日志中。如果您希望能够在无需用户干预的情况下从大多数问题中恢复,则应使用选项BACKUP,FORCE。即使某些行将被删除,这也会强制修复表,但是它将旧的数据文件保留为备份,以便您以后可以检查发生了什么。

全局变量,只读变量,默认为OFF。

三、问题修复

这类MySQL用户表损耗的问题解决方式也是有多种,我这里列举其中一种:

(1)my.cnf中的[mysqld]标签下添加skip_grant_tables,启动时跳过加载系统字典。

[mysqld] 
skip_grant_tables

(2)重启mysqld,然后修复mysql schema下的所有表。

shell> mysqlcheck -uroot -pxxx mysql --auto-repair
...
mysql.user
warning  : 1 client is using or hasn't closed the table properly
status   : OK

(3)在[mysqld]标签下注释或删除掉skip_grant_tables,然后重启mysqld。

shell> mysqld_safe --defaults-file=/etc/mysql/my.cnf &

此时mysqld是可以正常启动的,无异常。

四、深入排查

在产品化中,以上修复方式很不优雅,只是作为临时的解决方案;并且也存在一些令人疑惑的点:

  • 通常情况下在my.cnf中设置myisam_recover_options=BACKUP,FORCE时,启动时会自动修复MyISAM损坏的表;在上述场景中为什么没有自动修复呢?
  • 相同环境下,5.7.26版本mysqld启动是正常的,但是5.7.31版本mysqld启动出现如上述现象;难道是MySQL做了改动吗?

带着这些疑问,我们继续排查出现该现象的原因;此时Google也没有找到一些有效的信息,那么只能通过MySQL源代码来寻找一些答案。

首先需要下载mysql 5.7.31版本的源代码,并搭建mysql debug环境;具体步骤可以自动Google搜索一下,本文就不再赘述了。

在源代码中搜索一下关键词,用于打断点的位置,然后进行调试:

### 确认MySQL版本
shell> cat VERSION
MYSQL_VERSION_MAJOR=5
MYSQL_VERSION_MINOR=7
MYSQL_VERSION_PATCH=31
MYSQL_VERSION_EXTRA=

### 搜索一些关键信息
shell> grep -r "initialize ACL/grant/time" *
mysql-test/r/grant_debug.result:Pattern "Fatal error: Failed to initialize ACL/grant/time zones structures or failed to remove temporary table files." found
mysql-test/t/grant_debug.test:let SEARCH_PATTERN=Fatal error: Failed to initialize ACL/grant/time zones structures or failed to remove temporary table files.;
sql/mysqld.cc:    sql_print_error("Fatal error: Failed to initialize ACL/grant/time zones "

搜索得出的结果很多,我们需要对此进行过滤。mysql-test目录是mysql的测试用例代码,我们可以直 接忽略;需要关注的是sql/mysqld.cc的文件,因为mysqld启动时调用main->mysqld_main->…,而mysqld_main函数是在sql/mysqld.cc目录下,此时我们查看具体的代码(sql/mysqld.cc:4958):

if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
 my_tz_init((THD *)0, default_tz_name, opt_bootstrap) ||
 grant_init(opt_noacl))

{
 abort_loop= true;
 sql_print_error("Fatal error: Failed to initialize ACL/grant/time zones "
 "structures or failed to remove temporary table files.");

 delete_pid_file(MYF(MY_WME));

 unireg_abort(MYSQLD_ABORT_EXIT); 
}

定位到相关代码,大概是sql/mysqld.cc的4958行,且存在if条件判断,此时我们开始调试:

shell> gdb /usr/local/mysql/bin/mysqld 

(gdb) b sql/mysqld.cc:4958
Breakpoint 1 at 0xe6f8d0: file /opt/mysql-server/sql/mysqld.cc, line 4958. 

(gdb) r --defaults-file=/etc/mysql/my.cnf

(gdb) p mysql_rm_tmp_tables()
$1 = 0 '\000'

(gdb) p acl_init(opt_noacl)
$2 = 1 '\001'

(gdb) p my_tz_init((THD *)0, default_tz_name, opt_bootstrap)
$3 = 0 '\000'

(gdb) p grant_init(opt_noacl)
$4 = false

通过以上调试信息,可以判断出acl_init函数返回的值为真;此时我们查看该函数的代码 (
sql/auth/sql_auth_cache.cc:1365):

/*
 Initialize structures responsible for user/db-level privilege checking and
 load privilege information for them from tables in the 'mysql' database.

 SYNOPSIS
 acl_init()
 dont_read_acl_tables TRUE if we want to skip loading data from
 privilege tables and disable privilege checking.

 NOTES
 This function is mostly responsible for preparatory steps, main work
 on initialization and grants loading is done in acl_reload().

 RETURN VALUES
 0 ok
 1 Could not initialize grant's
*/

my_bool acl_init(bool dont_read_acl_tables)
{
 THD *thd;
 my_bool return_val;
 DBUG_ENTER("acl_init");
...

根据该函数的注释发现:该函数是初始化负责用户/数据库级特权检查的结构,并从mysql schema中的表中为其加载特权信息;且return值为1代表的是初始化权限失败。

此后开始逐步调试,观察return相关信息,当调试到lock_table_names函数时,我们发现在Phase 3时return值为true,且根据代码注释发现true代表是Failure;具体代码如下(sql/sql_base.cc:5549):

/**
Acquire "strong" (SRO, SNW, SNRW) metadata locks on tables used by
LOCK TABLES or by a DDL statement.

Acquire lock "S" on table being created in CREATE TABLE statement.

@note Under LOCK TABLES, we can't take new locks, so use
open_tables_check_upgradable_mdl() instead.

@param thd Thread context.
@param tables_start Start of list of tables on which locks
should be acquired.
@param tables_end End of list of tables.
@param lock_wait_timeout Seconds to wait before timeout.
@param flags Bitmap of flags to modify how the tables will be
open, see open_table() description for details.

@retval false Success.
@retval true Failure (e.g. connection was killed)
*/

bool
lock_table_names(THD *thd,
TABLE_LIST *tables_start, TABLE_LIST *tables_end,
ulong lock_wait_timeout, uint flags)
{
 MDL_request_list mdl_requests;
 TABLE_LIST *table;
 MDL_request global_request;
 Hash_set<TABLE_LIST, schema_set_get_key> schema_set(PSI_INSTRUMENT_ME);
 bool need_global_read_lock_protection= false;
...
 // Phase 3: Acquire the locks which have been requested so far.
 if (thd->mdl_context.acquire_locks(&mdl_requests, lock_wait_timeout))
return true;

 /*
Now when we have protection against concurrent change of read_only
option we can safely re-check its value.
Skip the check for FLUSH TABLES ... WITH READ LOCK and
FLUSH TABLES ... FOR EXPORT as they are not supposed to be affected
by read_only modes.
*/
 if (need_global_read_lock_protection &&
 !(flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK) &&
 !(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY) &&
 check_readonly(thd, true))
 return true;
...

调试信息如下:

(gdb) p flags
$7 = 0
(gdb) p need_global_read_lock_protection
$8 = true
(gdb) p check_readonly(thd, true)
$9 = true

可以看到flags的值为0,而
MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK为宏定义值0x1000,与flags的值 做按位与操作,结果自然也是0,当然MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY也是如此;need_global_read_lock_protection是bool类型值,代表是否需要全局读锁的保护,这个值是在table- >mdl_request.type不为MDL_SHARED_READ_ONLY发生改变;check_readonly函数相关信息⻅下面概述。

此时也查看了下MySQL 5.7.26版本代码作为对比,发现lock_table_names函数下的Phase 3后的部分代 码是在5.7.29版本后新增的。如果是git clone的MySQL代码可以用git blame命令查询文件变化的信息:

shell> git blame -L 5637,+10 sql/sql_base.cc
05824063 (Nisha Gopalakrishnan 2019-09-11 13:06:40 +0530 5637)     Now when we have protection against concurrent change of read_only
05824063 (Nisha Gopalakrishnan 2019-09-11 13:06:40 +0530 5638)     option we can safely re-check its value.
0405ebee (Nisha Gopalakrishnan 2019-09-12 19:24:45 +0530 5639)     Skip the check for FLUSH TABLES ... WITH READ LOCK and
0405ebee (Nisha Gopalakrishnan 2019-09-12 19:24:45 +0530 5640)     FLUSH TABLES ... FOR EXPORT as they are not supposed to be affected
0405ebee (Nisha Gopalakrishnan 2019-09-12 19:24:45 +0530 5641)     by read_only modes.
05824063 (Nisha Gopalakrishnan 2019-09-11 13:06:40 +0530 5642)   */
05824063 (Nisha Gopalakrishnan 2019-09-11 13:06:40 +0530 5643)   if (need_global_read_lock_protection &&
0405ebee (Nisha Gopalakrishnan 2019-09-12 19:24:45 +0530 5644)       !(flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK) &&
05824063 (Nisha Gopalakrishnan 2019-09-11 13:06:40 +0530 5645)       !(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY) &&
05824063 (Nisha Gopalakrishnan 2019-09-11 13:06:40 +0530 5646)       check_readonly(thd, true))

上述展示的信息中,最左侧的列值为commit id为05824063和0405ebee,有兴趣的同学可以详细看下。

此功能解决的问题是 BUG#28438114: SET READ_ONLY=1 SOMETIMES DOESN’T BLOCK CONCURRENTDDL.;当然这个代码的变更功能也在5.7 Release Notes中有所体现,如下所示(https://dev.mysql.co
m/doc/relnotes/mysql/5.7/en/news-5-7-29.html):

Under certain conditions, enabling the read_only or super_read_only system variable did not block concurrent DDL statements executed by users without the SUPER privilege. (Bug #28438114, Bug #91852)

最后我们再查看下check_readonly函数,该函数是基于read_only和super_read_only状态执行标准化检查,是禁止(TRUE)还是允许(FALSE)操作。代码如下(
sql/auth/sql_authorization.cc:489):

/**
  @brief Performs standardized check whether to prohibit (TRUE)
or allow (FALSE) operations based on read_only and super_read_only
state.
  @param thd              Thread handler
  @param err_if_readonly  Boolean indicating whether or not
    to add the error to the thread context if read-only is
    violated.

  @returns Status code
@retval TRUE The operation should be prohibited.
@   retval FALSE The operation should be allowed.
*/
bool check_readonly(THD *thd, bool err_if_readonly)
{
  DBUG_ENTER("check_readonly");

  /* read_only=OFF, do not prohibit operation: */
  if (!opt_readonly)
    DBUG_RETURN(FALSE);
...

此时第一反应就是去检查my.cnf中是否包含read_only相关参数,检查之后发现确实是使用了该参数, 如下:

 [mysqld]
 read_only=1

此时注释掉该参数,然后再次启动mysqld,发现MyISAM表可以自动修复,且正常启动;error log信息如下:

...
2020-08-18T11:52:26.775553+08:00 0 [ERROR] /usr/local/mysql/bin/mysqld: Table './mysql/user' is marked as crashed and should be repaired
2020-08-18T11:52:26.776217+08:00 0 [Warning] Checking table: './mysql/user'
2020-08-18T11:52:26.776273+08:00 0 [ERROR] 1 client is using or hasn't closed the table properly
2020-08-18T11:52:26.882537+08:00 0 [Note] Failed to start slave threads for channel ''
2020-08-18T11:52:26.906018+08:00 0 [Note] Event Scheduler: Loaded 0 events
2020-08-18T11:52:26.906480+08:00 0 [Note] /usr/local/mysql/bin/mysqld: ready for connections.
Version: '5.7.31-debug-log' socket: '/var/lib/mysql/sock/mysql.sock' port: 3306 Source distribution

由于docker一些限制,我们在mysqld启动会涉及两次;所以解决该问题的方式为:第一次mysqld的启动时先关闭read_only参数,第二次启动时开启read_only参数。之所以选择默认开启read_only参数, 是为了避免在mysqld启动后,选主逻辑未完成时的保护措施;当然选主完成后,会自动对master执行 set global read_only=0 操作。

五、总结

  • MySQL小版本的升级也会有变化,一定要做好升级前的**度测试工作。
  • MySQL源代码量很多,想要全部了解也很困难;此时我们通过对比不同版本之间的现象差异分别 进行调试,找出差异点后再深入探索到某些函数,效果事半功倍。

六、附录

调试的栈帧信息如下,有兴趣的小伙伴可以研究下:

(gdb) bt
#0 check_readonly (thd=0xcde33f0, err_if_readonly=true) at /opt/mysql- server/sql/auth/sql_authorization.cc:491
#1 0x0000000001486262 in lock_table_names (thd=0xcde33f0, tables_start=0xcdc9100, tables_end=0x0, lock_wait_timeout=31536000, flags=0) at /opt/mysql-server/sql/sql_base.cc:5646
#2 0x0000000001484be5 in Open_table_context::recover_from_failed_open (this=0x7fffffffcad0) at /opt/mysql-server/sql/sql_base.cc:4789
#3 0x0000000001486758 in open_tables (thd=0xcde33f0, start=0x7fffffffcb90, counter=0x7fffffffcbd4, flags=2048, prelocking_strategy=0x7fffffffcc10) at /opt/mysql-server/sql/sql_base.cc:5891
#4 0x0000000001487851 in open_and_lock_tables (thd=0xcde33f0, tables=0x7fffffffccd0, flags=2048, prelocking_strategy=0x7fffffffcc10) at /opt/mysql-server/sql/sql_base.cc:6583
#5 0x0000000000ea2611 in open_and_lock_tables (thd=0xcde33f0, tables=0x7fffffffccd0, flags=2048) at /opt/mysql-server/sql/sql_base.h:486
#6 0x0000000000e9c2cf in acl_reload (thd=0xcde33f0) at /opt/mysql- server/sql/auth/sql_auth_cache.cc:2091
#7 0x0000000000e9a2fd in acl_init (dont_read_acl_tables=false) at /opt/mysql- server/sql/auth/sql_auth_cache.cc:1429
#8 0x0000000000e6f8f2 in mysqld_main (argc=136, argv=0x2c136a8) at /opt/mysql-server/sql/mysqld.cc:4958
#9 0x0000000000e66cdd in main (argc=2, argv=0x7fffffffe458) at /opt/mysql- server/sql/main.cc:32

熟悉MySQL体系结构和innodb存储引擎工作原理;以及MySQL备份恢复、复制、数据迁移等技术;专注于MySQL、MariaDB开源数据库,喜好开源技术。

本文链接:https://www.dzdvip.com/31271.html 版权声明:本文内容均来源于互联网。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 395045033@qq.com,一经查实,本站将立刻删除。
(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022年4月9日 22:38
下一篇 2022年4月10日 12:27

相关推荐

  • 陈伟霆张钧甯宣布领证(陈伟霆真的和张钧甯在一起吗)

    “最近网友对陈伟霆张钧甯的关注度十分高,这主要是因为有人在网上说陈伟霆张钧甯宣布领证了。甚至还爆料出陈伟霆张钧甯这对酒窝夫妇其实在很早的时候就已经秘密的结婚了,现在领证算是正式宣布了。但其实这一切都是网友们自己的猜测而已,两人就是好朋友关系而已,并不是恋人关系。” 娱乐圈颜值较高的男明星和女明星非常之多,不过最近这段时间,被人们炒作的比较火的就是酒窝夫妇陈伟霆和张钧甯两人了,他们二人疑似已经隐婚,因为他们在参加综艺节目向往的生活的时候,两人一见如故打打闹闹默契程度非常之高,就连黄磊都称赞两人似小情侣一般。由于这段时间陈伟霆和杨幂合作的斛珠夫人正式播出,所以最近这段时间关于他的私生活,大家也比较关注。 事实上,陈伟霆早在多年之前就已经和知名的女星张钧甯有过一次合作,也正是有过一次比较默契的搭档经历,所以两个人才建立了扎实的友情基础,后来二人还被拍到一同出席大型盛典,又被拍到私下见面,两个人虽然没有被拍到正面,但是从身材和侧脸来看,二人的确是拥抱在一起,感情非常之好,一点都不像是普通朋友,更像是一对感情颇深的小情侣,所以也就引发了他们两人隐婚的猜测。 之后又有网友和媒体猜测,这对惹人怜爱和磕CP的酒窝夫妇是不是已经领证了,那但其实并非如此,前段时间和张钧甯疑似有领证可能的人是张翰,但是后来大家才发现他们只不过是一起合作了一部影视作品,在为这部作品做公开宣传罢了,而陈伟霆本人也没有和张钧甯谈过恋爱,他本人虽然有过多次恋爱,女友也相当有名,比如我们所熟知的Angelababy和阿sa等人,但是和张钧甯除了有些热络的朋友之情之外,似乎也就没有恋情之说了。 其实明星私底下的感情我们是不得而知的,比如当初大家都觉得陈伟霆可能和张钧甯除了合作过一次之外,就没有什么过多的联系了,但是没想到在几年之后两人一同参加节目,二人居然在节目当中一见如故,交谈十分热络,自然让人一看不免心生疑惑:难道只合作过一次就有如此大的默契吗?肯定是二人私下在一起了,所以才会如此,但其实仔细想想也并非如此,毕竟明星在恋爱方面还是比较低调的,约会的时候也会尽量避免被媒体拍到,只有真正的朋友才会见面的时候大大咧咧。 由此可见,酒窝夫妇也不过是粉丝和影迷们的幻想罢了,他们两人只是生活当中的好朋友,而张钧甯在前段时间也和一位男明星邱泽传出了绯闻,但随后又公开否认,可见张钧甯现在还是注重事业的发展,并没有谈恋爱的意思,…

    2022年8月9日
    103
  • seo为什么有灰色行业?如何制作一份合理的seo方案?

    随着互联网时代的不断进步,发现西安很多企业对seo推广排名越来越重视,那么今天就给大家讲讲seo为什么有灰色行业?如何制作一份合理的seo方案?? seo推广排名要注意以下细节和问题: 1、鉴定一家的西安网络营销公司是否稳妥,无非就是从优化排名公司的实力、效果、扣费方式等方面来分析。西安SEO优化排名公司实力就不用多讲了,这个非常重要,SEO排名优化团队技术怎么样,规模怎么样,都是一家百度排名优化公司实力的体现。百度优化排名司案例,网络SEO排名客户案例是最直接体现西安排名优化公司实力如何,看他们的案例的实时情况,就能知道做的怎么样。百度排名优化公司按关键词收费,此模式对于长期需要稳定的网站来说,不太合适,网络优化排名会有波动,做上去以后,营销优化排名也会下降,需要长期维护。西安百度优化排名公司还有长期外包的付费方式,这种方式也比较靠谱,时时有人管理,长期保证网站SEO排名效果。但我估计这位读者真正想问的是,这些网站是同一个人或公司的,而且内容是抄袭、转载、差不多的,放在一个服务器上,会不会影响SEO?那这就是站群作弊嘛,搜索引擎没有检测出来就没事,检测出来惩罚降权是可以预期的。看了上面的选择标准,如果有需要,公司可以找我们做SEO。除了做以上工作,还可以保证优化推广的效果,3个月内就可以把网站排名优化到前10。。 2、网络营销推广要在搜索引擎中获得更多的流量和排名,优先要对网站做定位,其次选择适当的核心关键词和行业词,这样才可以让网站能够获得一定用户流量,紧接着就要做好网站基础优化,同时稳定更新文章内容,这样才能够促使网站关键词在搜索引擎中可以稳定增长。相较于b2b平台来说,越来越多的企业选择做自己的独立网站进行产品和品牌宣传。而外贸网站推广中,谷歌优化企业选择最多的一种方式。那么到底谷歌优化该如何做呢?下面云程网络就来为大家具体介绍一下。由于106短信平台本身就是1对1的精准投放,因此这种营销推广方式比其他营销方式更快;第二,很多短信营销成本较低,与百度竞价广告不同,这意味着企业可以获得更高的盈利;最后,通过106短信平台的使用,在未知的人群中挖掘潜在用户,进行精准营销推广,获取更多的精准客户。。 3、网站关键词优化概念不多,对于企业来说,结果是终结论,所以正规外包seo公司可以签订合同,如果合同没有优化到预定的排名,可以无条件退款,保证企业的权益。选择关键词是…

    2021年8月6日
    12
  • 电脑C盘一定要删除的文件,误删也能恢复回来

    电脑是我们办公文员经常使用的一个设备,久而久之,就会发现电脑越来越卡顿,其实不是电脑配置老化的问题,还有一种可能就是没有定时清理的习惯,其实这样也会导致电脑卡顿的。电脑C盘中,有四个文件夹一定要定时清理,哪四个呢?看下去,我来告诉你! 1、Temp:存放的是电脑临时存储文件 2、Prefetch:电脑直接访问过的 3、Download:储存的是Windows系统更新时,下载的数据补贴和一些安装包等 4、LogFiles:系统缓存日志,和具体时间系统做了什么动作 以上这四个文件夹里的内容都是可以清理的,当然,这里指的是文件夹里面的缓存垃圾,不是整个文件夹哦。 清理文件时,如果不小心误删了重要文件,那么应该如何找回呢?这里推荐以下工具快速找回,注意:软件并不保证能恢复100%的文件,具体还是以实际情况而定,一般能在软件中预览到的,都能恢复。如何恢复呢?下面一起来看看吧! 推荐使用:金舟数据恢复软件 操作方法: 第一步、在电脑上打开软件,在这里选择恢复文件的所在磁盘,然后点击“下一步”; 第二步、恢复模式分为两种,误删文件恢复和万能恢复,根据下方的说明选择符合要求的恢复模式,点击“下一步”; 第三步、如图,在扫描出来的文件中,如果已经找到需要恢复的文件,可直接勾选中选择恢复,无需等待扫描结束; 第四步、选中的文件可进行双击预览,能在软件中预览的文件都是可以恢复的,点击“恢复”; 第五步、恢复的文件需要选择一个新的磁盘存储,以免造成文件被二次破坏; 第六步、恢复完成后会得到以下提示,点击前往导出目录查看文件即可; 第七步、如图,以下就是刚刚恢复回来的文件啦!

    2021年6月21日
    30
  • 什么是智能换电柜?有什么具体作用?

    随着社会的快速发展,人们的生活节奏越来越快,加上移动互联网的普及,不知不觉,外卖叫餐已经成为许多打工人离不开的生活方式,各个平台的外卖骑手也奔波在城市每个角落。 小区场所 据不完全统计,全平台外卖骑手总从业人数已经超过了700万人,可以说外卖行业已经成为了中国经济体系下重要的一环。 电瓶车作为外卖骑手的主要交通工具,对电池的要求特别高,它的续航能力直接影响骑手每天的收入。市面上一般的电瓶车电池续航大概在60公里,但充电时间却需要8小时以上,这对于骑手来说肯定使不够的。为了解决这个问题,很多城市出现了“共享智能换电柜”. 共享智能换电柜 安装换电柜 这个“共享智能换电柜”可以看作是电动车的共享充电宝,当外卖骑手在送餐过程中电动车电量不足,只需打开手机app定位到附近的智能换电柜,按流程更换电池,整个流程下来1分钟内就能完成。对于时间就是金钱的外卖行业,这极大地提高了效率,不再担心电动车的续航问题。 此外,智能换电柜系统自身设有高温预警、烟雾预警、水浸预警、灭火装置、风冷装置、蜂鸣报警等安全系统,确保产品安全,规避意外发生。 智能换电柜还拥有移动端软件应用系统,可以对电池的电量进行实时预警,并对可用电量进行骑行里程预估,帮助外卖骑手智能化管理自己的电动车及提前安排出行方案。 智能换电柜将广泛覆盖人们的生活聚集场所,为骑手们建立更方便快捷的充电场景。

    2021年6月22日
    12
  • 拼多多怎么做用户增长的?拼多多用户增长方式有哪些?

    上线两年半,但GMV已经达到了国内电商第三名,远超唯品会、蘑菇街等老牌电商企业,日单量更是已经超过了京东。

    如此快的增长速度,背后对应的是怎样的产品和运营策略呢?

    2021年5月11日
    23
  • 华为P50 Pro新色发布,续写移动影像旗舰传奇

    华为P50Pro系列手机一经发布,便获得了行业及消费者的广泛关注。3月16日,在华为全屋智能新品发布会上,华为P50Pro系列发布了丹霞橙、云锦白、星河蓝三款新色。华为P50Pro系列新色款带着夕阳的光辉,白昼的明丽,夜晚的梦幻,为用户带来更多样的选择,更心动的体验。华为P50Pro在带来全新配色的同时,其所承载的华为影像?也以创新实力成为大众关注的焦点。 极致卓越的拍摄体验,华为影像?自成一派 移动影像的出现打破了专业摄影师对于光影的“垄断地位”,让每个人都可以成为影像的创造者。纵观移动影像技术发展的历史,华为P系列为其留下了浓墨重彩的一笔。从华为P9系列的双摄系统,到华为P10系列的人像摄影;从华为P20系列的超级夜景模式,到华为P30系列的潜望式长焦架构;从华为P40系列的全时段、全焦段超清影像,再到华为P50系列业界首创的全新移动影像技术,华为书写出一部独一无二的影像传奇,移动影像技术也步入到一个新的阶段。 华为P50Pro系列的发布,也标志着华为在计算摄影领域形成了完整的技术体系,构建起了未来计算摄影的产业技术规范。华为的每一次探索,都深入触及移动影像的痛点,不断推动移动影像行业的发展与进步,华为影像?已经成为移动影像领域的先驱者与引领者。 里程碑式的技术创新,探索移动影像更多可能性 华为P50Pro系列发布之后,在计算摄影领域,华为从“光学系统、成像技术、图像处理”三个维度构建起了未来计算摄影的产业技术规范,并形成了独一无二的移动摄影技术体系,成为影像行业发展的里程碑。 众所周知,光在传递过程中会出现一定的偏差、色散等问题,而这些问题是任何光学镜头都无法避免的。经过多年发展,手机的影像硬件规格已达到天花板级别的配置,其色彩还原能力、长焦能力,以及在暗光环境下的光线感知力也到了发展的瓶颈期。而华为引领的计算光学(xdoptics)技术,突破了光学系统物理的边界,以业界首创“全局式”图像信息复原系统,在成像阶段对光学误差进行修正,记录和恢复真实世界的光影,为移动影像带来了新的发展方向。 华为P50Pro系列通过完备的软、硬件配合,和全色域2000+色彩调教,使原色和画质获得全新的突破,影像效果进一步提升。华为P50Pro系列全新升级的原色引擎XDFusionPro引入超级滤光系统、原色引擎和超动态范围技术,可以让暗光环境下的图像拥有更高的动态范围。搭配计算光…

    2022年3月17日
    12