日志和备份

日志

MySQL 的日志默认保存位置为 /usr/local/mysql/data

1日志类型与作用:

1.redo 重做日志:达到事务一致性(每次重启会重做)
作用:确保日志的持久性,防止在发生故障,脏页未写入磁盘。重启数据库会进行redo log执行重做,达到事务一致性

2.undo 回滚日志

作用:保证数据的原子性,记录事务发生之前的一个版本,用于回滚,innodb事务可重复读和读取已提交 隔离级别就是通过mvcc+undo实现

3.errorlog 错误日志
作用:Mysql本身启动,停止,运行期间发生的错误信息

  1. slow query log 慢查询日志
    作用:记录执行时间过长的sql,时间阈值(10s)可以配置,只记录执行成功
    另一个作用:在于提醒优化

  2. bin log 二进制日志
      作用:用于主从复制,实现主从同步
    记录的内容是:数据库中执行的sql语句

6.relay log 中继日志

作用:用于数据库主从同步,将主库发来的bin log保存在本地,然后从库进行回放

  1. general log 普通日志
      作用:记录数据库的操作明细,默认关闭,开启后会降低数据库性能
mysql -u root -P
show variables like 'general%';       #查看通用查询日志是否开启
show variables like 'log_bin%';       #查看二进制日志是否开启
show variables like '%slow%';         #查看慢查询日功能是否开启
show variables like 'long_query_time';    #查看慢查询时间设置
set global slow_query_log=ON;         #在数据库中设置开启慢查询的方法

PS: variables 表示变量 like 表示模糊查询



##配置文件
vim /etc/my.cnf
[mysqld]
##错误日志,用来记录当MySQL启动、停止或运行时发生的错误信息,默认已开启
log-error=/usr/local/mysql/data/mysql_error.log     #指定日志的保存位置和文件名

##通用查询日志,用来记录MySQL的所有连接和语句,默认是关闭的
general_log=ON
general_log_file=/usr/local/mysql/data/mysql_general.log

##二进制日志(binlog),用来记录所有更新了数据或者已经潜在更新了数据的语句,记录了数据的更改,可用于数据恢复,默认已开启
log-bin=mysql-bin      
或
log_bin=mysql-bin

##慢查询日志,用来记录所有执行时间超过long_query_time秒的语句,可以找到哪些查询语句执行时间长,以便提醒优化,默认是关闭的
s1ow_query_log=ON
slow_query_log_file=/usr/local/mysql/data/mysql_slow_query.log
long_query_time=5        #设置超过5秒执行的语句被记录,缺省时为10秒

##复制段
log-error=/usr/local/mysql/data/mysql_error.log
general_log=ON
general_log_file=/usr/local/mysql/data/mysql_general.log
log-bin=mysql-bin
slow_query_log=ON
slow_query_log_file=/usr/local/mysql/data/mysql_slow_query.log
long_query_time=5


systemctl restart mysqld


#xxx(字段)
xxx% 以xxx为开头的字段
%xxx 以xxx为结尾的字段
%xxx% 只要出现xxx字段的都会显示出来
xxx   精准查询

#二进制日志开启后,重启mysql 会在目录中查看到二进制日志
cd /usr/local/mysql/data
ls
mysql-bin.000001		#开启二进制日志时会产生一个索引文件及一个索引列表

索引文件:记录更新语句
索引文件刷新方式:
1、重启mysql的时候会更新索引文件,用于记录新的更新语句
2、刷新二进制日志

mysql-bin.index:
二进制日志文件的索引

备份

1为什么要备份

灾难恢复:硬件故障、软件故障、自然灾害、黑客攻击、误操作测试等数据丢失场景

2备份类型

完全备份,部分备份

完全备份:整个数据集

部分备份:只备份数据子集,如部分库或表

完全备份、增量备份、差异备份

增量备份:仅备份最近一次完全备份或增量备份(如果存在增量)以来变化的数据,备份较

快,还原复杂

冷、温、热备份
冷备:读、写操作均不可进行,数据库停止服务
温备:读操作可执行;但写操作不可执行
热备:读、写操作均可执行
 MyISAM:温备,不支持热备
 InnoDB:都支持
 
