MySQL数据库---笔记5

这篇具有很好参考价值的文章主要介绍了MySQL数据库---笔记5。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、锁

1.1、介绍

  • 概述

锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。

  • 分类
    MySQL中的锁,按照锁的粒度分,分为以下三类:
    1. 全局锁: 锁定数据库中的所有表。
    2. 表级锁: 每次操作锁住整张表。
    3. 行级锁: 每次操作锁住对应的行数据。

1.2、全局锁

1.2.1、全局锁介绍

  • 介绍

全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语句,已经更新操作的事务提交语句都将被阻塞。

其典型的使用场景是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。

MySQL数据库---笔记5,数据库,mysql,笔记
MySQL数据库---笔记5,数据库,mysql,笔记

  • 加入了全局锁之后,只能读,不能修改数据

  • 加全局锁

    flush tables with read lock;
    
  • 备份数据

    mysqldump -h指定主机地址 -uroot -p密码 需要备份的数据库 > 需要备份到的SQL文件;
    
  • 解锁

    unlock tables;
    

1.2.2、一致性数据备份

  • 特点

数据库中加全局锁,是一个比较重的操作,存在以下问题:

  1. 如果在主库上备份,那么在备份期间都不能执行更新,业务基本上就得停摆。
  2. 如果在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制日志(binlog),会导致主从延迟。

在InnoDB引擎中,我们可以在备份时加上参数--single-transaction参数来完成不加锁的一致性数据备份。

mysqldump --single-transaction -uroot-p密码 需要备份的数据库 > 需要备份到的SQL文件;

1.3、表级锁

表级锁,每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM、InnoDB、BDB等存储引擎中。

对于表级锁,主要分为以下三类:

  1. 表锁
  2. 元数据锁( meta data lock,MDL)
  3. 意向锁

1.3.1、表锁

对于表锁,分为两类:

  1. 表共享读锁( read lock )
  2. 表独占写锁( write lock )

语法:

  1. 加锁:lock tables 表名... read/write。
  2. 释放锁:unlock tables/ 客户端断开连接。
  • 读锁
    MySQL数据库---笔记5,数据库,mysql,笔记

  • 写锁MySQL数据库---笔记5,数据库,mysql,笔记
    读锁不会阻塞其他客户端的读,但是会阻塞写。写锁既会阻塞其他客户端的读,又会阻塞其他客户端的写。

1.3.2、元数据锁(meta data lock , MDL)

MDL加锁过程是系统自动控制,无需显式使用,在访问一张表的时候会自动加上。MDL锁主要作用是维护表元数据的数据一致性,在表上有活动事务的时候,不可以对元数据进行写入操作。为了避免DML与DDL冲突,保证读写的正确性。

在MySQL5.5中引入了MDL,当对一张表进行增删改查的时候,加MDL读锁(共享);当对表结构进行变更操作的时候,加MDL写锁(排他)。

对应SQL 锁类型 说明
lock tables xxx read / write SHARED_READ_ONLY / SHARED_NO_READ_WRITE
select 、select … lock in share mode SHARED_READ 与SHARED_READ、SHARED_WRITE兼容,与EXCLUSIVE互斥
insert 、update、delete、select … for update SHARED_WRITE 与SHARED_READ、SHARED_WRITE兼容,与EXCLUSIVE互斥
alter table … EXCLUSIVE 与其他的MDL都互斥

查看元数据锁:

select object type,object_ schema,object_ name,lock_type,lock_duration from performance schema.metadata_locks;

1.3.3、意向锁

  1. 意向共享锁(IS):由语句select...lock in share mode 添加
    表锁共享锁(read)兼容,与表锁排它锁(write)互斥
  2. 意向排他锁(IX):由insert、 update、delete.select ... for update添加。
    表锁共享锁(read)及排它锁(write)都互斥意向锁之间不会互斥
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;

1.4、行级锁

1.4.1、介绍

行级锁,每次操作锁住对应的行数据。锁定粒度最小,发生锁冲突的概率最低,并发度最高。应用在InnoDB存储引擎中。

InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁。对于行级锁,主要分为以下三类:

  1. 行锁(Record Lock)︰锁定单个行记录的锁,防止其他事务对此行进行update和delete。在RC、RR隔离级别下都支持。
    MySQL数据库---笔记5,数据库,mysql,笔记
  2. 间隙锁(Gap Lock)∶锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读。在RRA隔离级别下都支持。
    MySQL数据库---笔记5,数据库,mysql,笔记
  3. 临键锁(Next-Key Lock)∶行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap。在RR隔离级别下支持。
    MySQL数据库---笔记5,数据库,mysql,笔记

1.4.2、行锁

lnnoDB实现了以下两种类型的行锁:

  1. 共享锁(S)︰允许一个事务去读一行,阻止其他事务获得相同数据集的排它锁。
  2. 排他锁(X)∶允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。
S(共享锁) X(排他锁)
S(共享锁) 兼容 冲突
X(排他锁) 冲突 冲突
SQL 行锁类型 说明
INSERT … 排他锁 自动加锁
UPDATE… 排他锁 自动加锁
DELETE … 排他锁 自动加锁
SELECT(正常) 不加任何锁
SELECT …LOCK IN SHARE MODE 共享锁 需要手动在SELECT之后加LOCK IN SHARE MODE
SELECT … FOR UPDATE 排他锁 需要手动在SELECT之后加FOR UPDATE

默认情况下,InnoDB在REPEATABLE READ事务隔离级别运行,InnoDB使用next-key锁进行搜索和索引扫描,以防止幻读。

  1. 针对唯一索引进行检索时,对已存在的记录进行等值匹配时,将会自动优化为行锁。
  2. InnoDB的行锁是针对于索引加的锁,不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,此时就会升级为表锁。

可以通过以下SQL,查看意向锁及行锁的加锁情况:

select object_schema,object_name,index_name,ock_type.lock mode,lock data from performance_schema.data_locks;

1.4.3、间隙锁/临建锁

默认情况下,InnoDB在 REPEATABLE READ事务隔离级别运行,InnoDB使用next-key锁进行搜索和索引扫描,以防止幻读。

  1. 索引上的等值查询(唯一索引),给不存在的记录加锁时,优化为间隙锁。
  2. 索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock退化为间隙锁。
  3. 索引上的范围查询(唯一索引)–会访问到不满足条件的第一个值为止。

注意:间隙锁唯一目的是防止其他事务插入间隙。间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用间隙锁。

MySQL数据库---笔记5,数据库,mysql,笔记

二、InnoDB引擎

2.1、逻辑存储结构

MySQL数据库---笔记5,数据库,mysql,笔记

2.2、架构

MySQL5.5版本开始,默认使用InnoDB存储引擎,它擅长事务处理,具有崩溃恢复特性,在日常开发中使用非常广泛。下面是/nnoDB架构图,左侧为内存结构,右侧为磁盘结构。

MySQL数据库---笔记5,数据库,mysql,笔记

2.2.1、内存架构

  • Buffer Pool 缓冲池

MySQL数据库---笔记5,数据库,mysql,笔记

  • Change Buffer 更改缓冲区

MySQL数据库---笔记5,数据库,mysql,笔记

  • 自适应Hash

MySQL数据库---笔记5,数据库,mysql,笔记

  • 日志缓冲区

MySQL数据库---笔记5,数据库,mysql,笔记

2.2.2、磁盘结构

  • 系统表空间 独立表空间

MySQL数据库---笔记5,数据库,mysql,笔记

  • 通用表空间 撤销表空间 临时表空间

MySQL数据库---笔记5,数据库,mysql,笔记

  • 双写缓冲区 重做日志

MySQL数据库---笔记5,数据库,mysql,笔记

2.2.3、后台线程

MySQL数据库---笔记5,数据库,mysql,笔记

  1. Master Thread

核心后台线程,负责调度其他线程,还负责将缓冲池中的数据异步刷新到磁盘中,保持数据的一致性,还包括脏页的刷新、合并插入缓存、undo页的回收。

  1. IO Thread

在InnoDB存储引擎中大量使用了AIO来处理O请求,这样可以极大地提高数据库的性能,而IOThread主要负责这些lO请求的回调。

线程类型 默认个数 职责
Read thread 4 负责读操作
Write thread 4 负责写操作
Log thread 1 负责将日志缓冲区刷新到磁盘
Insert buffer thread 1 负责将写缓冲区内容刷新到磁盘
  1. Purge Thread

主要用于回收事务已经提交了的undo log,在事务提交之后,undo log可能不用了,就用它来回收。

  1. Page Cleaner Thread

协助Master Thread 刷新脏页到磁盘的线程,它可以减轻Master Thread的工作压力,减少阻塞。

2.3、事务原理

2.3.1、概述

事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。

特性:

  • 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
  • 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
  • 隔离性(lsolation)∶数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
  • 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

MySQL数据库---笔记5,数据库,mysql,笔记

2.3.2、redo log

重做日志,记录的是事务提交时数据页的物理修改,是用来实现事务的持久性

该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log file) ,前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都存到该日志文件中,用于在刷新脏页到磁盘,发生错误时,进行数据恢复使用。

MySQL数据库---笔记5,数据库,mysql,笔记

2.3.3、undo log

回滚日志,用于记录数据被修改前的信息,作用包含两个:提供回滚和MVCC(多版本并发控制)。
undo logredo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。

Undo log销毁: undo log在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些日志可能还用于MVCC。

Undo log存储: undo log采用段的方式进行管理和记录,存放在前面介绍的rollback segment 回滚段中,内部包含1024个undo logsegment。

2.4、MVCC

2.4.1、基本概念

  • 当前读

读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。对于我们日常的操作,如:select...lock in share mode(共享锁), select ... for updateupdateinsertdelete(排他锁)都是一种当前读。

  • 快照读

简单的select(不加锁)就是快照读,快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。

  • Read Committed:每次select,都生成一个快照读。

  • Repeatable Read:开启事务后第一个select语句才是快照读的地方。

  • Serializable:快照读会退化为当前读。

  • MVCC

全称Multi-Version Concurrency Control,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为MysQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现,还需要依赖于数据库记录中的三个隐式字段undo log日志readView

2.4.2、隐式字段

  • 记录中的隐式字段

MySQL数据库---笔记5,数据库,mysql,笔记

隐藏字段 含义
DB_TRX_ID 最近修改事务ID,记录插入这条记录或最后一次修改该记录的事务ID。
DB_ROLL_PTR 回滚指针,指向这条记录的上一个版本,用于配合undo log,指向上一个版本。
DB_ROW_ID 隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段。

2.4.3、undo log日志

回滚日志,在insert update.delete的时候产生的便于数据回滚的日志。

当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。

而update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除。

  • undo log 版本链

MySQL数据库---笔记5,数据库,mysql,笔记
不同事务或相同事务对同一条记录进行修改,会导致该记录的undolog生成一条记录版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录。

2.4.4、readView

ReadView(读视图)是 快照读 SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的) id。
ReadView中包含了四个核心字段:

字段 含义
m_ids 当前活跃的事务ID集合
min_trx_id 最小活跃事务ID
max_trx_id 预分配事务ID,当前最大事务ID+1(因为事务ID是自增的)
creator_trx_id ReadView创建者的事务ID

MySQL数据库---笔记5,数据库,mysql,笔记

不同的隔离级别,生成ReadView的时机体不同:

  • READ COMMITTED∶在事务中每一次执行快照读时生成ReadView。
  • REPEATABLE READ:仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView。

2.4.5、原理分析(RC级别)

RC隔离级别下,在事务中每一次执行快照读时生成ReadView。
MySQL数据库---笔记5,数据库,mysql,笔记

2.4.6、原理分析(RR级别)

  • RR隔离级别下,仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView。

MySQL数据库---笔记5,数据库,mysql,笔记
MySQL数据库---笔记5,数据库,mysql,笔记

MySQL数据库---笔记5,数据库,mysql,笔记

三、MySQL管理

3.1、系统数据库介绍

Mysql数据库安装完成后,自带了一下四个数据库,具体作用如下:

数据库 含义
mysql 存储MySQL服务器正常运行所需要的各种信息(时区、主从、用户、权限等)
information_schema 提供了访问数据库元数据的各种表和视图,包含数据库、表、字段类型及访问权限等
performance_schema 为MySQL服务器运行时状态提供了一个底层监控功能,主要用于收集数据库服务器性能参数
sys 包含了一系列方便DBA和开发人员利用performance_schema性能数据库进行性能调优和诊断的视图

3.2、常用工具

3.2.1、mysql

该mysql不是指mysql服务,而是指mysql的客户端工具。