物理和逻辑备份
物理备份:直接复制数据文件进行备份,与存储引擎有关,占用较多的空间,速度快
逻辑备份:从数据库中“导出”数据另存而进行的备份,与存储引擎无关,占用空间少,速度慢,可
能丢失精度

3实际操作

3.1 冷备份:

环境准备:
use kgc;
create table if not exists info1 (
id int(4) not null auto_increment,
name varchar(10) not null,
age char(10) not null,
hobby varchar(50),
primary key (id));

insert into info1 values(1,'user1',20,'running');
insert into info1 values(2,'user2',30,'singing');

InnoDB 存储引擎的数据库在磁盘上存储成三个文件: db.opt(表属性文件)、表名.frm(表结构文件)、表名.ibd(表数据文件)。

1.物理冷备份与恢复
systemctl stop mysqld
yum -y install xz
#压缩备份
tar Jcvf /opt/mysql_all_$(date +%F).tar.xz /usr/local/mysql/data/
mv /usr/local/mysql/data/ /opt/
#解压恢复
tar Jxvf /opt/mysql_all_2020-11-22.tar.xz -C /usr/local/mysql/data/
cd /usr/local/mysql/data
mv /usr/local/mysql/data/* ./
注意是移动不是复制,复制貌似会无法启动mysql,复制注意权限问题。



2. mysqldump 备份与恢复(温备份)
(1)、完全备份一个或多个完整的库 (包括其中所有的表)
mysqldump -uroot -p[密码] --databases 库名1 [库名2] ... > /备份路径/备份文件名.sql    #导出的就是数据库脚本文件
例:
mysqldump -u root -p --databases kgc > /opt/kgc.sql       
#备份一个kgc库
mysqldump -u root -p --databases mysql kgc > /opt/mysql-kgc.sql    
#备份mysql与 kgc两个库

(2)、完全备份 MySQL 服务器中所有的库
mysqldump -u root -p[密码] --all-databases > /备份路径/备份文件名.sql
例:
mysqldump -u root -p --all-databases > /opt/all.sql

(3)、完全备份指定库中的部分表
mysqldump -u root -p[密码] 库名 [表名1] [表名2] ... > /备份路径/备份文件名.sql
例:
mysqldump -u root -p [-d] kgc info1 info2 > /opt/kgc_info1.sql
#使用“-d”选项,说明只保存数据库的表结构
#不使用“-d"选项,说明表数据也进行备份
#做为一个表结构模板

(4)查看备份文件
grep -v "^--" /opt/kgc_info1.sql | grep -v "^/" | grep -v "^$"

3.2 mysqldump 备份与恢复


完全备份一个或多个完整的库 (包括其中所有的表)
mysqldump -u root -p[密码] --databases 库名1 [库名2] ... > /备份路径/备份文件名.sql    #导出的就是数据库脚本文件
例:
mysqldump -u root -p --databases kgc > /opt/kgc.sql       
#备份一个kgc库
mysqldump -u root -p --databases mysql kgc > /opt/mysql-kgc.sql    
#备份mysql与 kgc两个库

(2)、完全备份 MySQL 服务器中所有的库
mysqldump -u root -p[密码] --all-databases > /备份路径/备份文件名.sql
例:
mysqldump -u root -p --all-databases > /opt/all.sql

(3)、完全备份指定库中的部分表
mysqldump -u root -p[密码] 库名 [表名1] [表名2] ... > /备份路径/备份文件名.sql
例:
mysqldump -u root -p [-d] kgc info1 info2 > /opt/kgc_info1.sql
#使用“-d”选项,说明只保存数据库的表结构
#不使用“-d"选项,说明表数据也进行备份
#做为一个表结构模板

(4)查看备份文件
grep -v "^--" /opt/kgc_info1.sql | grep -v "^/" | grep -v "^$



mysql 完全恢复
模拟删库
drop database 库名;

mysql -u root -p123123 < /backup/bbs.sql
#恢复数据库操作

#恢复数据表
当备份文件中只包含表的 备份时,而不包含创建库时的语句,执行操作时必须指定库名,且目标库必须存在。

mysqldump -u root -p123123 kgc info > /backup/kgc_info.sql
#只备份表

drop database kgc;
 
create database kgc;

mysql -u root -p123123 kgc < /backup/kgc_info.sql
#######恢复表时需要指定对应的库##########

3.3增量备份与恢复

MySQL数据库增量恢复
1.一般恢复

将所有备份的二进制日志内容全部恢复

2.基于位置恢复

数据库在某一时间点可能既有错误的操作也有正确的操作
可以基于精准的位置跳过错误的操作
发生错误节点之前的一个节点,上一次正确操作的位置点停止

3.基于时间点恢复

跳过某个发生错误的时间点实现数据恢复
在错误时间点停止,在下一个正确时间点开始



一、增备实验
1.开启二进制日志功能
vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
binlog_format = MIXED      #可选,指定二进制日志(binlog)的记录格式为MIXED(混合输入)
server-id = 1              #可加可不加该命令

#二进制日志(binlog)有3种不同的记录格式: 
#STATEMENT (基于SQL语句)、
#ROW(基于行)、
#MIXED(混合模式),
#默认格式是STATEMENT

[root@localhost backup]#ls /usr/local/mysql/data
#二进制日志位置


2 可以每周对数据库或表进行完全备份
mysqldump -uroot -p123123 kgc info >/backup/kgc_info.sql
mysqldump -uroot -p123123 --all-databases  >/backup/kgc_info.sql

3.可以每天进行增量备份操作,生成新的二进制文件(mysql-bin.000002)
mysqladmin -uroot -p123123 -p flush-logs


4插入新数据
use info 
insert into info values(2,'gk',22);
insert into info values(3,'jk',23);

5再次生成新的二进制日志文件
mysqladmin -uroot -p123123  flush-logs
#之前的操作会保存在上一个二进制文件中,之后的操作会保存在新的二进制文件中

6.查看二进制日志文件
cp /usr/loacal/mysql/data/mysql-bin.000002 /opt/
mysqlbinlog --no-defaults --base64-output=decode-rows -v /opt/mysql-bin.000002


增量恢复:
1模拟丢失文件
delete from info where id=1;
mysqlbinlog --no-defaults /opt/mysql-bin.000002 |mysql -u -root -p123123


3.3-1增量备份与恢复

实际操作

#首先修改配置文件启用二进制日志
[root@localhost ~]#vim /etc/my.cnf
#修改二进制日志文件
[mysqld]
log-bin=mysql-bin
binlog_format = MIXED 

[root@localhost ~]#systemctl restart mysqld.service
#重启服务
root@localhost ~]#ls /usr/local/mysql/data/
#查看日志文件是否生成 mysql-bin.000001
auto.cnf  ib_buffer_pool  ib_logfile0  ibtmp1  mysql-bin.000001  performance_schema
bbs       ibdata1         ib_logfile1  mysql   mysql-bin.index   sys

[root@localhost ~]#mysql -uroot -p123123
#进入数据库创建环境
mysql> create database ky15;
#创建数据库 ky15
mysql> use ky15
#进入数据库 ky15
mysql> create table info (id int , name char(20),age int,address char(50),hobby char(50));
mysql> desc info;
#查看表结构
+---------+----------+------+-----+---------+-------+
| Field   | Type     | Null | Key | Default | Extra |
+---------+----------+------+-----+---------+-------+
| id      | int(11)  | YES  |     | NULL    |       |
| name    | char(20) | YES  |     | NULL    |       |
| age     | int(11)  | YES  |     | NULL    |       |
| address | char(50) | YES  |     | NULL    |       |
| hobby   | char(50) | YES  |     | NULL    |       |
+---------+----------+------+-----+---------+-------+
5 rows in set (0.00 sec)
mysql> insert into info values(1,'jk',18,'南京','吃饭');
mysql> insert into info values(2,'ll',19,'北京','跳舞');
#插入数据
mysql> select * from info;
+------+------+------+---------+--------+
| id   | name | age  | address | hobby  |
+------+------+------+---------+--------+
|    1 | jk   |   18 | 南京    | 吃饭   |
|    2 | ll   |   19 | 北京    | 跳舞   |
+------+------+------+---------+--------+
2 rows in set (0.00 sec)


mkdir /backup
#创建存放备份文件的目录
mysqldump -uroot -p123123 ky15 info > /backup/ky15_info.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
#备份ky15 下的info表
mysqladmin -uroot -p123123 flush-logs
#刷新日志
ls /usr/local/mysql/data/
#查看是否生成了新的 二进制日志
auto.cnf  ib_buffer_pool  ib_logfile0  ibtmp1  mysql             mysql-bin.000002  performance_schema
bbs       ibdata1         ib_logfile1  ky15    mysql-bin.000001  mysql-bin.index   sys

#数据库中插入新的文件
mysql> use ky15
#进入数据库 ky15
mysql> insert into info values(3,'lili',23,'北京','唱歌');
Query OK, 1 row affected (0.00 sec)
mysql> insert into info values(4,'lihua',23,'北京','骂人');
Query OK, 1 row affected (0.00 sec)

mysql> select * from info;
+------+-------+------+---------+--------+
| id   | name  | age  | address | hobby  |
+------+-------+------+---------+--------+
|    1 | jk    |   18 | 南京    | 吃饭   |
|    2 | ll    |   19 | 北京    | 跳舞   |
|    3 | lili  |   23 | 北京    | 唱歌   |
|    4 | lihua |   23 | 北京    | 骂人   |
+------+-------+------+---------+--------+
4 rows in set (0.00 sec)


cat /usr/local/mysql/data/mysql-bin.000002 
mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql-bin.000002
#查看日志文件

mysql> drop database ky15;
Query OK, 1 row affected (0.00 sec)
#模拟删库

mysql> create database ky15;


mysql -uroot -p123123 ky15 < ky15_info.sql 
mysql: [Warning] Using a password on the command line interface can be insecure.
#恢复表

mysql> show tables;
mysql> select * from info;
+------+------+------+---------+--------+
| id   | name | age  | address | hobby  |
+------+------+------+---------+--------+
|    1 | jk   |   18 | 南京    | 吃饭   |
|    2 | ll   |   19 | 北京    | 跳舞   |
+------+------+------+---------+--------+
2 rows in set (0.00 sec)


mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000002 |mysql -uroot -p123123
mysql: [Warning] Using a password on the command line interface can be insecure.
#恢复 增量备份

mysql> select * from info;
+------+-------+------+---------+--------+
| id   | name  | age  | address | hobby  |
+------+-------+------+---------+--------+
|    1 | jk    |   18 | 南京    | 吃饭   |
|    2 | ll    |   19 | 北京    | 跳舞   |
|    3 | lili  |   23 | 北京    | 唱歌   |
|    4 | lihua |   23 | 北京    | 骂人   |
+------+-------+------+---------+--------+
4 rows in set (0.00 sec)

3.4断点恢复

基于位置恢复

删除库中的数据
mysql> delete from info where id=3;
Query OK, 1 row affected (0.01 sec)

mysql> delete from info where id=4;
Query OK, 1 row affected (0.00 sec)


mysql> select * from info;
+------+------+------+---------+--------+
| id   | name | age  | address | hobby  |
+------+------+------+---------+--------+
|    1 | jk   |   18 | 南京    | 吃饭   |
|    2 | ll   |   19 | 北京    | 跳舞   |
+------+------+------+---------+--------+
2 rows in set (0.00 sec)

只恢复其中之一
[root@localhost backup]#mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql-bin.000002 >/backup/mysqlbin.log
#查看 相关的序号

[root@localhost backup]#mysqlbinlog --no-defaults --stop-position='601' /usr/local/mysql/data/mysql-bin.000002 |mysql -uroot -p123123
#从头开始  到601结束
mysql> select * from info;
+------+------+------+---------+--------+
| id   | name | age  | address | hobby  |
+------+------+------+---------+--------+
|    1 | jk   |   18 | 南京    | 吃饭   |
|    2 | ll   |   19 | 北京    | 跳舞   |
|    3 | lili |   23 | 北京    | 唱歌   |
+------+------+------+---------+--------+
3 rows in set (0.00 sec)

[root@localhost backup]#mysqlbinlog --no-defaults --start-position='601' /usr/local/mysql/data/mysql-bin.000002 |mysql -uroot -p123123
mysql: [Warning] Using a password on the command line interface can be insecure.
#从601 开始

mysql> select * from info;
+------+-------+------+---------+--------+
| id   | name  | age  | address | hobby  |
+------+-------+------+---------+--------+
|    1 | jk    |   18 | 南京    | 吃饭   |
|    2 | ll    |   19 | 北京    | 跳舞   |
|    4 | lihua |   23 | 北京    | 骂人   |
+------+-------+------+---------+--------+
3 rows in set (0.00 sec)


基于时间点

#格式只将position 改为datetime 时间日期 格式  年-月-日 时:分:秒
[root@localhost backup]#mysqlbinlog --no-defaults --start-datetime='2021-11-29 14:31:14' /usr/local/mysql/data/mysql-bin.000002 |mysql -uroot -p123123
mysql: [Warning] Using a password on the command line interface can be insecure.

SQL高级语言

1导入数据库

mysql> source /backup/hellodb_innodb.sql;
#将脚本导入  source  加文件路径

2. select

显示表格中的一个或者多个字段中所有的信息
语法:
select 字段名  from 表名;
例子
select * from info;
select name from info;
select name,id,age from info;

3. distinct

distinct 查询不重复记录
中文含义:/dɪˈstɪŋkt/ 不同的 明显的
语法:
select distinct 字段 from 表名﹔

例子:
select distinct age from students;
#去除年龄字段中重复的
select distinct gender from students;
#查找性别

4. where

where 有条件的查询
语法:select '字段' from 表名  where 条件

select name,age from students where age < 20;
#显示name和age 并且要找到age 小于20的

5.and;or

and 且           or  或
语法:
select 字段名  from 表名 where 条件1 (and|or) 条件2 (and|or)条件3;

例子:
select name,age from students where 30 > age and age > 20;
select name,age,classid from students where 30 > age and age > 20 and classsid=3;
select name,age from students where gender='m' or(30 > age and age > 20);
#男的 或 30到20岁之间  

6.in

in:
显示已知值的资料
语法:
select 字段名  from 表名 where 字段 in ('值1','值2'....);
例子:
select * from students where StuID in (1,2,3,4);
select * from students where ClassID in (1,4);

7.between

between:
显示两个值范围内的资料
语法:
select 字段名  from 表名 where 字段 between  '值1' and '值2';
包括 and两边的值
例子:
select * from students where name between 'ding dian' and 'ling chong';
#一般不使用在字符串上
select * from students where stuid between 2 and 5;
#id2-到5 的信息
select * from students where age between '22' and '30';
不需要表中一定有该字段,只会将22 到30 已有的都显示出来

8.like 通配符

通配符通常是和  like 一起使用
语法:
select 字段名  from 表名 where 字段 like 模式

select * from students where name like 's%';
通配符含义
%表示零个,一个或者多个字符
_下划线表示单个字符
A_Z所有以A开头 Z 结尾的字符串 ‘ABZ’ ‘ACZ’ 'ACCCCZ’不在范围内 下划线只表示一个字符 AZ 包含a空格z
ABC%所有以ABC开头的字符串 ABCD ABCABC
%CBA所有以CBA结尾的字符串 WCBA CBACBA
%AN%所有包含AN的字符串 los angeles
_AN%所有 第二个字母为 A 第三个字母 为N 的字符串

9. order by

order by 按关键字排序
语法:
select 字段名  from 表名 where 条件 order by 字段 [asc,desc];

select age,name from students order by age;
#正向排序

select name,age from info order by age desc;
#反向排序

可以加上where
select name,age from students where classid=3 order by age;
#显示 name和age字段的数据  并且只显示classid字段为3 的 并且以age字段排序

10.函数

10.1数学函数

函数含义
abs(x)返回x 的 绝对值
rand()返回0到1的随机数
mod(x,y)返回x除以y以后的余数
power(x,y)返回x的y次方
round(x)返回离x最近的整数
round(x,y)保留x的y位小数四舍五入后的值
sqrt(x)返回x的平方根
truncate(x,y)返回数字 x 截断为 y 位小数的值
ceil(x)返回大于或等于 x 的最小整数
floor(x)返回小于或等于 x 的最大整数
greatest(x1,x2…)返回返回集合中最大的值
least(x1,x2…)返回返回集合中最小的值

例子:

select abs(-1);
select rand();
select mod(6,4);
select power(2,2);
select round(2.5);
select round(3.1415926345,3);
select truncate(3.1415926345,3);
select ceil(2.6);
select floor(2.4);
select least(22,33,44);
select greatest(55,66,88);

10.2聚合函数

函数含义
avg()返回指定列的平均值
count()返回指定列中非 NULL 值的个数
min()返回指定列的最小值
max()返回指定列的最大值
sum(x)返回指定列的所有值之和

例子:

select avg(age) from students;
#求表中年龄的平均值
select sum(age) from students;
#求表中年龄的总和
select max(age) from students;
#求表中年龄的最大值
select min(age) from students;
#求表中年龄的最小值
select count(classid) from students;
#求表中有多少非空记录
select count(distinct gender) from students;

select count(*) from students;

如果某表只有一个字段使用*不会忽略空记录
如果count后面加上明确字段会忽略空记录

#####思考空格字符 会被匹配么?########

insert into students values(26,' ',22,'m',3,1);

10.3 字符串函数

函数描述
trim()返回去除指定格式的值
concat(x,y)将提供的参数 x 和 y 拼接成一个字符串
substr(x,y)获取从字符串 x 中的第 y 个位置开始的字符串,跟substring()函数作用相同
substr(x,y,z)获取从字符串 x 中的第 y 个位置开始长度为z 的字符串
length(x)返回字符串 x 的长度
replace(x,y,z)将字符串 z 替代字符串 x 中的字符串 y
upper(x)将字符串 x 的所有字母变成大写字母
lower(x)将字符串 x 的所有字母变成小写字母
left(x,y)返回字符串 x 的前 y 个字符
right(x,y)返回字符串 x 的后 y 个字符
repeat(x,y)将字符串 x 重复 y 次
space(x)返回 x 个空格
strcmp(x,y)比较 x 和 y,返回的值可以为-1,0,1
reverse(x)将字符串 x 反转

例子

#trim:
语法:
select trim (位置 要移除的字符串 from 字符串)
其中位置的值可以是 
leading(开始) 
trailing(结尾)
both(起头及结尾)
要移除的字符串:从字符串的起头、结尾或起头及结尾移除的字符串,缺省时为空格。#区分大小写
select trim(leading 'Sun' from 'Sun Dasheng');
select trim(both  from ' Sun Dasheng      ');
#去除空格

#length:
select name,length(name) from students;
#计算出字段中记录的字符长度

#replace
语法:select replace(字段,'原字符''替换字符') from 表名;
select replace(name,'ng','gl') from students;
#把ng换成gl

#concat:
语法:select concat(字段1,字段2)from 表名
select concat(name,classid) from students;
elect concat(name,classid) from students where classid=3;
select name || classid from students where classid=3;
select concat(name,'\t',classid) from students where classid=3;

#substr:
语法:select substr(字段,开始截取字符,截取的长度)  where 字段='截取的字符串'               
select substr(name,6) from students where name='Sun Dasheng';
select substr(name,6,2) from students where name='Sun Dasheng';

11 group by

group by:
对group by  后面的字段的查询结果进行汇总分组,通常是结合聚合函数一起使用的
group by    有一个原则,就是select 后面的所有列中,没有使用聚合函数的列必须出现在 group by 的后面。

语法:
select 字段1,sum(字段2) from 表名 group by 字段1;

例子:
select classid,sum(age) from students group by classid;
#求各个班的年龄总和
select classid,avg(age) from students group by classid;
#求平均年龄
select classid,count(age) from students group by classid;

12having

having:用来过滤由group by语句返回的记录集,通常与group by语句联合使用
having语句的存在弥补了where关键字不能与聚合函数联合使用的不足。如果被SELECT的只有函数栏,那就不需要GROUP BY子句。
语法:SELECT 字段1,SUM("字段")FROM 表格名 GROUP BY 字段1 having(函数条件);

select classid,avg(age) from students group by classid where age > 30;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where age > 30' at line 1

select classid,avg(age) from students group by classid having age > 30;
ERROR 1054 (42S22): Unknown column 'age' in 'having clause'

select classid,avg(age) from students group by classid having avg(age) > 30;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值