语法:
	mysql [options] [database]
选项:
	-U, --user=name 		#指定用户名
	-p,--password[=name]    #指定密码
	-h, --host=name			#指定服务器IP或域名
	-P, --port=port		    #指定连接端口
	-e,--execute=name		#执行SQL语句并退出

-e选项可以在Mysql客户端执行SQL语句,而不用连接到MySQL数据库再执行,对于一些批处理脚本,这种方式尤其方便。

示例:
	mysql-uroot -p123456 db01 -e "select * from stu";

3.2.2、mysqladmin

mysqladmin是一个执行管理操作的客户端程序。可以用它来检查服务器的配置和当前状态
创建并删除数据库等。

指令

mysqladmin --help

MySQL数据库---笔记5,数据库,mysql,笔记

3.2.3、mysqlbinlog

由于服务器生成的二进制日志文件以二进制格式保存,所以如果想要检查这些文本的文本格式,就会使用到mysqlbinlog日志管理工具。

语法:
	mysqlbinlog [options] log-files1 log-files2 ...
选项:
	-d, --database=name			指定数据库名称,只列出指定的数据库相关操作。
	-O, --offset=#				忽略掉日志中的前n行命令。
	-r, --result-file=name		将输出的文本格式日志输出到指定文件。
	-s, --short-form			显示简单格式,省略掉一些信息。
	--start-datatime=date1 --stop-datetime=date2	指定日期间隔内的所有日志。
	--start-position=pos1 --stop-position=pos2		指定位置间隔内的所有日志。

3.2.4、mysqlshow

mysqlshow客户端对象查找工具,用来很快地查找存在哪些数据库、数据库中的表、表中的列或者索引。

语法:
	mysqlshow [options] [db_name [table_name [col_name]
选项:
	--count		显示数据库及表的统计信息(数据库,表均可以不指定)
	-i			显示指定数据库或者指定表的状态信息
示例:
	#查询每个数据库的表的数量及表中记录的数量
	mysqlshow-uroot-p2143 --count
	
	#查询test库中每个表中的字段书,及行数
	mysqlshow-uroot-p2143 test --count
	
	#!查询test库中book表的详细情况
	mysqlshow-uroot-p2143 test book --count

3.2.5、mysqldump

mysqldump客户端工具用来备份数据库或在不同数据库之间进行数据迁移。备份内容包含创建表,及插入表的SQL语句。

语法:
	mysqldump [options] db_name [tables]
	mysqldump [options] --database/-B db1 [db2 db3..]
	mysqldump [options] --all-databases/-A
连接选项:
	-u, --USer=name				指定用户名
	-p,--password[=name]		指定密码
	-h, --host=name				指定服务器ip或域名
	-P, --port=#				指定连接端口
输出选项:
	--add-drop-database			在每个数据库创建语句前加上drop database语句
	--add-drop-table			在每个表创建语句前加上 drop table语句,默认开启;不开启(--skip-add-drop-table)
	-n, --no-create-db			不包含数据库的创建语句
	-t, --no-create-info		不包含数据表的创建语句
	-d --no-data				不包含数据
	-T, --tab=name				自动生成两个文件:一个.sql文件,创建表结构的语句;一个.txt文件,数据文件
  • 使用-T指令需要生成到其信任的路径下

MySQL数据库---笔记5,数据库,mysql,笔记

3.2.6、mysqlimport/source

mysqlimport是客户端数据导入工具,用来导入mysqldump加-T参数后导出的文本文件。

  • 需要在其信任的路径下进行导入
语法:
	mysqlimport [options] db_name textfile1 [textfile2...]
示例:
	mysqlimport-uroot-p2143 test /tmp/city.bxt

如果需要导入sql文件,可以使用mysql中的source指令:

语法:
	source /root/xooox.sql

MySQL数据库---笔记5,数据库,mysql,笔记文章来源地址https://www.toymoban.com/news/detail-531322.html

到了这里,关于MySQL数据库---笔记5的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL数据库学习笔记(二)

    排序查询 :select 字段列表 from [表名]  order by  [字段名1] [asc升序/desc降序,默认值为升序],[字段名2] [排序方式];//字段名1为优先级排序,如果字段名1有相同的,再以字段名2排序 聚合函数 : count 统计数量(一般不选null的列) max 最大值 min 最小值 sum 总和 avg 平均值 Select

    2024年02月11日
    浏览(43)
  • QT学习笔记-开发环境编译Qt MySql数据库驱动与交叉编译Qt MySql数据库驱动

    如果需要在QT程序中实现与MySQL数据库的交互,那么必不可少的一环就是对Qt MySql数据库驱动的编译。 操作系统:Windows10 专业版 64位 Qt版本:Qt 5.15.2 开发环境Qt安装路径:D:Qt 交叉编译服务器:Ubuntu 18.4 交叉编译服务器Qt安装路径:/opt/Qt 目标芯片:rk3568 目标平台:arm64 Qt安装

    2024年02月11日
    浏览(78)
  • 学习笔记-MySql数据库介绍与连接

    一.MySQL数据库介绍 MySQL是一个关系型数据库管理系统,在 WEB 应用方面,MySQL是最好的 RDMS (Relational Database Management System,关系数据库管理系统) 应用软件,它是由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品,MySQL 是最流行的关系型数据库管理系统中的一个。 1.特点 开源,

    2024年01月19日
    浏览(45)
  • 【MySQL高级篇笔记-其他数据库日志(下) 】

    此笔记为尚硅谷MySQL高级篇部分内容 目录 一、MySQL支持的日志 1、日志类型 2、日志的弊端 二、慢查询日志(slow query log) 三、通用查询日志(general query log) 1、问题场景  2、查看当前状态 3、启动日志 方式 1 :永久性方式 方式2:临时性方式  4、查看日志 5、停止日志 方式1:永

    2024年02月08日
    浏览(147)
  • 【MySQL高级篇笔记-数据库的设计规范(中) 】

    此笔记为尚硅谷MySQL高级篇部分内容 目录 一、为什么要数据库设计  二、范式 1、范式简介 2、范式都包括哪些  3、键和相关属性的概念 4、第一范式(1st NF) 5、第二范式(2nd NF) 6、第三范式(3rd NF) 7、小结 三、反范式化 1、概述 2、 应用举例 3、反范式的新问题 4、反范式的适用

    2024年02月08日
    浏览(69)
  • 【教程】MySQL数据库学习笔记(三)——数据定义语言DDL(持续更新)

    写在前面: 如果文章对你有帮助,记得点赞关注加收藏一波,利于以后需要的时候复习,多谢支持! 第一章 《认识与环境搭建》 第二章 《数据类型》 第三章 《数据定义语言DDL》 DDL(Data Definition Language,数据定义语言) 是用于定义和管理数据库对象(如表、视图、索引等

    2024年02月20日
    浏览(46)
  • SQL笔记(1)——MySQL创建数据库(收藏吃灰版)

    本文详细记录MySQL创建一个数据库的过程,不只是构建步骤,更多的是每一步涉及到的知识点。一般创建数据库有两种方式,一种是命令,另外一种就是通过数据库管理工具,本文主要记录通过命令的方式创建; 后面的学习也都是基于这个数据库进行的; 创建一个大学生成绩

    2024年02月08日
    浏览(56)
  • MySQL 课后习题解析与笔记——学生选课数据库相关操作

    这篇文章记录一下帮助粉丝朋友一起学习解决的 MySQL 课后习题,内容很基础,都是基础的数据库语句和操作,内容是关于学生选课数据库的一些操作。这里我用 MySQL 和 Navicat 完成这些题目。 题目如下: 现有学生选课数据库:Student(Sno,Sname,Sage,Ssex,Sdept)、 Course(Cno

    2024年02月08日
    浏览(79)
  • 珍藏多年的MySQL函数大全笔记,掌握数据库真不难

    做程序员的谁会离得开数据库呢? 今天就来分享一下我整理的MySQL的常用函数,基本上囊括了平时要用的函数,它们已经陪我走过了不少年头了,风里来雨里去,缝缝补补又几年,希望能帮到你们! 如果数据库函数你能用得好,其他的东西也就水到渠成了。 序号 函数 说明

    2023年04月23日
    浏览(55)
  • 运维笔记之centos7安装mysql数据库

    如果使用的4.1以上版本的rpm的话,除了import mysql的公钥到个人用户的配置中,还需要import mysql的公钥到RPM的配置中

    2024年02月04日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包